MATLAB与深度学习(二)— 训练神经网络(图像分类识别)

MATLAB与深度学习(二)— 训练神经网络(图像分类识别)


上一篇,我们介绍了与深度学习相关的MATLAB工具包。这一篇,我们将介绍如何训练神经网络和相关的基础知识。本文借鉴和引用了网上许多前辈的经验和代码,如有冒犯,请及时与我联系。

1. 下载数据集
以CIFAR-10数据集为例
1.1 方式一,在matlab上下载

%% Download the CIFAR-10 dataset
if ~exist('cifar-10-batches-mat','dir')
    cifar10Dataset = 'cifar-10-matlab';
    disp('Downloading 174MB CIFAR-10 dataset...');   
    websave([cifar10Dataset,'.tar.gz'],...
        ['https://www.cs.toronto.edu/~kriz/',cifar10Dataset,'.tar.gz']);
    gunzip([cifar10Dataset,'.tar.gz'])
    delete([cifar10Dataset,'.tar.gz'])
    untar([cifar10Dataset,'.tar'])
    delete([cifar10Dataset,'.tar'])
end    

1.2 方式二,直接下载
我运行方式一的代码会报错,所以直接通过下面网址下载后。然后把数据集放在MATLAB的工作路径上。
https://www.cs.toronto.edu/~kriz/cifar-10-matlab.tar.gz;链接.
MATLAB与深度学习(二)— 训练神经网络(图像分类识别)_第1张图片
2. 利用CIFAR10数据集 — 迁移学习训练现有网络
以Alexnet为例:图像分类识别

convnet = alexnet;
convnet.Layers % Take a look at the layers

MATLAB与深度学习(二)— 训练神经网络(图像分类识别)_第2张图片
常用网络层
卷积层将输入图像放进一组卷积滤波器,每个滤波器激活图像中的某些特征。

ReLU 层通过将负值映射到零和保持正数值,实现更快、更高效的训练。

池化层通过执行非线性下采样,减少网络需要学习的参数个数,从而简化输出。

全连接层将网络 2D 空间特征“扁平化”为 1D 矢量,为分类目的而表示图像级特征。

Softmax 层为数据集中的每个类别提供概率。

下载完成后,转换数据格式,不然后面会报错:

 saveCIFAR10AsFolderOfImages('cifar-10-batches-mat', pwd, true);

数据设置,CIFAR-10数据集可以选择的对象是10种

rootFolder = 'cifar10Train';
categories = {'Deer','Dog','Frog','Cat'};
imds = imageDatastore(fullfile(rootFolder, categories), 'LabelSource', 'foldernames');
imds.ReadFcn = @readFunctionTrain;

% Change the number 50 to as many training images as you would like to use
% how does increasing the number of images change the 
% accuracy of the classifier?
[trainingSet, ~] = splitEachLabel(imds, 50, 'randomize'); 

通过激活来提取数据集的特征

featureLayer = 'fc7';
trainingFeatures = activations(convnet, trainingSet, featureLayer);

训练SVM分类器

temp(:,:)=trainingFeatures ;
temp=temp';
classifier = fitcnb(temp, trainingSet.Labels);

测试

rootFolder = 'cifar10Test';
testSet = imageDatastore(fullfile(rootFolder, categories), 'LabelSource', 'foldernames');
testSet.ReadFcn = @readFunctionTrain;
testFeatures = activations(convnet, testSet, featureLayer);
temp1(:,:)=testFeatures ;
temp=temp1';
predictedLabels = predict(classifier, temp);
confMat = confusionmat(testSet.Labels, predictedLabels);
confMat = confMat./sum(confMat,2);
mean(diag(confMat))

测试结果:整体精度为0.6447。

3. 利用CIFAR10数据集训练自主创建的神经网络模型
引用其他博主的代码作为示例:图像分类识别
https://blog.csdn.net/caokaifa/article/details/81163973;链接.

clear all; close all;clc;
%加载显示数据
[trainingImages,trainingLabels,testImages,testLabels] = helperCIFAR10Data.load('cifar10Data');
figure
thumbnails = trainingImages(:,:,:,1:100);
montage(thumbnails)

%% 训练
%数据集有10类
numImageCategories = 10;
categories(trainingLabels)

%建立输入层32x32x3 CIFAR-10 images
[height, width, numChannels, ~] = size(trainingImages);
imageSize = [height width numChannels];
inputLayer = imageInputLayer(imageSize);

%建立网络中间层
filterSize = [5 5];
numFilters = 32;

middleLayers = [
  
% The first convolutional layer has a bank of 32 5x5x3 filters. A
% symmetric padding of 2 pixels is added to ensure that image borders
% are included in the processing. This is important to avoid
% information at the borders being washed away too early in the
% network.
convolution2dLayer(filterSize, numFilters, 'Padding', 2)  %(n+2p-f)/s+1

% Note that the third dimension of the filter can be omitted because it
% is automatically deduced based on the connectivity of the network. In
% this case because this layer follows the image layer, the third
% dimension must be 3 to match the number of channels in the input
% image.

% Next add the ReLU layer:
reluLayer()

% Follow it with a max pooling layer that has a 3x3 spatial pooling area
% and a stride of 2 pixels. This down-samples the data dimensions from
% 32x32 to 15x15.
maxPooling2dLayer(3, 'Stride', 2)

% Repeat the 3 core layers to complete the middle of the network.
convolution2dLayer(filterSize, numFilters, 'Padding', 2)
reluLayer()
maxPooling2dLayer(3, 'Stride',2)

convolution2dLayer(filterSize, 2 * numFilters, 'Padding', 2)
reluLayer()
maxPooling2dLayer(3, 'Stride',2)
]

%定义输出层
finalLayers = [
  
% Add a fully connected layer with 64 output neurons. The output size of
% this layer will be an array with a length of 64.
fullyConnectedLayer(64)

% Add an ReLU non-linearity.
reluLayer

% Add the last fully connected layer. At this point, the network must
% produce 10 signals that can be used to measure whether the input image
% belongs to one category or another. This measurement is made using the
% subsequent loss layers.
fullyConnectedLayer(numImageCategories)

% Add the softmax loss layer and classification layer. The final layers use
% the output of the fully connected layer to compute the categorical
% probability distribution over the image classes. During the training
% process, all the network weights are tuned to minimize the loss over this
% categorical distribution.
softmaxLayer
classificationLayer
]

%三层合并
layers = [
  inputLayer
  middleLayers
  finalLayers
]

%定义层权值
layers(2).Weights = 0.0001 * randn([filterSize numChannels numFilters]);

%设置网络参数值
opts = trainingOptions('sgdm', ...
  'Momentum', 0.9, ...
  'InitialLearnRate', 0.001, ...
  'LearnRateSchedule', 'piecewise', ...
  'LearnRateDropFactor', 0.1, ...
  'LearnRateDropPeriod', 8, ...
  'L2Regularization', 0.004, ...
  'MaxEpochs', 40, ...
  'MiniBatchSize', 128, ...
  'Verbose', true,...
  'Plots','training-progress');
%  参数解释:
%  sgdm就是stochastic gradient descent with momentum(动量的随机梯度下降法),
%  Momentum是动量参数为0.9,InitialLearnRate初始学习速率0.001,L2Regularization=0.004
%  是L2正则化系数,LearnRateDropFactor=0.1、LearnRateDropPeriod=8是每8个epoces使得学习
%  速率乘以一个0.1的比例因子,MaxEpochs=?40最大训练为40个epoces,MiniBatchSize=128为Batch
%  为128,Verbose?=true就是把信息打印到命令窗口

% 开始训练
% doTraining为false,直接导入已经训练好的模型,
% doTraining为True,可以自己改模型训练
doTraining = true;

if doTraining    
  % Train a network.
  cifar10Net = trainNetwork(trainingImages, trainingLabels, layers, opts);
else
  % Load pre-trained detector for the example.
  load('rcnnStopSigns.mat','cifar10Net')       
end

%显示训练权值
w = cifar10Net.Layers(2).Weights;

% rescale the weights to the range [0, 1] for better visualization
w = rescale(w);

figure
montage(w)

% 在测试集上训练网络
YTest = classify(cifar10Net, testImages);

% 计算准确度
accuracy = sum(YTest == testLabels)/numel(testLabels)

调用函数helperCIFAR10Data代码如下


% This is helper class to download and import the CIFAR-10 dataset. The
% dataset is downloaded from:
%
% ?https://www.cs.toronto.edu/~kriz/cifar-10-matlab.tar.gz
%
% References
% ----------
% Krizhevsky, Alex, and Geoffrey Hinton. "Learning multiple layers of
% features from tiny images." (2009).
classdef helperCIFAR10Data

methods(Static)

%------------------------------------------------------------------
function download(url, destination)
if nargin == 1
url = 'https://www.cs.toronto.edu/~kriz/cifar-10-matlab.tar.gz';
end

unpackedData = fullfile(destination, 'cifar-10-batches-mat');
if ~exist(unpackedData, 'dir')
fprintf('Downloading CIFAR-10 dataset...'); 
untar(url, destination);
fprintf('done.\n\n');
end
end

%------------------------------------------------------------------
% Return CIFAR-10 Training and Test data.
function [XTrain, TTrain, XTest, TTest] = load(dataLocation) 

location = fullfile(dataLocation, 'cifar-10-batches-mat');

[XTrain1, TTrain1] = loadBatchAsFourDimensionalArray(location, 'data_batch_1.mat');
[XTrain2, TTrain2] = loadBatchAsFourDimensionalArray(location, 'data_batch_2.mat');
[XTrain3, TTrain3] = loadBatchAsFourDimensionalArray(location, 'data_batch_3.mat');
[XTrain4, TTrain4] = loadBatchAsFourDimensionalArray(location, 'data_batch_4.mat');
[XTrain5, TTrain5] = loadBatchAsFourDimensionalArray(location, 'data_batch_5.mat');

XTrain = cat(4, XTrain1, XTrain2, XTrain3, XTrain4, XTrain5);
TTrain = [TTrain1; TTrain2; TTrain3; TTrain4; TTrain5];

[XTest, TTest] = loadBatchAsFourDimensionalArray(location, 'test_batch.mat');

end
end
end

function [XBatch, TBatch] = loadBatchAsFourDimensionalArray(location, batchFileName)
load(fullfile(location,batchFileName));
XBatch = data';
XBatch = reshape(XBatch, 32,32,3,[]);
XBatch = permute(XBatch, [2 1 3 4]);
TBatch = convertLabelsToCategorical(location, labels);
end

function categoricalLabels = convertLabelsToCategorical(location, integerLabels)
load(fullfile(location,'batches.meta.mat'));
categoricalLabels = categorical(integerLabels, 0:9, label_names);
end

测试结果:整体精度为0.7445。
MATLAB与深度学习(二)— 训练神经网络(图像分类识别)_第3张图片
再来一个例子:图像分类识别

%Load training data
% Please note: these are 4 of the 10 categories available
% Feel free to choose which ever you like best!
categories = {'Deer','Dog','Frog','Cat'};

rootFolder = 'cifar10Train';
imds = imageDatastore(fullfile(rootFolder, categories), ...
  'LabelSource', 'foldernames');

%Define Layers
varSize = 32;
conv1 = convolution2dLayer(5,varSize,'Padding',2,'BiasLearnRateFactor',2);
conv1.Weights = gpuArray(single(randn([5 5 3 varSize])*0.0001));
fc1 = fullyConnectedLayer(64,'BiasLearnRateFactor',2);
fc1.Weights = gpuArray(single(randn([64 576])*0.1));
fc2 = fullyConnectedLayer(4,'BiasLearnRateFactor',2);
fc2.Weights = gpuArray(single(randn([4 64])*0.1));

layers = [
  imageInputLayer([varSize varSize 3]);
  conv1;
  maxPooling2dLayer(3,'Stride',2);
  reluLayer();
  convolution2dLayer(5,32,'Padding',2,'BiasLearnRateFactor',2);
  reluLayer();
  averagePooling2dLayer(3,'Stride',2);
  convolution2dLayer(5,64,'Padding',2,'BiasLearnRateFactor',2);
  reluLayer();
  averagePooling2dLayer(3,'Stride',2);
  fc1;
  reluLayer();
  fc2;
  softmaxLayer()
  classificationLayer()];

%Define training options
opts = trainingOptions('sgdm', ...
  'InitialLearnRate', 0.001, ...
  'LearnRateSchedule', 'piecewise', ...
  'LearnRateDropFactor', 0.1, ...
  'LearnRateDropPeriod', 8, ...
  'L2Regularization', 0.004, ...
  'MaxEpochs', 10, ...
  'MiniBatchSize', 100, ...
  'Verbose', true);

%tain
[net, info] = trainNetwork(imds, layers, opts);

%test
rootFolder = 'cifar10Test';
imds_test = imageDatastore(fullfile(rootFolder, categories), ...
  'LabelSource', 'foldernames');
  labels = classify(net, imds_test);

ii = randi(4000);
im = imread(imds_test.Files{ii});
imshow(im);
if labels(ii) == imds_test.Labels(ii)
 colorText = 'g'; 
else
  colorText = 'r';
end
title(char(labels(ii)),'Color',colorText);

% This could take a while if you are not using a GPU
confMat = confusionmat(imds_test.Labels, labels);
confMat = confMat./sum(confMat,2);
mean(diag(confMat))

测试结果:整体精度0.7570。
MATLAB与深度学习(二)— 训练神经网络(图像分类识别)_第4张图片

你可能感兴趣的:(深度学习,深度学习)