Matlab卷积神经网络不学习

时间:2016-12-08 05:58:51

标签: matlab machine-learning neural-network matconvnet

我正在运行一个来自网络研讨会的例子。 这是代码:

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

正如您所看到的那样,使用众所周知的AlexNet作为第一个开始,然后删除最后3个图层,以便为新任务添加3个新图层以及新任务所需的神经元数量。

测试和培训的读取功能在这里是相同的,你有一个:

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

此代码在网络研讨会上运行良好,他们使用它来对通过matworks门传递的汽车和潜艇进行分类。

问题在于,当我使用自己的图像尝试时,新网络没有学习,我有一个12个类别的数据集,每个类别或多或少有1000个图像,所有这些图像都是从ImageNET下载的。

网络不会增加其Mini批次精度,实际上有时会增加但非常慢。

我也做了这个页面的教程 Matlab Deep Learning ToolBox

它与我的图像很好用。所以,我不明白我的微调有什么问题。感谢。

2 个答案:

答案 0 :(得分:0)

如果您有R2016a和GeForce GTX1080或其他Pascal GPU,请参阅this tech support answerthis bug report

答案 1 :(得分:0)

对于网络的预训练部分,您的学习率(0.01)对于微调工作流程而言看起来非常高。另外,对于随机初始化的分类头,您的LR为1.0很高。

如果将预训练部分的学习率设置为0并仅训练随机初始化的网络头部,会发生什么情况?如果您仅使用较低的学习率并进行端到端培训(例如1e-5),会发生什么?

查看训练进度图会很有用,但是我认为由于您的学习率设置,您可能没有收敛。