原文链接
此示例显示了如何微调预训练的AlexNet卷积神经网络,以对新的图像集合进行分类。
AlexNet已经接受了超过一百万张图像的培训,可以将图像分类为1000个对象类别(例如键盘,咖啡杯,铅笔和许多动物)。该网络已经为各种图像学习了丰富的功能表示。网络将图像作为输入,并输出图像中对象的标签以及每个对象类别的概率。
转移学习通常用于深度学习应用程序。您可以采用经过预训练的网络,并将其用作学习新任务的起点。与使用从头开始随机初始化的权重训练网络相比,使用迁移学习对网络进行微调通常会更快,更容易。您可以使用少量训练图像将学习到的功能快速转移到新任务中。
♥ 使用AlexNet迁移学习 - 图1
图1. 预训练好的AlexNet网络

载入数据

解压缩并将新图像加载为图像数据存储。imageDatastore根据文件夹名称自动标记图像,并将数据存储为ImageDatastore对象。图像数据存储库使您可以存储大的图像数据(包括内存中不适合的数据),并在训练卷积神经网络期间有效地读取一批图像。

  1. unzip('MerchData.zip');
  2. imds = imageDatastore('MerchData', ...
  3. 'IncludeSubfolders',true, ...
  4. 'LabelSource','foldernames');

将数据分成训练和测试集,70%用于训练,30%用于测试。splitEachLabel将图片分成两部分。

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

这个小的数据集包含55个训练图片和20个验证图片,展示一下这些图片。

  1. numTrainImages = numel(imdsTrain.Labels);
  2. idx = randperm(numTrainImages,16);
  3. figure
  4. for i = 1:16
  5. subplot(4,4,i)
  6. I = readimage(imdsTrain,idx(i));
  7. imshow(I)
  8. end

♥ 使用AlexNet迁移学习 - 图2
图2. 图片样本

加载预训练好的网络

加载预训练的AlexNet神经网络。如果未安装_用于AlexNet网络的_Deep Learning Toolbox™模型,则该软件将提供下载链接。AlexNet接受了超过一百万张图像的培训,可以将图像分类为1000种对象类别,例如键盘,鼠标,铅笔和许多动物。结果,该模型为各种图像学习了丰富的特征表示。

  1. net = alexnet;

使用analyzeNetwork展示网络架构和许多关于网络层的接口。

  1. analyzeNetwork(net)

♥ 使用AlexNet迁移学习 - 图3
图3. 网络的可视化
第一层,是图片的输入层,要求输入图片的大小为227x227x3,这个3是指的彩色图的3通道。

  1. inputSize = net.Layers(1).InputSize

inputSize = 1×3

227 227 3

换掉最后一层

预训练网络的最后三层net配置为1000个班级。对于新的分类问题,必须对这三层进行微调。从预训练的网络中提取除最后三层以外的所有层。

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

通过将最后三层替换为完全连接的层,softmax层和分类输出层,将层转移到新的分类任务。根据新数据指定新的完全连接层的选项。将完全连接的层设置为与新数据中的类数相同的大小。要在新层中学习比在传输层中学习更快,请增加完全连接层的WeightLearnRateFactorBiasLearnRateFactor值。

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

numClasses = 5

  1. layers = [
  2. layersTransfer
  3. fullyConnectedLayer(numClasses,'WeightLearnRateFactor',20,'BiasLearnRateFactor',20)
  4. softmaxLayer
  5. classificationLayer];

训练网络

网络要求输入图像的大小为227×227×3,但是图像数据存储区中的图像具有不同的大小。使用增强图像数据存储区来自动调整训练图像的大小。指定要在训练图像上执行的其他增强操作:沿垂直轴随机翻转训练图像,然后将它们随机水平和垂直平移最多30个像素。数据增强有助于防止网络过度拟合和记忆训练图像的确切细节。

  1. pixelRange = [-30 30];
  2. imageAugmenter = imageDataAugmenter( ...
  3. 'RandXReflection',true, ...
  4. 'RandXTranslation',pixelRange, ...
  5. 'RandYTranslation',pixelRange);
  6. augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
  7. 'DataAugmentation',imageAugmenter);

要在不执行进一步数据扩充的情况下自动调整验证图像的大小,请使用扩充图像数据存储,而无需指定任何其他预处理操作。

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

指定训练选项。对于转移学习,请保留预训练网络早期层的特征(转移层权重)。要减慢传输层中的学习速度,请将初始学习速率设置为较小的值。在上一步中,您增加了全连接层的学习速率因子,以加快新的最终层的学习速度。学习率设置的这种组合导致仅在新层中进行快速学习,而在其他层中进行较慢的学习。进行转学时,您不需要培训很多时间。时期是整个训练数据集的完整训练周期。指定小批量大小和验证数据。该软件ValidationFrequency在训练过程中的每一次迭代都会验证网络。

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

训练由传输层和新层组成的网络。默认情况下,trainNetwork使用GPU(如果有)(需要Parallel Computing Toolbox™和具有CUDA®功能且计算能力为3.0或更高的GPU)。否则,它将使用CPU。您还可以通过使用'ExecutionEnvironment'名称/值对参数指定执行环境trainingOptions

  1. netTransfer = trainNetwork(augimdsTrain,layers,options);

♥ 使用AlexNet迁移学习 - 图4
图4. 训练网络

分类验证数据

使用 classify来对验证集进行分类

  1. [YPred, scores] = classify(netTransfer, augimdsValidation);

展示一些验证集照片和它们的预测结果
♥ 使用AlexNet迁移学习 - 图5
图5. 预测结果
计算分类结果的准确性

  1. YValidation = imdsValidation.Labels;
  2. accuracy = mean(YPred == YValidation)

accuracy = 1

要提升分类的准确率,参见Deep Learning Tips and Tricks.