Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

使用深度网络设计器进行迁移学习

此示例说明如何使用深度网络设计器以交互方式执行迁移学习。

迁移学习指采用预训练的深度学习网络并对其进行微调以学习新任务的过程。使用迁移学习通常比从头开始训练网络更快、更简单。您可以使用更少的数据量将学习到的特征快速迁移到新任务中。

按照以下步骤进行操作,使用深度网络设计器执行迁移学习以进行图像分类:

  1. 打开深度网络设计器,选择一个预训练网络。

  2. 导入新数据集。

  3. 用适应新数据集的新层替换最终层。

  4. 设置学习率,使新层中的学习速度快于迁移的层。

  5. 使用深度网络设计器训练网络,或通过命令行导出网络进行训练。

提取数据

在工作区中,提取 MathWorks Merch 数据集。这是包含 75 幅 MathWorks 商品图像的小型数据集,这些商品分属五个不同类(瓶盖魔方扑克牌螺丝刀手电筒)。

unzip("MerchData.zip");

选择预训练网络

要打开深度网络设计器,请在 App 选项卡上的机器学习和深度学习下,点击该 App 的图标。您也可以从命令行打开该 App:

deepNetworkDesigner

深度网络设计器提供一些精选的预训练图像分类网络,这些网络已学习适用于各种图像的丰富特征表示。如果您的图像与最初用于训练网络的图像相似,迁移学习效果最好。如果您的训练图像是像 ImageNet 数据库中那样的自然图像,则任一预训练网络都合适。有关可用网络的列表以及如何比较它们,请参阅预训练的深度神经网络

如果您的数据与 ImageNet 数据相差很大(例如,如果您有很小的图像、频谱图或非图像数据),训练新网络可能效果更好。有关如何从头开始训练网络的示例,请参阅Create Simple Sequence Classification Network Using Deep Network DesignerCreate Simple Semantic Segmentation Network in Deep Network Designer

SqueezeNet 不需要额外的支持包。对于其他预训练网络,如果您没有安装所需的支持包,则该 App 提供安装选项。

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

浏览网络

深度网络设计器在 Designer 窗格中显示整个网络的缩小视图。

浏览网络图。要使用鼠标放大,请使用 Ctrl + 滚轮。要平移,请使用箭头键,或按住滚轮并拖动鼠标。选择一个层以查看其属性。取消选择所有层,以在属性窗格中查看网络摘要。

导入数据

要将数据加载到深度网络设计器中,请在数据选项卡上,点击导入数据 > 导入图像数据。将打开“导入图像数据”对话框。

数据源列表中,选择文件夹。点击浏览并选择提取的 MerchData 文件夹。

图像增强

您可以选择将图像增强应用于您的训练数据。深度网络设计器提供以下增强选项:

  • x 轴上的随机翻转

  • y 轴上的随机翻转

  • 随机旋转

  • 随机重新缩放

  • 随机水平平移

  • 随机垂直平移

通过对数据应用随机增强,您实际上是增加了训练数据量。增强还使您能够训练网络,使其在图像数据失真时仍保持稳定。例如,您可以对输入图像添加随机旋转,使网络不会因输入图像中存在旋转而改变。

对于此示例,在 x 轴上进行随机翻转,在 [-90,90] 度范围内进行随机旋转,在 [1,2] 范围内进行随机重新缩放。

验证数据

您还可以选择导入验证数据,您可以从训练数据中拆分出验证数据,也可以从其他来源导入。验证会估计新数据与训练数据相比的模型性能,并帮助您监控性能和防止过拟合。

对于此示例,我们将 30% 的图像用于验证。

点击导入将数据导入深度网络设计器。

可视化数据

使用深度网络设计器,您可以在数据窗格中直观地查看训练和验证数据的分布情况。您可以看到在此示例中数据集中有五个类。您也可以看到每个类的随机观测值。

准备要训练的网络

Designer 窗格中编辑网络,以在数据中指定新的类数量。要为迁移学习准备网络,请替换最后一个可学习层和最终分类层。

替换最后一个可学习层

要使用预训练网络进行迁移学习,您必须更改类的数量以匹配新数据集。首先,找到网络中的最后一个可学习层。对于 SqueezeNet,最后一个可学习层是最后一个卷积层,'conv10'。在这种情况下,请将该卷积层替换为新的卷积层,其中滤波器的数量等于类的数量。

将一个新 convolution2dLayer 拖到画布上。要匹配原始卷积层,请将 FilterSize 设置为 1,1

NumFilters 属性定义用于分类问题的类的数量。将 NumFilters 更改为新数据中的类数量,此示例中为 5

通过将 WeightLearnRateFactorBiasLearnRateFactor 设置为 10 来更改学习率,使新层中的学习速度快于迁移层的学习速度。

删除最后一个二维卷积层,改为连接新层。

替换输出层

要进行迁移学习,您需要替换输出层。滚动到网络层库的末尾,将一个新的 classificationLayer 拖到画布上。删除原始分类层,并在其位置连接新层。

对于新输出层,您不需要设置 OutputSize。在训练时,深度网络设计器会根据数据自动设置层的输出类。

检查网络

要检查网络是否准备好进行训练,请点击分析。如果 Deep Learning Network Analyzer 报告零错误,则表示编辑过的网络已准备就绪可以开始训练。

训练网络

在深度网络设计器中,您可以训练在该 App 中导入或创建的网络。

要使用默认设置训练网络,请在训练选项卡上,点击训练。默认训练选项更适合大型数据集,对于小型数据集,请减少小批量大小和验证频率。

如果您要更好地控制训练,请点击训练选项,然后选择训练所用的设置。

  • 将初始学习率设置为较小的值以减慢迁移的层中的学习速度。

  • 指定验证频率,以便每经过一轮训练就计算一次基于验证数据的准确度。

  • 指定少量轮数。一轮训练是对整个训练数据集的一个完整训练周期。对于迁移学习,所需的训练轮数相对较少。

  • 指定小批量大小,即每次迭代中使用多少个图像。为了确保在每轮训练中都使用整个数据集,请设置小批量大小以均分训练样本的数量。

对于此示例,将 InitialLearnRate 设置为 0.0001ValidationFrequency 设置为 5MaxEpochs 设置为 8。由于有 55 个观测值,请将 MiniBatchSize 设置为 11 以均分训练数据,并确保您在每轮训练期间都使用整个训练数据集。有关选择训练选项的详细信息,请参阅trainingOptions

要使用指定的训练选项训练网络,请点击关闭,然后点击训练

深度网络设计器允许您可视化和监控训练进度。然后,如果需要,您可以编辑训练选项并重新训练网络。

导出结果并生成 MATLAB 代码

要导出具有训练权重的网络架构,请在训练选项卡上,选择导出 > 导出经过训练的网络和结果。深度网络设计器将经过训练的网络导出为变量 trainedNetwork_1,将训练信息导出为变量 trainInfoStruct_1

trainInfoStruct_1
trainInfoStruct_1 = struct with fields:
               TrainingLoss: [1×40 double]
           TrainingAccuracy: [1×40 double]
             ValidationLoss: [4.3374 NaN NaN NaN 2.4329 NaN NaN NaN NaN 1.3966 NaN NaN NaN NaN 0.7526 NaN NaN NaN NaN 0.6424 NaN NaN NaN NaN 0.6349 NaN NaN NaN NaN 0.5940 NaN NaN NaN NaN 0.5490 NaN NaN NaN NaN 0.5179]
         ValidationAccuracy: [10 NaN NaN NaN 15 NaN NaN NaN NaN 40 NaN NaN NaN NaN 70 NaN NaN NaN NaN 85 NaN NaN NaN NaN 90 NaN NaN NaN NaN 85 NaN NaN NaN NaN 90 NaN NaN NaN NaN 95]
              BaseLearnRate: [1×40 double]
        FinalValidationLoss: 0.5179
    FinalValidationAccuracy: 95

您也可以生成 MATLAB 代码,它可以重新创建所使用的网络和训练选项。在训练选项卡上,选择导出 > 生成训练代码。查看 MATLAB 代码,了解如何以编程方式准备训练数据、创建网络架构和训练网络。

对新图像进行分类

加载一个新图像以使用经过训练的网络对其进行分类。

I = imread("MerchDataTest.jpg");

深度网络设计器会在训练期间调整图像大小,以匹配网络输入大小。要查看网络输入大小,请转至 Designer 窗格,然后选择 imageInputLayer(第一层)。该网络的输入大小为 227×227。

调整测试图像的大小以匹配网络输入大小。

I = imresize(I, [227 227]);

使用经过训练的网络对测试图像进行分类。

[YPred,probs] = classify(trainedNetwork_1,I);
imshow(I)
label = YPred;
title(string(label) + ", " + num2str(100*max(probs),3) + "%");

另请参阅

相关主题