基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)

基本介绍

  • 软件:Matlab R2018b
  • 数据集:Kaggle猫狗数据集
  • 网络:AlexNet

前期准备

数据集

Kaggle猫狗数据集猫与狗用于训练的图片(train)分别12500张,每张图片的尺寸大小都是有差异的,图片的命名格式为标签+标号。
【数据集度云链接】
链接:https://pan.baidu.com/s/17c4K04kDKDUsuXdLkPecKA
提取码:8rhn
基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)_第1张图片
在这里,将两种图片分别放在两个文件夹下,文件夹用标签命名。这样做主要是便于使用Matlab自身构建数据集的函数。(下文中将标注)
基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)_第2张图片

MATLAB中的AlexNet

直接在命令窗口输入下列命令,若没有该网络结构,软件会报错并提示下载。下载方法不在这里赘述。

net = alexnet;

读取并预处理数据集

1.读取原始数据集

imds = imageDatastore('E:\kaggle\train', ... 
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

函数说明

imds = imageDatastore(location,Name,Value)
location 数据集位置(文件夹地址)
IncludeSubfolders 子文件夹包含标记(使用前文中提到的文件夹分类并命名)true为指定,false为不指定,默认不指定
FileExtensions 图像文件扩展名,指定读取某一类型的图片文件,这里不指定

在这里使用IncludeSubfolders标定图片的标签可以省去很多不必要的步骤。但不是很适合训练集打乱的情况。

2.读取数据集数量

numTrainImages = numel(imds.Labels);

这一行代码实质是打印数据集中所有的标签,再统计标签总数以达到统计训练集图片总数。

3.统一图片尺寸

AlexNet默认输入图片尺寸为227×227×3,其中3指的是彩色图片的三通道。所以我们需要把数据集中的图片统一比例与像素大小。

for i = 1:numTrainImages
    s = string(imds.Files(i));
    I = imread(s);
    I = imresize(I,[227,227]);
    imwrite(I,s);
    s
end

这个循环函数,imds.Files的作用是读取数据集中所有图片的地址,然后逐一读取改尺寸。

4.分割数据集

在这里有两种方式生成训练数据集与测试数据集:
1.按比例分割数据集
2.使用官方测试数据集

按比例分割数据集

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');

这行代码主要功能是将原数据集imds7:3分割为训练数据集imdsTrain与测试数据集imdsValidation,分割挑去方式为随机。

官方测试数据集

imdsTrain = imds
imdsValidation = imageDatastore('E:\kaggle\test', ... 
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

读取方法与第一步的方法相同。

在这里使用第一种方法

AlexNet网络

1.读取原始AlexNet

net = alexnet;

inputSize = net.Layers(1).InputSize

layersTransfer = net.Layers(1:end-3);

numClasses = numel(categories(imdsTrain.Labels));

inputSize 读取该网络输入图片的尺寸
layersTransfer 获取AlexNet后三层之外的网络,保持不变
numClasses 获取以确定的数据集标签数(即分类数量,猫狗分类数量为2)

2.组建新网络

layers = [
    layersTransfer
    fullyConnectedLayer(numClasses,'WeightLearnRateFactor',20,'BiasLearnRateFactor',20)
    softmaxLayer
    classificationLayer];

这里主要是更改最后全连接层。

训练AlexNet网络

指定训练选项。对于迁移学习,请保留预训练网络的较浅层中的特征(迁移的层权重)。要减慢迁移的层中的学习速度,请将初始学习速率设置为较小的值。在上一步中增大了全连接层的学习率因子,以加快新的最终层中的学习速度。这种学习率设置组合只会加快新层中的学习速度,对于其他层则会减慢学习速度。执行迁移学习时,所需的训练轮数相对较少。一轮训练是对整个训练数据集的一个完整训练周期。指定小批量大小和验证数据。软件在训练过程中每 ValidationFrequency 次迭代验证一次网络。

options = trainingOptions('sgdm', ...
    'MiniBatchSize',10, ...
    'MaxEpochs',6, ...
    'InitialLearnRate',1e-4, ...
    'Shuffle','every-epoch', ...
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',3, ...
    'Verbose',false, ...
    'Plots','training-progress');

训练网络

netTransfer = trainNetwork(augimdsTrain,layers,options);

基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)_第3张图片
其实由于AlexNet本身的结构问题,Accuracy基本上也就是在92%上下波动,再加上迁移学习可以节省很多时间,所以其实可以使用很少的数据集,100张左右都是差不了太多的。(训练25000张其实最终结果没太大差别)

测试网络

idx = randperm(numel(imdsValidation.Files),20);

在上文中提到的测试数据集中随机抽取20张作为本次测试的数据集idx

figure
for i = 1:20
    subplot(5,4,i)
    I = readimage(imdsValidation,idx(i));
    imshow(I)
    label = YPred(idx(i));
    title(string(label));
end

逐一测试并展示出来
基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)_第4张图片
肉眼检测一下,发现左下角的小黑狗被错误识别成猫了。但是整体结果还算可以。
基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)_第5张图片

结语

总的来说,通过AlexNet迁移学习猫狗分类是相当简单的。只需要改少许代码,就可以实现其他的多分类任务。
这里只是核心代码,做一下GUI便是可以作为某一期末课程设计了。在这里附上简单的GUI界面:
基于MATLAB的Alexnet迁移学习进行猫狗分类(数据集:Kaggle)_第6张图片

全部代码

imds = imageDatastore('E:\kaggle\train', ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

numTrainImages = numel(imds.Labels);

for i = 1:numTrainImages
    s = string(imds.Files(i));
    I = imread(s);
    I = imresize(I,[227,227]);
    imwrite(I,s);
    s
end

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');

net = alexnet;

inputSize = net.Layers(1).InputSize

layersTransfer = net.Layers(1:end-3);

numClasses = numel(categories(imdsTrain.Labels));

layers = [
    layersTransfer
    fullyConnectedLayer(numClasses,'WeightLearnRateFactor',20,'BiasLearnRateFactor',20)
    softmaxLayer
    classificationLayer];

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

options = trainingOptions('sgdm', ...
    'MiniBatchSize',10, ...
    'MaxEpochs',10, ...
    'InitialLearnRate',1e-4, ...
    'Shuffle','every-epoch', ...
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',3, ...
    'Verbose',false, ...
    'Plots','training-progress');

netTransfer = trainNetwork(augimdsTrain,layers,options);

你可能感兴趣的:(Matlab神经网络实战)