datasetPath = 'path/to/first_level_dataset';
imds = imageDatastore(datasetPath, 'IncludeSubfolders', true, 'LabelSource', 'foldernames');
imds.ReadFcn = @readAndPreprocessImage;
[imdsTrain, imdsVal] = splitEachLabel(imds, 0.8, 'randomized');
lgraph = yolov4Layers(inputSize, numClasses);
options = trainingOptions('adam', ...
'InitialLearnRate', 1e-4, ...
'Shuffle', 'every-epoch', ...
'Plots', 'training-progress', ...
'ValidationData', imdsVal, ...
'ValidationFrequency', 10);
detector = trainYOLOv2ObjectDetector(imdsTrain, lgraph, options);
subclassDatasetPath = 'path/to/subclass_dataset';
subclassImds = imageDatastore(subclassDatasetPath, 'IncludeSubfolders', true, 'LabelSource', 'foldernames');
subclassImds.ReadFcn = @readAndPreprocessImage;
firstLevelClasses = {'military_ships', 'commercial_ships', 'private_ships'};
numSubclasses = [3, 4, 2];
for i = 1:numel(firstLevelClasses)
currentClass = firstLevelClasses{i};
currentSubclassImds = subset(subclassImds, @(labels) contains(labels, currentClass));
subclassData = objectDetectorTrainingData(currentSubclassImds, 'DataAugmentation', 'random');
numClasses = numSubclasses(i);
imageInputLayer(inputSize)
convolution2dLayer(3, 64, 'Padding', 'same')
maxPooling2dLayer(2, 'Stride', 2)
fullyConnectedLayer(numClasses)
subclassOptions = trainingOptions('adam', ...
'InitialLearnRate', 1e-4, ...
'Plots', 'training-progress');
subclassDetector = trainNetwork(subclassData, subclassLayers, subclassOptions);
save(fullfile('path/to/save/models', [currentClass '_subclass_detector.mat']), 'subclassDetector');