主要内容

训练暹罗网络以比较图像

此示例显示如何培训暹罗网络以识别手写字符的类似图像。

暹罗网络是一种深入学习网络,它使用具有相同架构的两个或多个相同的子网,并共享相同的参数和权重。暹罗网络通常用于涉及在两个可比较的事物之间找到关系的任务。暹罗网络的一些常见应用包括面部识别,签名验证[1],或解释识别[2]。暹罗网络在这些任务中表现良好,因为它们的共享权重意味着在培训期间可以学习的参数较少,并且它们可以通过相对少量的培训数据产生良好的结果。

暹罗网络特别有用的情况下,有大量的类与少量的观察每个。在这种情况下,没有足够的数据来训练深度卷积神经网络来将图像分类。相反,Siamese网络可以确定两个图像是否属于同一类。

此示例使用Omniglot DataSet [3]培训暹罗网络以比较手写字符的图像[4]。Omniglot DataSet包含50个字母表的字符集,分为30用于训练和20用于测试。每个字母表包含14个用于Ojibwe(CANADIA土着SULLABS)到55的数量的字符,用于TIFINAGH。最后,每个角色都有20个手写观察。该示例列举了一个网络来识别两个手写观察是否是相同字符的不同实例。

您还可以使用暹蒙网络来使用维数减少识别类似图像。例如,看到训练一个暹罗网络降维

负载和预处理培训数据

下载并提取omn​​iglot.训练数据集。

URL =.“https://github.com/brendenlake/omniglot/raw/master/python/images_background.zip”;downloadfolder = tempdir;filename = fullfile(downloadFolder,“images_background.zip”);datafoldertrain = fullfile(DownloadFolder,'images_background');如果〜存在(datafoldertrain,“dir”)disp(“下载omniglot培训数据(4.5 MB)......”)Websave(Filename,URL);解压缩(文件名,downloadfolder);结束DISP(“训练数据下载”。
培训数据下载。

使用使用的图像数据存储将培训数据加载imageageAtastore.函数。手动指定标签,方法是从文件名中提取标签并设置标签财产。

imdstrain = imagedataStore(DataFoldertrain,......'insertumbfolders',真实,......'labelsource''无');文件= imdsTrain.Files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),'_');imdstrain.labels =分类(标签);

Omniglot Training DataSet由30个字母表组成的黑白手写字符,每个角色的观察20个观察。图像大小为105×105-1,并且每个像素的值在于01

显示图像的随机选择。

idxs = randperm(numel(imdstrain.files),8);对于i = 1:numel(IDXS)子图(4,2,i)Imshow(ReadImage(IMDStrain,IDXS(I))标题(IMDStrain.Labels(IDXS(I)),“翻译”“没有”);结束

创建成对类似和不同的图像

为了训练网络,数据必须分为类似或不同的图像成对。这里,类似的图像是具有相同标签的相同字符的不同的手写实例,而不同字符的不同图像具有不同的标签。功能getsiameSebatch.(定义在金宝app支持功能本例的一部分)创建随机的类似或不同图像,Bireimage1.Bireimage2..该函数还返回标签Biaplabel.,它可以识别这对图像是相似的还是不同的。相似的图像有Biaplabel = 1,而异不同的对Biaplabel = 0.

例如,创建一个小型代表性的五对图像集

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

显示生成的图像对。

对于i = 1:批量化如果pairLabel(i) == 1 s =“相似”别的S =“不同”结束子图(2,5,i)imshow([BileImage1(:,:,:,i)绑架2(:,:,:,i)]);标题结束

在这个例子中,每个训练循环的迭代都会创建一个由180对图像组成的新批。这保证了网络是在大量的随机图像对上训练的,相似和不相似的图像对的比例大致相等。

定义网络架构

暹罗网络架构如下图所示。

为了比较两个图像,通过共享权重的两个相同的子网之一传递每个图像。子网供应将每个105-105×1图像转换为4096维特征向量。同一类的图像具有类似的4096维表示。每个子网的输出特征向量通过减法组合,结果通过A全协商用单个输出操作。A.sigmoid.操作将此值转换为概率01,表示网络对图像是否类似或不同的预测。网络预测和真品之间的二进制交叉熵丢失用于在训练期间更新网络。

在此示例中,两个相同的子网被定义为一个dlnetwork.对象。决赛全协商sigmoid.操作在子网输出上作为功能操作执行。

将子网创建为一系列接受105-×105-1图像的层,并输出大小4096的特征向量。

对于Convolution2Dlayer.对象,使用窄正态分布初始化权重和偏差。

对于maxpooling2dlayer.对象,将步幅设置为2

对于决赛fullyConnectedLayer对象,指定输出大小为4096,并使用窄正态分布初始化权重和偏差。

图层= [imageInputlayer([105 105 1],“名字”'输入1''正常化''无')卷积2dlayer(10,64,“名字”'conv1''掌控itializer''窄正常''偏见的人''窄正常') reluLayer (“名字”'relu1')maxpooling2dlayer(2,“步”2,“名字”'maxpool1')卷积2dlayer(7,128,“名字”'conv2''掌控itializer''窄正常''偏见的人''窄正常') reluLayer (“名字”'relu2')maxpooling2dlayer(2,“步”2,“名字”'maxpool2') convolution2dLayer (4128,“名字”'conv3''掌控itializer''窄正常''偏见的人''窄正常') reluLayer (“名字”'relu3')maxpooling2dlayer(2,“步”2,“名字”'maxpool3')卷积2dlayer(5,256,“名字”'conv4''掌控itializer''窄正常''偏见的人''窄正常') reluLayer (“名字”'relu4')全康连接层(4096,“名字”'fc1''掌控itializer''窄正常''偏见的人''窄正常')];Lgraph = LayerGraph(层);

要使用自定义训练循环训练网络并启用自动分化,将图层图转换为adlnetwork.对象。

dlnet = dlnetwork (lgraph);

为决赛创建权重全协商操作。通过使用标准偏差为0.01的窄正态分布采样随机选择来初始化权重。

Fcweights = Dlarray(0.01 * Randn(1,4096));FCBIAS = DLARRAY(0.01 * RANDN(1,1));fcparams = struct(......“fcweights”,fcwweights,......“fcbias”,fcbias);

要使用网络,请创建功能forwardSiamese(定义在金宝app支持功能本示例的部分)定义了两个子网和减法方式的方式定义如何fullyconnect,sigmoid.操作组合。功能forwardSiamese接受网络,结构中包含的参数全协商操作和两个训练图像。当forwardSiamese功能输出关于两个图像的相似性的预测。

定义模型渐变功能

创建功能MapicalGRADENTERS.(定义在金宝app支持功能这个例子的一部分)。当MapicalGRADENTERS.函数需要暹罗子网DLNET.,参数结构全协商操作,以及迷你输入数据X1X2他们的标签pairLabels.该函数返回损耗值和损耗相对于网络的可学习参数的梯度。

暹罗网络的目的是区分两种输入X1X2.网络的输出是概率01,其中一个值更接近0表示预测的图像是不同的,并且值更接近1图像类似。丢失由预测分数与真标值之间的二进制交叉熵给出:

损失 - Tlog. y - 1 - t 日志 1 - y

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

指定培训选项

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

numiterations = 10000;minibatchsize = 180;

指定adam优化选项:

  • 设置学习率0.00006

  • 初始化尾随平均梯度和尾随平均梯度方形衰减率[]对于这两个DLNET.fcparams.

  • 将渐变衰减系数设置为0.9和平方梯度衰减因子到0.99

学会= 6e-5;trailingavgsubnet = [];trailingavgsqsubnet = [];trailingavgparams = [];trailingavgsqparams = [];graddecay = 0.9;Graddecaysq = 0.99;

在GPU上的火车,如果有的话。使用GPU需要并行计算工具箱™和支持的GPU设备。金宝app有关支持设备的信息,请参阅金宝appGPU通金宝app过发布支持(并行计算工具箱).自动检测是否有可用GPU并将相关数据放在GPU上,设置值execultenvironment.到目前为止“自动”.如果您没有GPU,或者不想使用一个用于培训,请设置值execultenvironment.到目前为止“cpu”.为确保您使用GPU进行培训,请设置值execultenvironment.到目前为止“GPU”

executionEnvironment =“自动”

要监控培训进度,您可以在每次迭代后绘制培训损失。创建变量绘图那个包含“培训 - 进展”.如果您不想绘制培训进度,请将此值设置为“没有”

情节=“培训 - 进展”

初始化训练损失进度图的绘图参数。

Plotratio = 16/9;如果plots ==“培训 - 进展”trafterplot = figure;trafterplot.position(3)= Plotratio *培训夹.Position(4);培训窗。可见='开';TrainingPlotaxes = GCA;LineloSstrain =动画线(培训架);xlabel(培训帆布,“迭代”)ylabel(培训架,“损失”)标题(培训架,“训练期间的损失”结束

火车模型

使用自定义训练循环训练模型。在训练数据上循环并在每次迭代时更新网络参数。

每一次迭代:

  • 用批量提取一批图像对和标签getsiameSebatch.在该部分中定义的功能创建批量图像对

  • 将数据转换为dlarray.底层类型的对象单身并指定维标签'SSCB'(空间,空间,通道,批量)用于图像数据和'cb'(通道,批次)的标签。

  • 对于GPU培训,将数据转换为GPUArray.对象。

  • 使用模型梯度评估使用dlfeval.MapicalGRADENTERS.函数。

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

%循环在迷你批次。对于迭代= 1:NUMITRATIONS%提取物小批图像对和对标签(X1, X2, pairLabels] = getSiameseBatch (imdsTrain miniBatchSize);%将mini批次数据转换为dlarray。指定维标签%'SSCB'(空间,空间,通道,批量)用于图像数据dlx1 = dlarray(单(x1),'SSCB');dlx2 = dlarray(单(x2),'SSCB');如果在GPU上培训,则%将数据转换为GPUArray。如果(execultenvironment ==.“自动”&& canusegpu)||executionenvironment ==.“GPU”dlX1 = gpuArray (dlX1);dlX2 = gpuArray (dlX2);结束%评估模型梯度和生成器状态使用%dlfeval和easturedients函数在结束时列出%例子。[梯度,梯度,梯度日本,损失] = DLFeval(@ MapeStrients,Dlnet,FcParams,DLX1,DLX2,Biabels);loadValue = double(收集(提取物));%更新暹罗子网参数。[Dlnet,trailingavgsubnet,trailingavgsqsubnet] =......Adamupdate(Dlnet,梯度,......TrailigeAvgsubnet,Trailighavgsqsubnet,迭代,学习,Graddecay,Graddecaysq);%更新全连接参数。[FcParams,trailighavgparams,trailingavgsqparams] =......Adamupdate(FCParams,GradientParams,......TrailighavgParams,Trailingavgsqparams,迭代,学习,Graddecay,Graddecaysq);%更新培训损失进度图。如果plots ==“培训 - 进展”Addpoints(LineLoStrain,迭代,丢失值);结束粗暴;结束

评估网络的准确性

下载并提取omn​​iglot.测试数据集。

URL =.“https://github.com/brendenlake/omniglot/raw/master/python/images_evaluation.zip”;downloadfolder = tempdir;filename = fullfile(downloadFolder,“images_evaluation.zip”);datafoldertest = fullfile(DownloadFolder,'images_evaluation');如果〜存在(DataFoldert,'dir')disp('下载omniglot测试数据(3.2 MB)......')Websave(Filename,URL);解压缩(文件名,downloadfolder);结束DISP(“测试数据下载。”
测试数据下载。

使用使用的图像数据存储将测试数据加载imageageAtastore.函数。手动指定标签,方法是从文件名中提取标签并设置标签财产。

imdstest = imageageataStore(DataFoldertest,......'insertumbfolders',真实,......'labelsource''无');files = imdstest.files;部分=分裂(文件、filesep);标签=加入(部分(:,(end-2): (end-1)),'_');imdstest.labels =分类(标签);

测试数据集包含20个字母,与网络培训的其他字母不同。总计,测试数据集中有659种不同的类。

numclasses = numel(唯一(imdstest.labels))
numclasses = 659.

要计算网络的准确性,请创建一组五个随机迷你批次的测试对。用来预测isiamese.函数(在金宝app支持功能来评估网络预测并计算迷你批次的平均准确率。

精度=零(1,5);精度释放= 150;对于我= 1:5%提取物小批图像对和对标签[xacc1,xacc2,biapelabelsacc] = getsiamesebatch(Indstest,Cleascactbatchsize);%将mini批次数据转换为dlarray。指定维标签图像数据的%'SSCB'(空间,空间,通道,批次)。dlxacc1 = dlarray(单个(xacc1),'SSCB');dlxacc2 = dlarray(单个(xacc2),'SSCB');%如果使用GPU,则将数据转换为GPUARRAY。如果(execultenvironment ==.“自动”&& canusegpu)||executionenvironment ==.“GPU”dlxacc1 = gpuarray(dlxacc1);dlxacc2 = gpuarray(dlxacc2);结束使用训练有素的网络评估预测海底= predictSiamese (dlnet fcParams、dlXAcc1 dlXAcc2);%将预测转换为二进制0或1Y =聚集(提取物(DILLY));y =圆形(y);%计算小靶的平均精度精度(i) = sum(Y == pairLabelsAcc)/accuracyBatchSize;结束所有小匹匹匹匹配项都会计算精度AverageAccuracy =均值(准确性)* 100
Averageaccuracy = 88.6667

显示带有预测的图像测试集

在视觉上检查网络是否正确识别类似和不同的对,创建一小批图像对进行测试。使用预测isiamese函数来获取每个测试对的预测。使用预测,概率得分和标签显示一对图像,指示预测是否正确或不正确。

testbatchsize = 10;[xtest1,xtest2,biabelstest] = getsiamesebatch(Indstest,testbatchsize);%将数据转换为dlarray。指定维标签图像数据和“CB”%'SSCB'(空间,空间,通道,批处理)标签%(通道,批量)dlXTest1 = dlarray(单(XTest1),'SSCB');dlxtest2 = dlarray(单个(xtest2),'SSCB');%如果使用GPU,则将数据转换为GPUArray如果(execultenvironment ==.“自动”&& canusegpu)||executionenvironment ==.“GPU”dlxtest1 = gpuarray(dlxtest1);dlxtest2 = gpuarray(dlxtest2);结束计算预测的概率dlyscore = predictsiamese(dlnet,f​​cparams,dlxtest1,dlxtest2);yscore =聚集(提取数据(Dlyscore));%将预测转换为二进制0或1ypred = round(yscore);%提取数据到绘图xtest1 =提取数据(dlxtest1);xtest2 =提取数据(dlxtest2);%绘制具有预测标签和预测分数的图像testingplot =图;testingplot.position(3)= plotratio * testingplot.position(4);testingplot.visible ='开'对于i = 1:numel(Biabelabelstest)如果Ypred(i)== 1 predlabel =“相似”别的predlabel =“不同”结束如果Biapelstest(i)== Ypred(i)teststr =“\ bf \ color {darkgreen}正确\ rm \ newline”别的testStr =“\ bf \ color {红色}不正确\ rm \ newline”结束子图(2,5,i)imshow([xtest1(:,:,:,i)xtest2(::,:,:,i)]);标题(teststr +{黑}\颜色预测:“+ predlabel +“\ newlinescore:”+ YScore(我));结束

该网络能够比较测试图像,以确定它们的相似性,即使这些图像都没有在训练数据集。

金宝app支持功能

用于训练和预测的模型函数

功能forwardSiamese用于网络训练。函数定义了子网和全协商sigmoid.操作组合形成完整的暹罗网络。转发亚胺可以接受网络结构和两个训练图像,并输出关于两个图像的相似性的预测。在本例中,函数forwardSiamese介绍在该部分定义网络架构

功能Y = ForwardSiamese(DLNET,FCPARAMS,DLX1,DLX2)%ForwardSiamese接受网络和一对培训图像,并返回一个对该对的概率的百分比类似(更接近1)或%不同(更接近0)。在培训期间使用前亚胺。%通过双子网传递第一张图像F1 =前进(DLNET,DLX1);f1 = sigmoid(f1);将第二个映像通过孪生子网F2 =前进(dlnet dlX2);F2 =乙状结肠(F2);%减去特征向量Y = abs(F1 - F2);%通过全协调操作传递结果y =全协调(y,fcparams.fcweights,fcparams.fcbias);%转换为0和1之间的概率。y = sigmoid(y);结束

功能预测isiamese.使用培训的网络对两个图像的相似性进行预测。该函数类似于函数forwardSiamese,先前定义。但是,预测isiamese.用来预测使用网络而不是函数前进功能,因为一些深入的学习层在训练和预测期间表现不同。在本例中,函数预测isiamese.介绍在该部分评估网络的准确性

功能Y =预测isiamese(Dlnet,f​​cparams,dlx1,dlx2)%predictsiamese接受网络和一对图像,并返回a对对相似的概率的百分比预测(更接近1)%或不同(接近0)。在预测时使用predictSiamese。%通过双子网传递第一张图像F1 =预测(DLNET,DLX1);f1 = sigmoid(f1);将第二个映像通过孪生子网F2 =预测(DLNET,DLX2);F2 =乙状结肠(F2);%减去特征向量Y = abs(F1 - F2);%通过全互连操作结果y =全协调(y,fcparams.fcweights,fcparams.fcbias);%转换为0和1之间的概率。y = sigmoid(y);结束

模型梯度函数

功能MapicalGRADENTERS.的暹罗dlnetwork.对象,一对迷你批量输入数据X1X2,以及表示它们是相似还是不同的标签。该函数返回关于网络中可学习参数的损失梯度和预测与地面真实之间的二元交叉熵损失。在本例中,函数MapicalGRADENTERS.介绍在该部分定义模型渐变功能

功能[梯度,梯度,梯度日本,损失] = MaposGRadients(DLNet,FCParams,DLX1,DLX2,Biabels)%the measticroperents函数计算的二进制交叉熵损耗%配对图像并返回丢失和损耗的渐变%网络可学习参数%通过网络传递图像对Y =转发亚胺(DLNET,FCPARAMS,DLX1,DLX2);%计算二进制交叉熵损失损失= BinaryCrossentropy(Y,Biaplabels);计算损失相对于网络可学习的梯度%的参数[GradueSubnet,GradientSparams] = Dlgradient(丢失,DLNET.LEARNABLE,FCPARAM);结束功能损失= binarycrossentropy (Y, pairLabels)%binarycrossentropy接受网络的预测y,真实% label和pairLabels,并返回二进制交叉熵损失值。%获取预测的精度,以防止由于浮动导致的错误%点精度Precision =底层(Y);%转换比浮点精度少于eps的值。Y(Y %转换1-eps和1到1 eps之间的值。Y(Y> 1  -  EPS(精确))= 1  -  EPS(精确);%计算每对的二进制交叉熵损耗丢失= -Pairlabels。* log(y) - (1  -  Biabels)。* log(1  -  Y);对minibatch和normalize中的所有对求和。损失=(亏损)/元素个数之和(pairLabels);结束

创建批量图像对

以下函数根据其标签创建类似或不相似的随机图像。在本例中,函数getsiameSebatch.介绍在该部分创建类似和不同图像的对。

功能[x1,x2,biaplabels] = getsiameSebatch(IMDS,Minibatchsize)%getsiamesebatch返回一个随机选择的批处理或配对图像。上%平均值,这种功能产生了平衡的类似和不相似的一组%对。Biaplabels = Zeros(1,小匹匹匹匹配);imgsize =尺寸(ReadImage(IMDS,1));x1 =零([Imgsize 1 minibibatchsize]);x2 =零([Imgsize 1 minibitchsize]);对于i = 1:小匹匹配选择=兰特(1);如果选择<0.5 [Biredx1,Biredx2,Biaplabels(i)] = GetSimilarPair(IMDS.Labels);别的[Biredx1,Biridx2,Biaplabels(i)] = GetDissimilarPair(IMDS.Labels);结束X1(:::,:,i)= IMDS.ReadImage(BiredX1);x2(::,:,i)= imds.readimage(Biredx2);结束结束功能[pairIdx1, pairIdx2 pairLabel] = getSimilarPair (classLabel)%GetImilarSiaMesepair返回一个随机的图像索引%在同一类中和类似的对标签= 1。找到所有唯一的类。classes =唯一(classlabel);%选择一个随机选择的类,这将用于获得类似的对。classchoice = randi(numel(类));%从所选类中找到所有观察的指标。idxs = find(classlabel == classes(classchoice));%从所选的类中随机选择两张不同的图片。BiredxChoice = Randperm(Numel(IDXS),2);BiredX1 = IDXS(BiredXchoice(1));Biredx2 = IDXS(BiredXchoice(2));Biaplabel = 1;结束功能[Biredx1,BiridX2,Label] = GetDissimilarPair(ClassLabel)%getdissimilarsiamesepair返回一个随机的图像索引%在不同类别和不同的对标签= 0。找到所有唯一的类。classes =唯一(classlabel);%随机选择两个不同的类,这将用于获得一个不同的对。Classeschoice = Randperm(Numel(类),2);%从第一和第二类找到所有观察的指数。idxs1 = find(classlabel == classes(classeschoice(1)));idxs2 = find(classlabel == classes(classeschoice(2)));%随机选择每个类的一个图像。Biredx1Choice = RANDI(NUMER(IDXS1));Biredx2Choice = RANDI(NUMER(IDXS2));BiredX1 = IDXS1(BiredX1Choice);BiredX2 = IDXS2(BiredX2Choice);标签= 0;结束

参考资料

[1] Bromley, J., I. Guyon, Y. LeCunn, E. Säckinger,和R. Shah。”使用“暹罗”时滞神经网络的签名验证。“在第六次国际神经信息处理系统会议(NIPS 1993),1994年,PP737-744中的诉讼程序中。可用使用“暹罗”时间延迟神经网络签名验证在NIPS诉讼网站上。

[2] Wenpeg,Y.和HSchütze。“卷曲神经网络,用于解释鉴定。“在2015年ACL的北美章会议上的讨论会上,2015年,PP901-911。可提供卷积神经网络,用于解释在ACL选集网站上

[3] Lake, b.m., Salakhutdinov, R.和Tenenbaum, J. B.”通过概率计划诱导学习人类级概念。“科学,350(6266),(2015)PP1332-1338。

[4] Koch,G.,Zemel,R.和Salakhutdinov,R。(2015)。“暹罗一拍图像识别的神经网络“。在第32届国际机械学习会议上的诉讼程序中,37(2015)。可用暹罗一拍图像识别的神经网络在ICML'15网站上。

另请参阅

||||

相关主题