尝试多种预先训练的网络进行迁移学习
这个例子展示了如何配置一个实验,以取代不同预先训练的网络层来进行迁移学习。迁移学习是深度学习应用中常用的一种方法。你可以把一个预先训练好的网络作为学习新任务的起点。用迁移学习对网络进行优化通常比用随机初始化的权重从头开始训练网络要快得多,也容易得多。您可以使用较少的训练图像快速地将学到的特征转移到新任务中。
在深度学习工具箱™中有许多预先训练过的网络。这些预先训练过的网络具有不同的特征,这些特征在选择网络应用于您的问题时非常重要。最重要的特征是网络的准确性、速度和规模。选择网络通常是在这些特征之间进行权衡。要比较任务中不同预训练网络的性能,请编辑此实验并指定要使用哪个预训练网络。
本实验需要深度学习工具箱模型GoogLeNet网络支持包和深度学习工具箱模型ResNet-18网络支持包。在运行实验之前,通过调用googlenet
而且resnet18
函数并单击下载链接。有关可从Add-On Explorer下载的其他预训练网络的更多信息,请参见预训练深度神经网络.
开放实验
首先,打开示例。实验管理器加载带有可检查和运行的预配置实验的项目。打开实验,在实验的浏览器窗格中,双击实验名称(TransferLearningExperiment
).
内置训练实验由描述、超参数表、设置函数和度量函数集合组成,用于评估实验结果。有关更多信息,请参见配置内置训练实验.
的描述字段包含实验的文本描述。对于本例,描述如下:
通过替换预训练网络中的层来执行迁移学习。
的Hyperparameters部分指定策略(详尽的扫描
)和超参数值用于实验。当运行实验时,实验管理器使用超参数表中指定的超参数值的每个组合来训练网络。在本例中,是超参数NetworkName
指定要训练的网络和训练选项的值miniBatchSize
.
的设置函数为实验配置训练数据、网络架构和训练选项。setup函数的输入是一个包含超参数表字段的结构。setup函数返回三个输出,用于训练网络处理图像分类问题。在这个例子中,setup函数:
加载与超参数对应的预训练网络
NetworkName
.
networkName = params.NetworkName;
开关networkName情况下“squeezenet”网= squeezenet;miniBatchSize = 128;情况下“googlenet”网= googlenet;miniBatchSize = 128;情况下“resnet18”网= resnet18;miniBatchSize = 128;情况下“mobilenetv2”网= mobilenetv2;miniBatchSize = 128;情况下“resnet50”网= resnet50;miniBatchSize = 128;情况下“resnet101”网= resnet101;miniBatchSize = 64;情况下“inceptionv3”网= inceptionv3;miniBatchSize = 64;情况下“inceptionresnetv2”网= inceptionresnetv2;miniBatchSize = 64;否则错误(“未定义的网络选择。”);结束
下载并提取Flowers数据集,其大小约为218 MB。有关该数据集的更多信息,请参阅图像数据集.
url =“http://download.tensorflow.org/example_images/flower_photos.tgz”;downloadFolder = tempdir;文件名= fullfile (downloadFolder,“flower_dataset.tgz”);
imageFolder = fullfile (downloadFolder,“flower_photos”);如果~存在(imageFolder“dir”) disp ("正在下载花卉数据集(218 MB)…") websave(文件名,url);解压(文件名,downloadFolder)结束
imd = imageDatastore (imageFolder,...IncludeSubfolders = true,...LabelSource =“foldernames”);
[imdsTrain, imdsValidation] = splitEachLabel (imd, 0.9);inputSize = net.Layers (1) .InputSize;augimdsTrain = augmentedImageDatastore (inputSize imdsTrain);augimdsValidation = augmentedImageDatastore (inputSize imdsValidation);
lgraph = layerGraph(净);[learnableLayer, classLayer] = findLayersToReplace (lgraph);numClasses =元素个数(类别(imdsTrain.Labels));
如果isa (learnableLayer“nnet.cnn.layer.FullyConnectedLayer”newLearnableLayer = fulllyconnectedlayer (numClasses,...Name =“new_fc”,...WeightLearnRateFactor = 10,...BiasLearnRateFactor = 10);elseifisa (learnableLayer“nnet.cnn.layer.Convolution2DLayer”) newLearnableLayer = convolution2dLayer(1,numClasses,...Name =“new_conv”,...WeightLearnRateFactor = 10,...BiasLearnRateFactor = 10);结束
lgraph = replaceLayer (lgraph learnableLayer.Name newLearnableLayer);
newClassLayer = classificationLayer (Name =“new_classoutput”);lgraph = replaceLayer (lgraph classLayer.Name newClassLayer);
定义了一个
trainingOptions
实验对象。该示例使用初始学习率0.0003训练网络10个周期,并每5个周期验证网络。
validationFrequencyEpochs = 5;
numObservations = augimdsTrain.NumObservations;numIterationsPerEpoch =地板(numObservations / miniBatchSize);validationFrequency = validationFrequencyEpochs * numIterationsPerEpoch;
选择= trainingOptions (“个”,...MaxEpochs = 10,...MiniBatchSize = MiniBatchSize,...InitialLearnRate = 3的军医,...洗牌=“every-epoch”,...ValidationData = augimdsValidation,...ValidationFrequency = ValidationFrequency,...Verbose = false);
要检查设置功能,请在设置函数,点击编辑.在MATLAB®编辑器中打开setup函数。此外,setup函数的代码出现在附录1在这个例子的最后。
的指标节指定评估实验结果的可选函数。此示例不包括任何自定义度量函数。
运行实验
在运行实验时,实验管理器将对setup函数定义的网络进行六次训练。每次试验使用不同的超参数值组合。默认情况下,实验管理器每次运行一个试验。如果您有并行计算工具箱™,您可以同时运行多个试验,或者将试验卸载为集群中的批处理作业。
一次做一个试验,在实验管理器将来发布,在模式中,选择
顺序
并点击运行.同时进行多个试验,在模式中,选择
同时
并点击运行.如果当前没有并行池,experimental Manager将使用默认集群配置文件启动一个并行池。然后,实验管理器运行与并行池中工作人员数量相同的同步测试。为了获得最好的结果,在运行实验之前,启动一个与gpu数量相同的并行池。有关更多信息,请参见使用实验管理器并行训练网络而且GPU计算的需求(并行计算工具箱).要将实验作为批处理作业卸载,请在模式中,选择
批处理顺序
或批处理同时
,指定你集群而且池大小,然后单击运行.有关更多信息,请参见将实验作为批处理作业卸载到集群.
结果表显示了每次试验的准确性和损失。
方法完成实验后,可以按列对结果表进行排序,对试验进行筛选过滤器窗格,或通过添加注释记录观察结果。有关更多信息,请参见对实验结果进行排序、筛选和注释.
要测试单个试验的性能,请导出训练过的网络或试验的训练信息。在实验管理器将来发布,选择出口>训练网络或出口>培训信息,分别。有关更多信息,请参见网而且信息.将结果表的内容保存为表格
数组在MATLAB工作空间,选择出口>结果表.
关闭实验
在实验的浏览器窗格中,右键单击项目的名称并选择关闭项目.实验管理器关闭项目中包含的所有实验和结果。
附录1:Setup函数
该功能为实验配置训练数据、网络架构和训练选项。
输入
参数个数
是一个包含来自实验管理器超参数表字段的结构。
输出
augimdsTrain
是用于训练数据的增强图像数据存储。lgraph
是定义神经网络体系结构的层图。选项
是一个trainingOptions
对象。
函数[augimdsTrain,lgraph,options] = TransferLearningExperiment_setup1(params) networkName = params. networkName;开关networkName情况下“squeezenet”网= squeezenet;miniBatchSize = 128;情况下“googlenet”网= googlenet;miniBatchSize = 128;情况下“resnet18”网= resnet18;miniBatchSize = 128;情况下“mobilenetv2”网= mobilenetv2;miniBatchSize = 128;情况下“resnet50”网= resnet50;miniBatchSize = 128;情况下“resnet101”网= resnet101;miniBatchSize = 64;情况下“inceptionv3”网= inceptionv3;miniBatchSize = 64;情况下“inceptionresnetv2”网= inceptionresnetv2;miniBatchSize = 64;否则错误(“未定义的网络选择。”);结束url =“http://download.tensorflow.org/example_images/flower_photos.tgz”;downloadFolder = tempdir;文件名= fullfile (downloadFolder,“flower_dataset.tgz”);imageFolder = fullfile (downloadFolder,“flower_photos”);如果~存在(imageFolder“dir”) disp ("正在下载花卉数据集(218 MB)…") websave(文件名,url);解压(文件名,downloadFolder)结束imd = imageDatastore (imageFolder,...IncludeSubfolders = true,...LabelSource =“foldernames”);[imdsTrain, imdsValidation] = splitEachLabel (imd, 0.9);inputSize = net.Layers (1) .InputSize;augimdsTrain = augmentedImageDatastore (inputSize imdsTrain);augimdsValidation = augmentedImageDatastore (inputSize imdsValidation);lgraph = layerGraph(净);[learnableLayer, classLayer] = findLayersToReplace (lgraph);numClasses =元素个数(类别(imdsTrain.Labels));如果isa (learnableLayer“nnet.cnn.layer.FullyConnectedLayer”newLearnableLayer = fulllyconnectedlayer (numClasses,...Name =“new_fc”,...WeightLearnRateFactor = 10,...BiasLearnRateFactor = 10);elseifisa (learnableLayer“nnet.cnn.layer.Convolution2DLayer”) newLearnableLayer = convolution2dLayer(1,numClasses,...Name =“new_conv”,...WeightLearnRateFactor = 10,...BiasLearnRateFactor = 10);结束lgraph = replaceLayer (lgraph learnableLayer.Name newLearnableLayer);newClassLayer = classificationLayer (Name =“new_classoutput”);lgraph = replaceLayer (lgraph classLayer.Name newClassLayer);validationFrequencyEpochs = 5;numObservations = augimdsTrain.NumObservations;numIterationsPerEpoch =地板(numObservations / miniBatchSize);validationFrequency = validationFrequencyEpochs * numIterationsPerEpoch;选择= trainingOptions (“个”,...MaxEpochs = 10,...MiniBatchSize = MiniBatchSize,...InitialLearnRate = 3的军医,...洗牌=“every-epoch”,...ValidationData = augimdsValidation,...ValidationFrequency = ValidationFrequency,...Verbose = false);结束
附录2:找到要替换的图层
该函数查找层图的单个分类层和前面的可学习(全连通或卷积)层lgraph
.
函数[learnableLayer, classLayer] = findLayersToReplace (lgraph)如果~ isa (lgraph“nnet.cnn.LayerGraph”)错误(参数必须是LayerGraph对象)结束src =字符串(lgraph.Connections.Source);dst =字符串(lgraph.Connections.Destination);layerNames =字符串({lgraph.Layers.Name} ');isClassificationLayer = arrayfun(@(左)...(isa (l,“nnet.cnn.layer.ClassificationOutputLayer”) | isa (l,“nnet.layer.ClassificationLayer”)),...lgraph.Layers);如果sum(isClassificationLayer) ~= 1 error(“图层图必须有一个单独的分类层。”)结束classLayer = lgraph.Layers (isClassificationLayer);currentLayerIdx =找到(isClassificationLayer);而真正的如果numel(currentLayerIdx) ~= 1错误(“层图必须在分类层之前有一个可学习层。”)结束currentLayerType =类(lgraph.Layers (currentLayerIdx));isLearnableLayer = ismember (currentLayerType,...[“nnet.cnn.layer.FullyConnectedLayer”,“nnet.cnn.layer.Convolution2DLayer”]);如果learnableLayer = lgraph.Layers(currentLayerIdx);返回结束currentDstIdx = find(layerNames(currentLayerIdx) == dst);currentLayerIdx = find(src(currentDstIdx) == layerNames);结束结束