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;链接.
2. 利用CIFAR10数据集 — 迁移学习训练现有网络
以Alexnet为例:图像分类识别
convnet = alexnet;
convnet.Layers % Take a look at the layers
常用网络层
卷积层将输入图像放进一组卷积滤波器,每个滤波器激活图像中的某些特征。
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。
再来一个例子:图像分类识别
%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))