主要内容

火车暹罗网络比较图像

这个例子展示了如何训练暹罗网络手写字符识别类似的图像。

暹罗网络是一种深入学习网络,使用相同的两个或两个以上相同的子网,架构和共享相同的参数和权值。暹罗网络通常用于任务涉及找到两个类似的事物之间的关系。一些常见的应用程序为暹罗网络包括面部识别、签名验证[1],或者解释识别[2]。暹罗网络执行这些任务,因为他们共享权重意味着有更少的参数学习培训期间,他们可以产生好结果相对少量的训练数据。

暹罗网络是特别有用的情况下有大量的类和少量的观测。在这种情况下,没有足够的数据来训练深卷积神经网络将图像划分为这些类。相反,暹罗网络可以确定两幅图像是否在同一个班。

这个例子使用Omniglot数据集[3]训练暹罗网络比较图像的手写字符[4]。Omniglot数据集包含50个字母的字符集,分为20 30用于培训和测试。每个字母都包含一个字符数从14 Ojibwe (Canadia土著Sullabics)曾到55。最后,每个角色都有20个手写的观察。这个例子列车网络识别两个手写的观察是否不同实例相同的字符。

您还可以使用暹罗使用降维网络识别类似的图像。例如,看到的火车降维的暹罗网络

负载和训练数据进行预处理

下载并解压Omniglot训练数据集。

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”)disp (“下载Omniglot训练数据(4.5 MB)……”)websave(文件名,url);解压缩(文件名,downloadFolder);结束disp (“训练数据下载”。)
训练数据下载。

加载图像数据存储使用训练数据imageDatastore函数。手动指定标签从文件中提取标签名称和设置标签财产。

imdsTrain = imageDatastore (dataFolderTrain,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTrain.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“-”);imdsTrain。标签=categorical(labels);

Omniglot训练数据集包括黑色和白色手写字符来自30个字母,用20的观察每个字符。大小的图像是105 - 105 - 1,和每个像素的值之间01

显示一个随机选择的图像。

idx = randperm(元素个数(imdsTrain.Files), 8);i = 1:元素个数(idx)次要情节(4 2 i) imshow (readimage (imdsTrain idx (i)))标题(imdsTrain.Labels (idx (i)),翻译=“没有”);结束

创建对相似和不同的图像

训练网络,数据必须分为对相似或不同的图像。这里,类似的图像不同的手写的实例相同的性格,相同的标签,而不同的图像不同的角色有不同的标签。这个函数getSiameseBatch(定义在金宝app支持功能这个例子)创建的随机双相似或不同的图像,pairImage1pairImage2。函数返回标签pairLabel标识,如果对图像的相似或相异的。类似的双图像pairLabel = 1,而不同的配对pairLabel = 0

作为一个例子,创建一个小代表的五双图像

batchSize = 10;[pairImage1, pairImage2 pairLabel] = getSiameseBatch (imdsTrain batchSize);

显示生成的双图像。

我= 1:batchSize如果pairLabel (i) = = 1 s =“相似”;其他的s =“不同”;结束次要情节(2、5、我)imshow ([pairImage1 (::,:, i) pairImage2(::,:,我)]);标题(年代)结束

在这个示例中,创建一个新的批180配对图像的每个迭代训练循环。这确保了网络训练的大量随机双图像大致相等比例的相似和相异的对。

定义网络体系结构

暹罗网络体系结构见下图。

比较两个图像,每幅图像通过一个共享的两个相同的子网权重。每个子网将105 -通过- 105 - 1图像4096维的特征向量。同一个类的图像也有类似4096 -维表示。每个子网的输出特征向量相结合通过减法和结果是通过fullyconnect操作与单个输出。一个乙状结肠将该值转换为一个概率之间的操作01,表明网络预测的图像是否相似或相异的。网络之间的二进制叉损失预测和真正的标签是用于更新网络在训练。

在这个例子中,定义为两个相同的子网dlnetwork对象。最后一个fullyconnect乙状结肠子网上的操作执行功能操作输出。

创建一系列的子网层接受105 -通过- 105 - 1和输出图像特征向量的大小4096。

convolution2dLayer对象,使用正态分布狭窄的初始化权重和偏见。

maxPooling2dLayer对象,设置步幅2

最后fullyConnectedLayer对象,指定输出大小为4096,并使用正态分布狭窄的初始化重量和偏见。

层= [imageInputLayer(105 105 1,标准化=“没有”)convolution2dLayer (64, WeightsInitializer =“narrow-normal”BiasInitializer =“narrow-normal”)reluLayer maxPooling2dLayer(2步= 2)convolution2dLayer(7128年,WeightsInitializer =“narrow-normal”BiasInitializer =“narrow-normal”)reluLayer maxPooling2dLayer(2步= 2)convolution2dLayer(4128年,WeightsInitializer =“narrow-normal”BiasInitializer =“narrow-normal”)reluLayer maxPooling2dLayer(2步= 2)convolution2dLayer(5256年,WeightsInitializer =“narrow-normal”BiasInitializer =“narrow-normal”)reluLayer fullyConnectedLayer(4096年,WeightsInitializer =“narrow-normal”BiasInitializer =“narrow-normal”));lgraph = layerGraph(层);

训练网络使用一个自定义训练循环和启用自动分化、转换层图dlnetwork对象。

网= dlnetwork (lgraph);

创建最终的重量fullyconnect操作。初始化权重通过抽样随机选择从一个狭窄的正态分布标准差为0.01。

fcWeights = dlarray (0.01 * randn (4096);fcBias = dlarray (0.01 * randn (1,1));fcParams =结构(“FcWeights”fcWeights,“FcBias”,fcBias);

使用网络,创建函数forwardSiamese(定义在金宝app支持功能这个示例的部分),它定义了两个子网和减法,fullyconnect,乙状结肠操作的总和。这个函数forwardSiamese接受网络,包含参数的结构fullyconnect操作,和两个训练图像。的forwardSiamese函数输出预测两幅图像的相似度。

定义模型损失函数

创建函数modelLoss(定义在金宝app支持功能这个示例的部分)。的modelLoss函数暹罗子网的参数结构fullyconnect操作,和mini-batch输入数据X1X2与他们的标签pairLabels。损失函数返回值和梯度的损失对网络的可学的参数。

暹罗的目的是区分两个输入网络X1X2。网络的输出是一个概率之间01,一个值接近0表示图像不同的预测,和一个值接近1这些图片是相似的。损失是由预测分数之间的二进制叉和真正的标签值:

损失 = - - - - - - tlog ( y ) - - - - - - ( 1 - - - - - - t ) 日志 ( 1 - - - - - - y ) ,

在真正的标签 t 可以是0或1, y 预测的标签。

指定培训选项

培训期间指定要使用的选项。10000年火车迭代。

numIterations = 10000;miniBatchSize = 180;

指定的选项为亚当优化:

  • 设置学习速率0.00006

  • 设置渐变衰减系数0.9和衰减系数的平方梯度0.99

learningRate = 6 e-5;gradDecay = 0.9;gradDecaySq = 0.99;

火车在GPU上,如果一个是可用的。使用GPU需要并行计算工具箱™和支持GPU设备。金宝app支持设备的信息,请参阅金宝appGPU的金宝app支持版本(并行计算工具箱)。自动检测你是否有空GPU和GPU上的相关数据,设置的值executionEnvironment“汽车”。如果你没有一个GPU,或不希望使用一个用于培训,设置的值executionEnvironment“cpu”。确保你使用GPU培训,设置的值executionEnvironment“图形”

executionEnvironment =“汽车”;

火车模型

初始化培训进展阴谋。

图C = colororder;lineLossTrain = animatedline(颜色= C (2:));ylim([0正])包含(“迭代”)ylabel (“损失”网格)

亚当的初始化参数解算器。

trailingAvgSubnet = [];trailingAvgSqSubnet = [];trailingAvgParams = [];trailingAvgSqParams = [];

火车模型使用自定义训练循环。循环训练数据和更新网络参数在每个迭代。

每一次迭代:

  • 提取一批图像对和标签使用getSiameseBatch函数中定义的部分创建批图像对

  • 将数据转换为dlarray对象指定尺寸标签“SSCB”(空间、空间、通道、批处理)的图像数据“CB”(通道、批处理)的标签。

  • GPU培训,将数据转换为gpuArray对象。

  • 评估损失和梯度模型使用dlfevalmodelLoss函数。

  • 更新网络参数使用adamupdate函数。

开始=抽搐;%在mini-batches循环。迭代= 1:numIterations%提取mini-batch图像对和对标签(X1, X2, pairLabels] = getSiameseBatch (imdsTrain miniBatchSize);% dlarray mini-batch的数据转换。指定尺寸的标签%”SSCB”(空间、空间、通道、批)图像数据X1 = dlarray (X1,“SSCB”);X2 = dlarray (X2,“SSCB”);%如果训练在GPU,然后将数据转换成gpuArray。如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”X1 = gpuArray (X1);X2 = gpuArray (X2);结束%评估模型和梯度使用dlfeval modelLoss损失%末尾列出函数的例子。[损失,gradientsSubnet, gradientsParams] = dlfeval (fcParams @modelLoss,净,X1, X2, pairLabels);%更新暹罗子网参数。[净,trailingAvgSubnet trailingAvgSqSubnet] = adamupdate (gradientsSubnet净,trailingAvgSubnet trailingAvgSqSubnet,迭代,learningRate、gradDecay gradDecaySq);%更新fullyconnect参数。[fcParams, trailingAvgParams trailingAvgSqParams] = adamupdate (fcParams gradientsParams,trailingAvgParams trailingAvgSqParams,迭代,learningRate、gradDecay gradDecaySq);%更新培训损失情节进展。D =持续时间(0,0,toc(开始),格式=“hh: mm: ss”);lossValue =双(损失);addpoints (lineLossTrain迭代,lossValue);标题(”经过:“+ drawnow字符串(D))结束

评估网络的准确性

下载并解压Omniglot测试数据集。

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”)disp (“下载Omniglot测试数据(3.2 MB)……”)websave(文件名,url);解压缩(文件名,downloadFolder);结束disp (“测试数据下载”。)
测试数据下载。

负载测试数据作为图像数据存储使用imageDatastore函数。手动指定标签从文件中提取标签名称和设置标签财产。

imdsTest = imageDatastore (dataFolderTest,IncludeSubfolders = true,LabelSource =“没有”);文件= imdsTest.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),“_”);imdsTest。标签=categorical(labels);

测试数据集包含20个字母不同,网络训练。总共有659个不同的类的测试数据集。

numClasses =元素个数(独特(imdsTest.Labels))
numClasses = 659

计算网络的准确性,创建一组五个随机mini-batches测试对。使用predictSiamese函数中定义金宝app支持功能这个例子)来评估网络的预测和计算平均mini-batches准确性。

精度= 0 (1、5);accuracyBatchSize = 150;i = 1:5%提取mini-batch图像对和对标签(X1, X2, pairLabelsAcc] = getSiameseBatch (imdsTest accuracyBatchSize);% dlarray mini-batch的数据转换。指定尺寸的标签%”SSCB”(空间、空间、通道、批)图像数据。X1 = dlarray (X1,“SSCB”);X2 = dlarray (X2,“SSCB”);%如果使用GPU,然后将数据转换成gpuArray。如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”X1 = gpuArray (X1);X2 = gpuArray (X2);结束%评估预测使用训练网络Y = predictSiamese(净、fcParams X1, X2);%预测转换为二进制0或1Y =收集(extractdata (Y));Y =圆(Y);%计算minibatch的平均精度准确性(i) = (Y = = pairLabelsAcc) / accuracyBatchSize总和;结束

对所有minibatches计算精度

averageAccuracy =意味着(准确性)* 100
averageAccuracy = 89.0667

显示一个测试集的图像与预测

视觉检查网络和不同对正确识别相似,创建一个小批测试图像对。使用predictSiamese函数的预测为每个测试。显示的图像的预测概率得分,和一个标签显示预测是否正确或不正确的。

testBatchSize = 10;[XTest1, XTest2 pairLabelsTest] = getSiameseBatch (imdsTest testBatchSize);

测试一批数据转换dlarray。指定尺寸的标签“SSCB”(空间、空间、通道、批)图像数据。

XTest1 = dlarray (XTest1,“SSCB”);XTest2 = dlarray (XTest2,“SSCB”);

如果是使用GPU,然后将数据转换为gpuArray

如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”XTest1 = gpuArray (XTest1);XTest2 = gpuArray (XTest2);结束

计算预测概率。

YScore = predictSiamese(网,fcParams, XTest1 XTest2);YScore =收集(extractdata (YScore));

将预测转换为二进制0或1。

YPred =圆(YScore);

提取数据绘图。

XTest1 = extractdata (XTest1);XTest2 = extractdata (XTest2);

情节与预测图像标签和预测分数。

f =图;tiledlayout (2、5);f.Position (3) = 2 * f.Position (3);predLabels =分类(YPred [0, 1], [“不同”“相似”]);targetLabels =分类(pairLabelsTest [0, 1], [“不同”,“相似”]);i = 1:元素个数(pairLabelsTest) nexttile imshow ([XTest1 (::,:, i) XTest2(::,:,我)]);标题(目标:“+字符串(targetLabels (i)) +换行符+预测:“+字符串(predLabels (i)) +换行符+“分数:+ YScore (i))结束

网络能够比较测试图像,以确定他们的相似之处,即使这些图像在训练数据集。

金宝app支持功能

模型训练和预测功能

这个函数forwardSiamese在网络训练使用。函数定义子网和如何fullyconnect乙状结肠操作相结合,形成完整的暹罗网络。forwardSiamese接受网络结构和两个训练图像和输出预测两幅图像的相似度。在这个例子中,函数forwardSiamese介绍了部分定义网络体系结构

函数Y = forwardSiamese(净、fcParams X1, X2)% forwardSiamese接受网络和对训练图像,和%返回一个预测的概率对类似(接近% 1)或不同的(接近0)。使用forwardSiamese在训练。通过两个子网%通过第一形象日元=前进(净,X1);日元=乙状结肠(Y1);通过两个子网%通过第二个图像Y2 =前进(净X2);Y2 =乙状结肠(Y2);%减去特征向量Y = abs (Y1, Y2);%结果通过fullyconnect操作Y = fullyconnect (Y, fcParams.FcWeights, fcParams.FcBias);%转换为概率在0和1之间。Y =乙状结肠(Y);结束

这个函数predictSiamese使用训练网络对两幅图像的相似度进行预测。类似于函数的函数forwardSiamese,前面定义。然而,predictSiamese使用预测的网络,而不是函数向前函数,因为一些深度学习在训练和预测层表现出不同的行为。在这个例子中,函数predictSiamese介绍了部分评估网络的准确性

函数Y = predictSiamese(净、fcParams X1, X2)% predictSiamese接受网络和两个图像,并返回一个%的概率预测的一对(接近1)或类似%不同(接近0)。使用predictSiamese在预测。通过两个子网%通过第一形象。日元=预测(净,X1);日元=乙状结肠(Y1);通过两个子网%通过第二个图像。Y2 =预测(净X2);Y2 =乙状结肠(Y2);%减去特征向量。Y = abs (Y1, Y2);%结果通过fullyconnect操作。Y = fullyconnect (Y, fcParams.FcWeights, fcParams.FcBias);%转换为概率在0和1之间。Y =乙状结肠(Y);结束

损失函数模型

这个函数modelLoss的暹罗dlnetwork对象,一双mini-batch输入数据X1X2,标签指示是否相似或相异的。损失函数返回二进制叉之间的预测和地面真理和梯度的损失对网络中可学的参数。在这个例子中,函数modelLoss介绍了部分定义模型损失函数

函数[损失,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(精密))=每股收益(精度);%转换1-eps 1-eps和1之间的值。Y (Y > 1 - eps(精密))= 1 - eps(精度);%计算每一对二叉叉的损失损失= -pairLabels。*日志(Y) - (1 - pairLabels)。*日志(1 - Y);%所有对minibatch和规范化。损失=(亏损)/元素个数之和(pairLabels);结束

创建批图像对

下面的函数创建随机双相似或不同的图像,基于他们的标签。在这个例子中,函数getSiameseBatch介绍了部分创建对相似和不同的图像。

暹罗批处理函数

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

得到相似的双功能

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

函数[pairIdx1, pairIdx2 pairLabel] = getSimilarPair (classLabel)%找到所有独特的类。类=独特(classLabel);%随机选择一个类用来得到一个相似的一对。classChoice =兰迪(元素个数(类));%找到的所有观测的指标选择类。idx =找到(classLabel = =类(classChoice));%从所选的类随机选择两个不同的图像。pairIdxChoice = randperm(元素个数(idx), 2);pairIdx1 = idx (pairIdxChoice (1));pairIdx2 = idx (pairIdxChoice (2));pairLabel = 1;结束

得到Disimilar对函数

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

引用

[1]布罗姆利,J。,I. Guyon, Y. LeCun, E. Säckinger, and R. Shah. "签名验证使用时间延迟神经网络“暹罗”。“第六届国际研讨会论文集在神经信息处理系统(少量的1993),1994年,pp737 - 744。可以在签名验证使用时间延迟神经网络“暹罗”在少量的程序的网站。

[2]Wenpeg Y。,和H Schütze. "卷积神经网络释义识别。“2015年研讨会论文集北美ACL的章,2015年,pp901 - 911。可以在卷积神经网络释义识别在ACL选集网站上

[3]湖,b . M。,Salakhutdinov, R., and Tenenbaum, J. B. "人类通过概率计划概念学习归纳。《科学》,350 (6266),(2015)pp1332 - 1338。

[4]科赫,G。泽梅尔,R。,和Salakhutdinov, R. (2015). "暹罗一次性图像识别的神经网络”。第32届国际研讨会论文集在机器学习,37 (2015)。可以在暹罗一次性图像识别的神经网络ICML的15个网站。

另请参阅

||||

相关的话题