Main Content

迁移学习快速入门

此示例说明如何使用深度网络设计器为迁移学习准备网络。

深度学习应用中常常用到迁移学习。您可以采用预训练的网络,基于它学习新任务。与使用随机初始化的权重从头训练网络相比,通过迁移学习微调网络要更快更简单。您可以使用较少数量的训练图像快速地将已学习的特征迁移到新任务。

加载图像数据

在工作区中,提取 MathWorks® Merch 数据集。要访问此数据,请以实时脚本形式打开此示例。这个小型数据集包含 75 幅 MathWorks 商品图像,它们分属五个不同类(瓶盖、魔方、扑克牌、螺丝刀和手电筒)。

folderName = "MerchData";
unzip("MerchData.zip",folderName);

创建一个图像数据存储。通过图像数据存储可以存储大图像数据集合,包括无法放入内存的数据,并在神经网络的训练过程中高效分批读取图像。指定包含提取图像的文件夹,并指示子文件夹名称与图像标签对应。

imds = imageDatastore(folderName, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");

显示一些示例图像。

numImages = numel(imds.Labels);
idx = randperm(numImages,16);
I = imtile(imds,Frames=idx);
figure
imshow(I)

提取类名称和类数目。

classNames = categories(imds.Labels);
numClasses = numel(classNames);

将数据划分为训练、验证和测试数据集。将 70% 的图像用于训练,15% 的图像用于验证,15% 的图像用于测试。splitEachLabel 函数将图像数据存储拆分为三个新数据存储。

[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.7,0.15,0.15,"randomized");

加载预训练网络

要针对新任务调整预训练的神经网络,请使用深度网络设计器。

deepNetworkDesigner

从预训练网络列表中选择 SqueezeNet,然后点击打开

深度网络设计器将显示整个网络的缩小视图。

编辑迁移学习网络

要重新训练 SqueezeNet 以对新图像进行分类,请编辑网络的最后一个二维卷积层 conv10

设计器窗格中,选择 conv10 层。在属性窗格的底部,点击解锁层。在出现的警告对话框中,点击仍要解锁。这样做会解锁层属性,以便您使其适应新任务。

NumFilters 属性设置为新的类数,在此示例中为 5。通过将 WeightLearnRateFactorBiasLearnRateFactor 设置为 10 来更改学习率,使新层中的学习速度快于迁移层的学习速度。

要检查网络是否准备好进行训练,请点击分析。深度学习网络分析器报告零错误或警告,因此,网络已准备就绪,可以开始进行训练。要导出网络,请点击导出。该 App 将网络保存在变量 net_1 中。

指定训练选项

指定训练选项。在选项中进行选择需要经验分析。要通过运行试验探索不同训练选项配置,您可以使用Experiment Manager

options = trainingOptions("adam", ...
    ValidationData=imdsValidation, ...
    ValidationFrequency=5, ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

训练神经网络

使用 trainnet 函数训练神经网络。由于目的是分类,因此使用交叉熵损失。

net = trainnet(imdsTrain,net_1,"crossentropy",options);

测试神经网络

对测试图像进行分类。要使用多个观测值进行预测,请使用 minibatchpredict 函数。要将预测分数转换为标签,请使用 scores2label 函数。minibatchpredict 函数自动使用 GPU(如果有)。

inputSize = net.Layers(1).InputSize(1:2);

augimdsTrain = augmentedImageDatastore(inputSize,imdsTest);

YTest = minibatchpredict(net,imdsTest);
YTest = scores2label(YTest,classNames);

在混淆图中可视化分类准确度。

TTest = imdsTest.Labels;
figure
confusionchart(TTest,YTest);

对新图像进行分类

对一个测试图像进行分类。从 JPEG 文件中读取一个图像,调整其大小,并将其转换为 single 数据类型。

im = imread("MerchDataTest.jpg");

im = imresize(im,inputSize(1:2));
X = single(im);

对图像进行分类。要使用单个观测值进行预测,请使用 predict 函数。

scores = predict(net,X);
[label,score] = scores2label(scores,classNames);

显示具有预测标签和对应分数的图像。

figure
imshow(im)
title(string(label) + " (Score: " + gather(score) + ")")

要了解有关迁移学习以及如何提高网络性能的更多信息,请参阅Retrain Neural Network to Classify New Images

参考

[1] ImageNet. http://www.image-net.org.

[2] Iandola, Forrest N., Song Han, Matthew W. Moskewicz, Khalid Ashraf, William J. Dally, and Kurt Keutzer. "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5 MB model size." Preprint, submitted November 4, 2016. https://arxiv.org/abs/1602.07360.

[3] Iandola, Forrest N. "SqueezeNet." https://github.com/forresti/SqueezeNet.

另请参阅

| | | |

相关主题