主要内容

运行一个定制的培训实验图像进行比较

自从R2021a

这个例子展示了如何创建一个自定义训练实验训练的暹罗网络手写字符识别类似的图像。自定义训练实验,您显式地定义所使用的训练过程实验管理器。在本例中,您实现一个自定义训练循环训练暹罗网络,一种深入学习网络,使用相同的两个或两个以上相同的子网,架构和共享相同的参数和权值。一些常见的应用程序为暹罗网络包括面部识别、签名验证,解释识别。

这个图表说明了暹罗网络体系结构。

比较两个图像,每幅图像通过一个共享的两个相同的子网权重。每个子网将105 -通过- 105 - 1图像4096维的特征向量。同一个类的图像也有类似4096 -维表示。每个子网的输出特征向量相结合通过减法和结果是通过fullyconnect操作与单个输出。乙状结肠操作将该值转换为一个概率说明图片是相似的(当概率接近于1)或不同的(当概率接近于0)。网络之间的二进制叉损失预测和真正的标签更新网络在训练。有关更多信息,请参见火车暹罗网络比较图像

开放实验

首先,打开示例。实验管理器加载一个预配置实验的项目,你可以检查和运行。开放实验,实验的浏览器面板,双击ImageComparisonExperiment

定制培训实验由一个描述,hyperparameters表和培训功能。有关更多信息,请参见配置自定义训练实验

描述字段包含的文本描述的实验。对于这个例子,描述是:

火车暹罗网络来识别手写字符的相似和不同的图像。尝试不同的重量和偏见的卷积和完全连接层初始化网络。

Hyperparameters节指定策略和hyperparameter值用于实验。当您运行实验,实验管理器使用每一列车网络的组合hyperparameter hyperparameter表中指定的值。下面的例子使用了hyperparametersWeightsInitializerBiasInitializer初始化器指定重量和偏见,分别为卷积和完全连接在每个子网层。关于这些初始化器的更多信息,见WeightsInitializerBiasInitializer

培训功能部分指定一个函数,定义了训练数据,网络体系结构,培训方案和培训过程所使用的实验。在MATLAB®编辑器打开这个功能,点击编辑。函数的代码也出现在培训功能。训练的输入函数是一个结构从hyperparameter表和字段experiments.Monitor对象,您可以使用它来跟踪培训的进度,记录值的指标使用的培训,和生产培训的阴谋。函数返回一个结构,包含训练网络,最终的重量fullyconnect为网络操作,用于培训的执行环境。实验管理器保存此输出可以出口到MATLAB工作区当培训完成。这些部分:训练函数

  • 初始化输出网络的初始值和集fullyconnect权重空数组,表明训练还没有开始。实验设置执行环境“汽车”,所以火车和验证GPU如果一个可用网络。使用GPU需要并行计算工具箱™和支持GPU设备。万博1manbetx有关更多信息,请参见GPU计算的需求(并行计算工具箱)

output.network = [];输出。重量= [];输出。executionEnvironment =“汽车”;
  • 加载和预处理训练和测试数据定义了实验的训练和测试数据imageDatastore对象。实验采用Omniglot数据集,由50个字母字符集,分为30集培训和20集进行测试。这个数据集的更多信息,请参阅图像数据集

班长。状态=“加载训练数据”;url =“https://github.com/brendenlake/omniglot/raw/master/python/images_background.zip”;downloadFolder = tempdir;文件名= fullfile (downloadFolder,“images_background.zip”);dataFolderTrain = fullfile (downloadFolder,“images_background”);如果~存在(dataFolderTrain“dir”)websave(文件名,url);解压缩(文件名,downloadFolder);结束imdsTrain = imageDatastore (dataFolderTrain,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTrain.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“_”);imdsTrain。=分类标签(标签);班长。状态=“装载测试数据”;url =“https://github.com/brendenlake/omniglot/raw/master/python/images_evaluation.zip”;文件名= fullfile (downloadFolder,“images_evaluation.zip”);dataFolderTest = fullfile (downloadFolder,“images_evaluation”);如果~存在(dataFolderTest“dir”)websave(文件名,url);解压缩(文件名,downloadFolder);结束imdsTest = imageDatastore (dataFolderTest,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTest.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“_”);imdsTest。=分类标签(标签);
  • 定义网络体系结构定义了两个相同的子网,接受105年的建筑-通过- 105 - 1图像和输出一个特征向量。卷积和完全连接层使用重量和偏见hyperparameter表中指定初始值设定项。训练网络使用一个自定义训练循环和启用自动分化,训练函数转换层图dlnetwork对象。最终的重量fullyconnect操作被抽样的随机选择初始化一个狭窄的正态分布标准差为0.01。

班长。状态=“创建网络”;层= [imageInputLayer(105 105 1,标准化=“没有”64年)convolution2dLayer(10日,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () maxPooling2dLayer(2步= 2)convolution2dLayer(7128年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () maxPooling2dLayer(2步= 2)convolution2dLayer(4128年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () maxPooling2dLayer(2步= 2)convolution2dLayer(5256年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () fullyConnectedLayer(4096年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer)];lgraph = layerGraph(层);网= dlnetwork (lgraph);fcWeights = dlarray (0.01 * randn (4096);fcBias = dlarray (0.01 * randn (1,1));fcParams =结构(“FcWeights”fcWeights,“FcBias”,fcBias);output.network =净;输出。重量= fcParams;
  • 指定培训选项定义使用的培训选择实验。在这个例子中,实验经理列车网络mini-batch大小为180 1000次迭代,每100次迭代计算网络的准确性。培训可以花费一些时间来运行。为了更好的结果,请考虑增加10000次迭代的训练。

numIterations = 1000;miniBatchSize = 180;validationFrequency = 100;initialLearnRate = 6 e-5;gradientDecayFactor = 0.9;squaredGradientDecayFactor = 0.99;trailingAvgSubnet = [];trailingAvgSqSubnet = [];trailingAvgParams = [];trailingAvgSqParams = [];
  • 火车模型定义了自定义训练循环使用的实验。对于每一次迭代,定制培训循环提取一批图像对和标签,转换数据dlarray对象与基本类型单一,指定尺寸标签“SSCB”(空间、空间、通道、批处理)的图像数据“CB”(通道、批处理)的标签。如果你训练GPU,数据转换为gpuArray(并行计算工具箱)对象。然后,训练函数评估损失并更新网络参数的模型。验证,培训函数创建一组五个随机mini-batches测试对,评估网络预测和计算平均mini-batches准确性。自定义训练循环的每次迭代后,培训功能节省训练网络的权重fullyconnect操作,记录培训损失,并更新培训的进展。

班长。指标= [“TrainingLoss”“ValidationAccuracy”];班长。包含=“迭代”;班长。状态=“培训”;迭代= 1:numIterations [X1, X2, pairLabels] = getSiameseBatch (imdsTrain miniBatchSize);X1 = dlarray(单(X1)、“SSCB”);X2 = dlarray(单(X2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”X1 = gpuArray (X1);X2 = gpuArray (X2);结束[损失,gradientsSubnet, gradientsParams] = dlfeval (@modelLoss,净,fcParams X1, X2, pairLabels);lossValue =双(收集(extractdata(损失)));网,trailingAvgSubnet, trailingAvgSqSubnet =gradientsSubnet adamupdate(净,trailingAvgSubnet trailingAvgSqSubnet,迭代,initialLearnRate、gradientDecayFactor squaredGradientDecayFactor);[fcParams, trailingAvgParams trailingAvgSqParams] =adamupdate (fcParams gradientsParams,trailingAvgParams trailingAvgSqParams,迭代,initialLearnRate、gradientDecayFactor squaredGradientDecayFactor);如果~ rem(迭代,validationFrequency) | |迭代= = 1 | |迭代= = numIterations监视器。状态=“验证”;精度= 0 (1、5);accuracyBatchSize = 150;我= 1:5 (XAcc1、XAcc2 pairLabelsAcc] = getSiameseBatch (imdsTest accuracyBatchSize);XAcc1 = dlarray(单(XAcc1),“SSCB”);XAcc2 = dlarray(单(XAcc2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”XAcc1 = gpuArray (XAcc1);XAcc2 = gpuArray (XAcc2);结束Y = predictSiamese(网,fcParams, XAcc1 XAcc2);Y =圆(Y);准确性(i) = (Y = = pairLabelsAcc) / accuracyBatchSize总和;结束recordMetrics(监控、迭代ValidationAccuracy =意味着(精度)* 100);班长。状态=“培训”;结束output.network =净;输出。重量= fcParams;recordMetrics(监控、迭代TrainingLoss = lossValue);班长。进步=(迭代/ numIterations) * 100;如果monitor.Stop返回;结束结束
  • 显示对测试图像创建一个小批量的图像对,您可以使用视觉检查网络正确识别相似和不同的配对。培训完成后,审查结果画廊在将来发布图显示一个按钮。的的名字图的属性指定按钮的名称。你可以点击这个按钮显示的图可视化窗格。

testBatchSize = 10;[XTest1, XTest2 pairLabelsTest] = getSiameseBatch (imdsTest testBatchSize);XTest1 = dlarray(单(XTest1),“SSCB”);XTest2 = dlarray(单(XTest2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”XTest1 = gpuArray (XTest1);XTest2 = gpuArray (XTest2);结束YScore = predictSiamese(网,fcParams, XTest1 XTest2);YScore =收集(extractdata (YScore));YPred =圆(YScore);XTest1 = extractdata (XTest1);XTest2 = extractdata (XTest2);图(Name =“测试图像”);标题(tiledlayout (2、5),“测试图像的比较”)i = 1:元素个数(pairLabelsTest)如果pairLabelsTest (i) = = YPred titleStr =(我)“正确”;titleColor =“# 77 ac30”;%深绿色其他的titleStr =“不正确”;titleColor =“# FF0000”;%的红色结束如果YPred (i) = = 1 predStr =“预测:类似”;其他的predStr =“预测:不同”;结束scoreStr =“分数:+ YScore(我);nexttile imshow ([XTest1 (::,:, i) XTest2(::,:,我)]);imageTitle =标题(titleStr [predStr scoreStr]);imageTitle。颜色= titleColor;xticks ([]) yticks ([])结束

运行实验

当您运行实验,实验管理列车网络多次训练函数定义的。每个试验使用不同的组合hyperparameter值。默认情况下,实验管理器运行一个审判。如果你有并行计算工具箱,您可以同时运行多个试验或卸载实验作为批处理作业在集群:

  • 运行一个审判的一次实验,在实验管理器将来发布,在模式中,选择顺序并点击运行

  • 同时,运行多个试验模式中,选择同时并点击运行。如果没有当前并行池、实验管理器启动一个集群使用默认配置文件。实验管理器然后运行尽可能多的同时试验有工人在你平行池。为达到最佳效果,在你运行你的实验,开始与尽可能多的工人gpu并行池。有关更多信息,请参见并行使用实验管理器来训练网络GPU计算的需求(并行计算工具箱)

  • 将实验作为批处理作业,模式中,选择批处理顺序批处理同时,指定你集群池大小,然后单击运行。有关更多信息,请参见卸载实验作为集群的批处理作业

一个表显示的结果为每个审判训练和验证精度损失。

显示培训策划和跟踪每个试验的进展在实验时,审查结果,点击培训策划

评估结果

找到最佳的实验结果,验证结果的准确性对表进行排序。

  1. 指出ValidationAccuracy列。

  2. 点击三角形图标。

  3. 选择按照降序排列

最高的试验验证准确性出现在顶部的结果表。

视觉检查网络和不同的对正确识别相似,选择结果表中的第一行,审查结果,点击测试的图片。实验管理器显示10个随机选择的对测试图像的预测训练网络,概率得分,和一个标签显示的预测是否正确或不正确的。

执行额外的计算,导出培训输出工作空间的结构。的trainedNet这个结构包含了训练网络。

  1. 实验管理器将来发布,点击出口>训练输出

  2. 在对话框窗口中,输入导出的培训工作空间变量的名称输出。默认的名称是trainingOutput

记录对你的实验的结果,添加一个注释。

  1. 在结果表中,右键单击ValidationAccuracy细胞最好的审判。

  2. 选择添加注释

  3. 注释窗格中,在文本框中输入你的观察。

有关更多信息,请参见排序、过滤和注释的实验结果

关闭实验

实验的浏览器窗格中,右键单击项目并选择的名称关闭项目。实验管理器关闭所有的实验和结果包含在项目中。

培训功能

这个函数指定了训练数据、网络架构、培训方案和培训过程中使用的实验。这个函数的输入是一个结构从hyperparameter表字段和一个experiments.Monitor对象,您可以使用它来跟踪培训的进度,记录值的指标使用的培训,和生产培训的阴谋。训练函数返回一个结构,包含训练网络,最终的重量fullyconnect为网络操作,用于培训的执行环境。实验管理器保存此输出可以出口到MATLAB工作区当培训完成。

函数输出= ImageComparisonExperiment_training(参数、监控)

初始化输出

output.network = [];输出。重量= [];输出。executionEnvironment =“汽车”;

加载和预处理训练和测试数据

班长。状态=“加载训练数据”;url =“https://github.com/brendenlake/omniglot/raw/master/python/images_background.zip”;downloadFolder = tempdir;文件名= fullfile (downloadFolder,“images_background.zip”);dataFolderTrain = fullfile (downloadFolder,“images_background”);如果~存在(dataFolderTrain“dir”)websave(文件名,url);解压缩(文件名,downloadFolder);结束imdsTrain = imageDatastore (dataFolderTrain,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTrain.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“_”);imdsTrain。=分类标签(标签);班长。状态=“装载测试数据”;url =“https://github.com/brendenlake/omniglot/raw/master/python/images_evaluation.zip”;文件名= fullfile (downloadFolder,“images_evaluation.zip”);dataFolderTest = fullfile (downloadFolder,“images_evaluation”);如果~存在(dataFolderTest“dir”)websave(文件名,url);解压缩(文件名,downloadFolder);结束imdsTest = imageDatastore (dataFolderTest,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTest.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“_”);imdsTest。=分类标签(标签);

定义网络体系结构

班长。状态=“创建网络”;层= [imageInputLayer(105 105 1,标准化=“没有”64年)convolution2dLayer(10日,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () maxPooling2dLayer(2步= 2)convolution2dLayer(7128年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () maxPooling2dLayer(2步= 2)convolution2dLayer(4128年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () maxPooling2dLayer(2步= 2)convolution2dLayer(5256年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer () fullyConnectedLayer(4096年WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer)];lgraph = layerGraph(层);网= dlnetwork (lgraph);fcWeights = dlarray (0.01 * randn (4096);fcBias = dlarray (0.01 * randn (1,1));fcParams =结构(“FcWeights”fcWeights,“FcBias”,fcBias);output.network =净;输出。重量= fcParams;

指定培训选项

numIterations = 1000;miniBatchSize = 180;validationFrequency = 100;initialLearnRate = 6 e-5;gradientDecayFactor = 0.9;squaredGradientDecayFactor = 0.99;trailingAvgSubnet = [];trailingAvgSqSubnet = [];trailingAvgParams = [];trailingAvgSqParams = [];

火车模型

班长。指标= [“TrainingLoss”“ValidationAccuracy”];班长。包含=“迭代”;班长。状态=“培训”;迭代= 1:numIterations [X1, X2, pairLabels] = getSiameseBatch (imdsTrain miniBatchSize);X1 = dlarray(单(X1)、“SSCB”);X2 = dlarray(单(X2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”X1 = gpuArray (X1);X2 = gpuArray (X2);结束[损失,gradientsSubnet, gradientsParams] = dlfeval (@modelLoss,净,fcParams X1, X2, pairLabels);lossValue =双(收集(extractdata(损失)));网,trailingAvgSubnet, trailingAvgSqSubnet =gradientsSubnet adamupdate(净,trailingAvgSubnet trailingAvgSqSubnet,迭代,initialLearnRate、gradientDecayFactor squaredGradientDecayFactor);[fcParams, trailingAvgParams trailingAvgSqParams] =adamupdate (fcParams gradientsParams,trailingAvgParams trailingAvgSqParams,迭代,initialLearnRate、gradientDecayFactor squaredGradientDecayFactor);如果~ rem(迭代,validationFrequency) | |迭代= = 1 | |迭代= = numIterations监视器。状态=“验证”;精度= 0 (1、5);accuracyBatchSize = 150;我= 1:5 (XAcc1、XAcc2 pairLabelsAcc] = getSiameseBatch (imdsTest accuracyBatchSize);XAcc1 = dlarray(单(XAcc1),“SSCB”);XAcc2 = dlarray(单(XAcc2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”XAcc1 = gpuArray (XAcc1);XAcc2 = gpuArray (XAcc2);结束Y = predictSiamese(网,fcParams, XAcc1 XAcc2);Y =圆(Y);准确性(i) = (Y = = pairLabelsAcc) / accuracyBatchSize总和;结束recordMetrics(监控、迭代ValidationAccuracy =意味着(精度)* 100);班长。状态=“培训”;结束output.network =净;输出。重量= fcParams;recordMetrics(监控、迭代TrainingLoss = lossValue);班长。进步=(迭代/ numIterations) * 100;如果monitor.Stop返回;结束结束

显示对测试图像

testBatchSize = 10;[XTest1, XTest2 pairLabelsTest] = getSiameseBatch (imdsTest testBatchSize);XTest1 = dlarray(单(XTest1),“SSCB”);XTest2 = dlarray(单(XTest2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”XTest1 = gpuArray (XTest1);XTest2 = gpuArray (XTest2);结束YScore = predictSiamese(网,fcParams, XTest1 XTest2);YScore =收集(extractdata (YScore));YPred =圆(YScore);XTest1 = extractdata (XTest1);XTest2 = extractdata (XTest2);图(Name =“测试图像”);标题(tiledlayout (2、5),“测试图像的比较”)i = 1:元素个数(pairLabelsTest)如果pairLabelsTest (i) = = YPred titleStr =(我)“正确”;titleColor =“# 77 ac30”;%深绿色其他的titleStr =“不正确”;titleColor =“# FF0000”;%的红色结束如果YPred (i) = = 1 predStr =“预测:类似”;其他的predStr =“预测:不同”;结束scoreStr =“分数:+ YScore(我);nexttile imshow ([XTest1 (::,:, i) XTest2(::,:,我)]);imageTitle =标题(titleStr [predStr scoreStr]);imageTitle。颜色= titleColor;xticks ([]) yticks ([])结束
结束

辅助函数

modelLoss函数作为输入暹罗dlnetwork对象,一双mini-batch输入数据X1X2,标签指示是否相似或相异的。函数返回损失对可学的参数之间的网络和二进制叉损失预测和地面真理。

函数[损失,gradientsSubnet, gradientsParams] = modelLoss(净、fcParams X1, X2, pairLabels) Y = forwardSiamese(净、fcParams X1, X2);损失= binarycrossentropy (Y, pairLabels);[gradientsSubnet, gradientsParams] = dlgradient(损失,net.Learnables fcParams);结束

binarycrossentropy函数返回的二叉叉损失值的预测网络。

函数精度损失= binarycrossentropy (Y, pairLabels) = underlyingType (Y);Y (Y < eps(精密))=每股收益(精度);Y (Y > 1 - eps(精密))= 1 - eps(精度);
损失= -pairLabels。*日志(Y) - (1 - pairLabels)。*日志(1 - Y);损失=(亏损)/元素个数之和(pairLabels);结束

forwardSiamese函数定义子网和如何fullyconnect乙状结肠操作相结合,形成完整的暹罗网络。函数接受网络的结构和两个训练图像和返回一个预测的概率对类似的(接近1)或不同的(接近0)。

函数Y = forwardSiamese(净、fcParams X1, X2) F1 =前进(净,X1);F1 =乙状结肠(F1);
F2 =前进(净X2);F2 =乙状结肠(F2);
Y = abs (F1, F2);Y = fullyconnect (Y, fcParams.FcWeights, fcParams.FcBias);Y =乙状结肠(Y);结束

getSiameseBatch函数返回一个随机选择的批配对图像。平均而言,这个函数产生一个平衡组相似和不同的配对。

函数(X1, X2, pairLabels] = getSiameseBatch (imd, miniBatchSize) pairLabels = 0 (1, miniBatchSize);imgSize =大小(readimage (imd, 1));X1 = 0 ([imgSize 1 miniBatchSize]);X2 = 0 ([imgSize 1 miniBatchSize]);i = 1: miniBatchSize选择=兰德(1);如果选择< 0.5 [pairIdx1、pairIdx2 pairLabels (i)) = getSimilarPair (imds.Labels);其他的[pairIdx1, pairIdx2 pairLabels (i)) = getDissimilarPair (imds.Labels);结束X1(::,:,我)= imds.readimage (pairIdx1);X2(::,:,我)= imds.readimage (pairIdx2);结束结束

getSimilarPair函数返回一个随机双指数图像在同一类和类似的一对标签1。

函数[pairIdx1 pairIdx2,标签]= getSimilarPair (classLabel)类=独特(classLabel);classChoice =兰迪(元素个数(类));idx =找到(classLabel = =类(classChoice));pairIdxChoice = randperm(元素个数(idx), 2);pairIdx1 = idx (pairIdxChoice (1));pairIdx2 = idx (pairIdxChoice (2));标签= 1;结束

getDissimilarPair函数返回一个随机双指数在不同的课程和不同的图像对标签的0。

函数[pairIdx1 pairIdx2,标签]= getDissimilarPair (classLabel)类=独特(classLabel);classesChoice = randperm(元素个数(类),2);idxs1 =找到(classLabel = =类(classesChoice (1)));idxs2 =找到(classLabel = =类(classesChoice (2)));pairIdx1Choice =兰迪(元素个数(idxs1));pairIdx2Choice =兰迪(元素个数(idxs2));pairIdx1 = idxs1 (pairIdx1Choice);pairIdx2 = idxs2 (pairIdx2Choice);标签= 0;结束

predictSiamese函数使用训练网络对两幅图像的相似度进行预测。

函数Y = predictSiamese(净、fcParams X1, X2) F1 =预测(净,X1);F1 =乙状结肠(F1);
F2 =预测(净X2);F2 =乙状结肠(F2);
Y = abs (F1, F2);Y = fullyconnect (Y, fcParams.FcWeights, fcParams.FcBias);Y =乙状结肠(Y);结束

另请参阅

应用程序

功能

对象

相关的话题