主要内容

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

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

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

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

开放实验

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

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

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

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

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

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

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

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”;downloadFolder = tempdir;文件名= 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), Name =“input1”归一化=“没有”)convolution2dLayer (Name = 64“conv1”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu1”)maxPooling2dLayer(= 2步= 2的名字“maxpool1”)convolution2dLayer(7128年,Name =“conv2”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu2”)maxPooling2dLayer (2“步”2 Name =“maxpool2”)convolution2dLayer (4128,“名字”,“conv3”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu3”)maxPooling2dLayer (2“步”2 Name =“maxpool3”)convolution2dLayer(5256年,Name =“conv4”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu4”)fullyConnectedLayer(4096年,Name =“fc1”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer)];
lgraph = layerGraph(层);dlnet = dlnetwork (lgraph);
fcWeights = dlarray (0.01 * randn (4096);fcBias = dlarray (0.01 * randn (1,1));fcParams =结构(“FcWeights”fcWeights,“FcBias”,fcBias);
output.network = dlnet;输出。重量= 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);dlX1 = dlarray(单(X1)、“SSCB”);dlX2 = dlarray(单(X2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”dlX1 = gpuArray (dlX1);dlX2 = gpuArray (dlX2);结束(gradientsSubnet gradientsParams,亏损)= dlfeval (@modelGradients,dlnet、fcParams dlX1、dlX2 pairLabels);lossValue =双(收集(extractdata(损失)));[dlnet, trailingAvgSubnet trailingAvgSqSubnet] =adamupdate (dlnet gradientsSubnet,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);dlXAcc1 = dlarray(单(XAcc1),“SSCB”);dlXAcc2 = dlarray(单(XAcc2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”dlXAcc1 = gpuArray (dlXAcc1);dlXAcc2 = gpuArray (dlXAcc2);结束海底= predictSiamese (dlnet fcParams、dlXAcc1 dlXAcc2);Y =收集(extractdata(海底));Y =圆(Y);准确性(i) = (Y = = pairLabelsAcc) / accuracyBatchSize总和;结束recordMetrics(监控、迭代ValidationAccuracy =意味着(精度)* 100);班长。状态=“培训”;结束output.network = dlnet;输出。重量= fcParams;recordMetrics(监控、迭代TrainingLoss = lossValue);班长。进步=(迭代/ numIterations) * 100;如果monitor.Stop返回;结束结束

检查培训功能,培训功能,点击编辑。MATLAB®编辑器中打开的训练函数。此外,训练函数的代码出现在附录1最后这个例子。

运行实验

当您运行实验,实验管理列车网络多次训练函数定义的。每个试验使用不同的组合hyperparameter值。默认情况下,实验管理器运行一个审判。如果你有并行计算工具箱,您可以同时运行多个试验。为达到最佳效果,在你运行你的实验,开始与尽可能多的工人gpu并行池。有关更多信息,请参见并行使用实验管理器来训练网络

  • 运行一个审判的一次实验,在实验管理器将来发布,点击运行

  • 同时运行多个试验,点击使用并行然后运行。如果没有当前并行池、实验管理器启动一个集群使用默认配置文件。实验管理器然后执行多个同时试验,根据并行工人的数量。

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

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

评估结果

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

  1. 指出ValidationAccuracy列。

  2. 点击三角形图标。

  3. 选择按照降序排列

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

视觉检查网络正确识别相似和不同的双:

  1. 选择最高的试验精度。

  2. 实验管理器将来发布,点击出口

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

  4. 测试网络在一小批通过调用图像对displayTestSet功能,这是上市附录3最后这个例子。使用导出的训练函数作为输入输出。例如,在MATLAB命令窗口中,输入:

displayTestSet (trainingOutput)

函数显示10个随机选择的对测试图像的预测训练网络,概率得分,和一个标签显示的预测是否正确或不正确的。

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

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

  2. 选择添加注释

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

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

关闭实验

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

附录1:培训功能

这个函数指定了训练数据、网络架构、培训方案和培训过程中使用的实验。

输入

  • 参数个数从实验管理器是一个结构字段hyperparameter表。

  • 监控是一个experiments.Monitor对象,您可以使用它来跟踪培训的进展,在结果表中更新信息字段,记录值的指标使用的培训,和生产培训的阴谋。

输出

  • 输出是一个结构,包含训练网络,最后的重量吗fullyconnect为网络操作,用于培训的执行环境。实验管理器保存此输出,所以你可以出口到MATLAB工作区当培训完成。

函数输出= ImageComparisonExperiment_training1(参数、监控)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”;downloadFolder = tempdir;文件名= 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), Name =“input1”归一化=“没有”)convolution2dLayer (Name = 64“conv1”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu1”)maxPooling2dLayer(= 2步= 2的名字“maxpool1”)convolution2dLayer(7128年,Name =“conv2”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu2”)maxPooling2dLayer (2“步”2 Name =“maxpool2”)convolution2dLayer (4128,“名字”,“conv3”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu3”)maxPooling2dLayer (2“步”2 Name =“maxpool3”)convolution2dLayer(5256年,Name =“conv4”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer) reluLayer (Name =“relu4”)fullyConnectedLayer(4096年,Name =“fc1”,WeightsInitializer = params.WeightsInitializer,BiasInitializer = params.BiasInitializer)];lgraph = layerGraph(层);dlnet = dlnetwork (lgraph);fcWeights = dlarray (0.01 * randn (4096);fcBias = dlarray (0.01 * randn (1,1));fcParams =结构(“FcWeights”fcWeights,“FcBias”,fcBias);output.network = dlnet;输出。重量= fcParams;numIterations = 1000;miniBatchSize = 180;validationFrequency = 100;initialLearnRate = 6 e-5;gradientDecayFactor = 0.9;squaredGradientDecayFactor = 0.99; trailingAvgSubnet = []; trailingAvgSqSubnet = []; trailingAvgParams = []; trailingAvgSqParams = []; monitor.Metrics = [“TrainingLoss”“ValidationAccuracy”];班长。包含=“迭代”;班长。状态=“培训”;迭代= 1:numIterations [X1, X2, pairLabels] = getSiameseBatch (imdsTrain miniBatchSize);dlX1 = dlarray(单(X1)、“SSCB”);dlX2 = dlarray(单(X2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”dlX1 = gpuArray (dlX1);dlX2 = gpuArray (dlX2);结束(gradientsSubnet gradientsParams,亏损)= dlfeval (@modelGradients,dlnet、fcParams dlX1、dlX2 pairLabels);lossValue =双(收集(extractdata(损失)));[dlnet, trailingAvgSubnet trailingAvgSqSubnet] =adamupdate (dlnet gradientsSubnet,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);dlXAcc1 = dlarray(单(XAcc1),“SSCB”);dlXAcc2 = dlarray(单(XAcc2),“SSCB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |输出。executionEnvironment = =“图形”dlXAcc1 = gpuArray (dlXAcc1);dlXAcc2 = gpuArray (dlXAcc2);结束海底= predictSiamese (dlnet fcParams、dlXAcc1 dlXAcc2);Y =收集(extractdata(海底));Y =圆(Y);准确性(i) = (Y = = pairLabelsAcc) / accuracyBatchSize总和;结束recordMetrics(监控、迭代ValidationAccuracy =意味着(精度)* 100);班长。状态=“培训”;结束output.network = dlnet;输出。重量= fcParams;recordMetrics(监控、迭代TrainingLoss = lossValue);班长。进步=(迭代/ numIterations) * 100;如果monitor.Stop返回;结束结束结束

附录2:定制培训辅助函数

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

函数(gradientsSubnet gradientsParams,亏损)= modelGradients (dlnet、fcParams dlX1, dlX2, pairLabels) Y = forwardSiamese (dlnet, fcParams, dlX1 dlX2);损失= binarycrossentropy (Y, pairLabels);[gradientsSubnet, gradientsParams] = dlgradient(损失,dlnet.Learnables fcParams);结束

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

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

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

函数dlX1, Y = forwardSiamese (dlnet fcParams dlX2) F1 =前进(dlnet dlX1);F1 =乙状结肠(F1);
F2 =前进(dlnet dlX2);F2 =乙状结肠(F2);
Y = abs (F1, F2);Y = fullyconnect (Y, fcParams.FcWeights, fcParams.FcBias);Y =乙状结肠(Y);结束

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

函数(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);结束结束

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

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

这个函数返回一个随机双指数在不同的课程和不同的图像对标签的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;结束

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

函数dlX1, Y = predictSiamese (dlnet fcParams dlX2) F1 =预测(dlnet dlX1);F1 =乙状结肠(F1);
F2 =预测(dlnet dlX2);F2 =乙状结肠(F2);
Y = abs (F1, F2);Y = fullyconnect (Y, fcParams.FcWeights, fcParams.FcBias);Y =乙状结肠(Y);结束

附录3:显示对测试图像

这个函数创建一个小批量的图像对帮助你视觉检查网络是否正确识别相似和不同的配对。这个函数使用了辅助函数predictSiamesepredictSiamese中列出附录2

函数displayTestSet (trainingOutput) dlnet = trainingOutput.network;fcParams = trainingOutput.weights;executionEnvironment = trainingOutput.executionEnvironment;downloadFolder = tempdir;dataFolderTest = fullfile (downloadFolder,“images_evaluation”);imdsTest = imageDatastore (dataFolderTest,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTest.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“_”);imdsTest。=分类标签(标签);testBatchSize = 10;[XTest1, XTest2 pairLabelsTest] = getSiameseBatch (imdsTest testBatchSize);dlXTest1 = dlarray(单(XTest1),“SSCB”);dlXTest2 = dlarray(单(XTest2),“SSCB”);如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”dlXTest1 = gpuArray (dlXTest1);dlXTest2 = gpuArray (dlXTest2);结束dlYScore = predictSiamese (dlnet fcParams、dlXTest1 dlXTest2);YScore =收集(extractdata (dlYScore));YPred =圆(YScore);XTest1 = extractdata (dlXTest1);XTest2 = extractdata (dlXTest2);plotRatio = 16/9;testingPlot =图;testingPlot.Position (3) = plotRatio * testingPlot.Position (4);testingPlot。可见=“上”;i = 1:元素个数(pairLabelsTest)如果YPred (i) = = 1 predLabel =“相似”;其他的predLabel =“不同”;结束如果pairLabelsTest (i) = = YPred testStr =(我)“{暗绿色}\ bf \颜色正确\ rm \换行符”;其他的testStr =“{红}\ bf \颜色错误\ rm \换行符”;结束次要情节(2、5、我)imshow ([XTest1 (::,:, i) XTest2(::,:,我)]);标题(testStr +{黑}\颜色预测:“+ predLabel +“\ newlineScore:“+ YScore(我));结束

另请参阅

应用程序

功能

对象

相关的话题