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');