2

I'm running an example that I got from a Webinar. this is the code:

%% Fine Tuning A Deep Neural Network 
clear; clc;close all;
imagenet_cnn = load('imagenet-cnn');
net = imagenet_cnn.convnet;
net.Layers

%% Perform net surgery
layers = net.Layers(1:end-3);
layers(end+1) = fullyConnectedLayer(12, 'Name', 'fc8_2')
layers(end+1) = softmaxLayer('Name','prob_2');
layers(end+1) = classificationLayer('Name','classificationLayer_2')
  
%% Setup learning rates for fine-tuning

% fc 8 - bump up learning rate for last layers
layers(end-2).WeightLearnRateFactor = 100;
layers(end-2).WeightL2Factor = 1;
layers(end-2).BiasLearnRateFactor = 20;
layers(end-2).BiasL2Factor = 0;

%% Load Image Data

 rootFolder = fullfile('E:\Universidad\Tesis\Matlab', 'TesisDataBase');
categories = {'Avion','Banana','Carro','Gato', 'Mango','Perro','Sandia','Tijeras','Silla','Mouse','Calculadora','Arbol'};
imds = imageDatastore(fullfile(rootFolder, categories), 'LabelSource', 'foldernames');
tbl = countEachLabel(imds);

%% Equalize number of images of each class in training set
minSetCount = min(tbl{:,2}); % determine the smallest amount of images in a category
% Use splitEachLabel method to trim the set.
imds = splitEachLabel(imds, minSetCount);

% Notice that each set now has exactly the same number of images.
countEachLabel(imds)
[trainingDS, testDS] = splitEachLabel(imds, 0.7,'randomize');
% Convert labels to categoricals
trainingDS.Labels = categorical(trainingDS.Labels);
trainingDS.ReadFcn = @readFunctionTrain;

%% Setup test data for validation
testDS.Labels = categorical(testDS.Labels);
testDS.ReadFcn = @readFunctionValidation;

%% Fine-tune the Network

miniBatchSize = 32; % lower this if your GPU runs out of memory.
numImages = numel(trainingDS.Files);
numIterationsPerEpoch = 250;
maxEpochs = 62;
lr = 0.01;
opts = trainingOptions('sgdm', ...
    'InitialLearnRate', lr,...
    'LearnRateSchedule', 'none',...
    'L2Regularization', 0.0005, ...
    'MaxEpochs', maxEpochs, ...
    'MiniBatchSize', miniBatchSize);
net = trainNetwork(trainingDS, layers, opts);

As you can see this code , uses the well known AlexNet as a first start, then the last 3 layers are deleted ,in order to put 3 new layers with the number of neurons necessary for the new task.

the read func for test and training are the same here you have one of them:

function Iout = readFunctionTrain(filename)
% Resize the flowers images to the size required by the network.
I = imread(filename);
% Some images may be grayscale. Replicate the image 3 times to
% create an RGB image.
if ismatrix(I)
    I = cat(3,I,I,I);
end
% Resize the image as required for the CNN.
Iout = imresize(I, [227 227]);

this code runs well at the webinar, they use it to classify cars and subs that pass thru the matworks door.

The problem is that the new net is not learning when I try it with my own images,I have a data set of 12 categories each one with 1000 images more or less, all this images where downloaded from ImageNET.

the net does not increase its Mini batch accuracy, actually some times it does but very slow.

I also did the tutorial of this page Matlab Deep Learning ToolBox

and it worked good with my images. So , I don't understand what is wrong with my fine-tuning. Thanks.

Nick
  • 138,499
  • 22
  • 57
  • 95
Nicole Ramírez
  • 345
  • 3
  • 19

2 Answers2

0

If you have R2016a and a GeForce GTX1080 or other Pascal GPU, then see this tech support answer and this bug report.

Joss Knight
  • 222
  • 1
  • 4
0

Your learning rate for the pre-trained section of the network (0.01) looks very high for a fine tuning workflow. Also, your LR of 1.0 is quite high for the randomly initialized classification head.

What happens if you set the learning rate of the pre-trained section to 0 and train only the randomly initialized head of the network? What happens if you just use a low learning rate and train end to end (say 1e-5)?

It would be useful to see the training-progress plot, but I think its possible you're not converging due to your learning rate settings.

Alex Taylor
  • 1,402
  • 1
  • 9
  • 15