필터 지우기
필터 지우기

Transfer learning CNN with regression at the end?

조회 수: 5 (최근 30일)
Tobias Pahlberg
Tobias Pahlberg 2017년 5월 15일
댓글: Mity sosi 2019년 5월 12일
Hi
I have been trying to test transfer learning with a regression layer at the end, but I end up with a network that always predicts NaNs. What am I doing wrong?
I want to use e.g., VGG19 to estimate timber volume in images but as I cannot release the data I created a modified version of one of the Matlab examples to show the problem. The example that I modified is called 'TrainAConvolutionalNeuralNetworkForRegressionExample', where the rotation of digits should be estimated.
I assume the problem lies in how the layers are put together at the end. Here is the modified code:
clear
close all
% Clear GPU memory
gpuDevice(1)
% Load VGG network
net = vgg19; % vgg16, vgg19 or alexnet
% Load the digit training set as 4-D array data using
[trainImagesSmall,~,trainAngles] = digitTrain4DArrayData;
% Load the digit test set.
[testImagesSmall,~,testAngles] = digitTest4DArrayData;
% Pick out a subset to test
numToTest = 1000;
testImagesSmall = testImagesSmall(:,:,1,round(linspace(1,5000,numToTest)));
testAngles = testAngles(round(linspace(1,5000,numToTest)),1);
% % In case the images have been resized and saved one can load instead
% load('trainImages.mat');
% load('testImages.mat');
% Resize train images to match VGG input
trainImages = zeros(224,224,1,5000);
for i = 1:size(trainImages,4)
i
trainImages(:,:,1,i) = imresize(trainImagesSmall(:,:,1,i),[224 224]);
clc
end
trainImages = repmat(trainImages,1,1,3,1);
disp('Saving training images...');
save('trainImages.mat', 'trainImages','-v7.3');
% Resize test images to match VGG input
testImages = zeros(224,224,1,numToTest);
for i = 1:numToTest
i
testImages(:,:,1,i) = imresize(testImagesSmall(:,:,1,i),[224 224]);
clc
end
testImages = repmat(testImages,1,1,3,1);
disp('Saving test images...');
save('testImages.mat', 'testImages','-v7.3');
% Display 20 random sample training digits using |imshow|.
numTrainImages = size(trainImages,4);
figure
idx = randperm(numTrainImages,20);
for i = 1:numel(idx)
subplot(4,5,i)
imshow(trainImages(:,:,:,idx(i)))
drawnow
end
% Combine all the layers together in a |Layer| array.
layersTransfer = net.Layers(1:end-3);
layers = [layersTransfer
fullyConnectedLayer(1)
regressionLayer];
% Train Network
transferLayerOptions = trainingOptions( 'sgdm','MiniBatchSize',25,...
'InitialLearnRate',0.001, ...
'MaxEpochs',7, 'Verbose', true);
% load('trainedNet_7Epochs.mat'); % Load previously trained network
net = trainNetwork(trainImages,trainAngles,layers,transferLayerOptions);
% Clear GPU memory (don't know if this makes any difference here)
gpuDevice(1)
% Use |predict| to predict the angles of rotation of the test images.
predictedTestAngles = zeros(length(testAngles),1);
for i = 1:length(testAngles)
i
predictedTestAngles(i) = predict(net,testImages(:,:,:,i));
clc
end
% =========================================================================
if any(isnan(predictedTestAngles))
disp('There were NaNs predicted');
return;
end
% =========================================================================
% Calculate the prediction error between the predicted and actual angles of
% rotation.
predictionError = testAngles - predictedTestAngles;
figure;
plot(1:length(testAngles),testAngles,'b-', 1:length(predictedTestAngles),predictedTestAngles,'r-');
ylabel('Angle');
legend('True angle', 'Predicted angle');
  댓글 수: 4
Joss Knight
Joss Knight 2017년 6월 23일
Just checking whether you were suffering from the Pascal cuDNN bug, but clearly you weren't.
Mity sosi
Mity sosi 2019년 5월 12일
Hi
how did you make your trainimages ? how did you make digitTrain4DArrayData ?

댓글을 달려면 로그인하십시오.

채택된 답변

Tobias Pahlberg
Tobias Pahlberg 2017년 10월 6일
Lowering the initial learn rate to 1e-5 did the trick.

추가 답변 (1개)

Greg Heath
Greg Heath 2017년 5월 15일
In order to get a variety of answers you have to use a different initial random number state for each design.
So, either use a different rng initialization for each run
OR (my technique)
Use a double for loop to loop over number of hidden nodes (outer loop) and random initial weights (inner loop)
A single rng initialization before the first loop will suffice. I have posted zillions of examples in both the NEWSGROUP and ANSWERS.
Hope this helps.
Thank you for formally accepting my answer
Greg
  댓글 수: 2
Tobias Pahlberg
Tobias Pahlberg 2017년 5월 16일
I think you misunderstood me. The problem is that the trained network gives the same answer, let's say 15 degrees, for every test image I supply to the function predict. (I updated the question to be more clear.)
Tobias Pahlberg
Tobias Pahlberg 2017년 5월 17일
편집: Tobias Pahlberg 2017년 5월 17일
Corrected a bug in my code and now it only predicts NaNs for every image I supply.

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by