探索同一学习任务的不同框架如何影响成绩

2020-07-13 14:17:53

监督学习是处理函数逼近的机器学习分支:利用未知目标函数生成的多个输入输出对,构造一个逼近目标函数的不同函数。例如,目标函数可能是我个人的电影喜好,我们可能对获得一个模型感兴趣,该模型可以预测(大约)我会有多喜欢看某部新电影。有了这样的模型,我们就可以创建一个电影推荐应用程序。

有些函数可能比其他函数更容易逼近(给出了逼近难度的定义,但我现在不会进入那个兔子洞),而有些任务可以被框定为多个函数。这就提出了一个问题-不同的框架是否会导致不同的模型性能?为了找出答案,我试着玩了两个框架的玩具问题。

我使用的是Olivetti Faces数据集,其中包含40名受试者面部的64x64灰度图像(每个受试者10张图像)。以下是一些面孔:

这项任务是典型的人脸识别任务(最近,由于在执法等环境中的使用有问题,这项任务颇具争议)。为了让事情更有趣,我决定只使用每个受试者的两张图片进行训练,其余的作为测试集。所以我们的目标是训练一个模型,它在给定一幅图像的情况下,输出模型认为这张脸属于的主题。

我只想把重点放在与问题框架相关的培训方面,并把它当作一个普遍的问题来对待。为此,我排除了许多对真正的人脸识别应用程序非常重要的细节:

为每个预测分配一个置信度分数,并确定一个置信度阈值,低于该阈值则不报告任何结果。

简而言之,我想看看更改目标函数会有什么不同。由于功能不同,模型也可能略有不同,但它们是基于相同的(基础)数据进行训练的。

为了衡量模型性能,我使用了准确度度量-正确分类的百分比。对于每个帧,我运行了大约100个训练/测试拆分(训练集中有两个图像,测试集中有8个图像)。

作为基准,我使用具有L2范数的(单个)最近邻分类器。即,当对新的人脸进行分类时,对于训练集中的每个人脸,我们计算每两个像素(在相似位置)之间的平方差之和,并将最接近的人脸作为答案。

凭直觉,很难说这种模式会有多好。一方面,同一个人的图像之间显然应该有许多相似之处(包括我们想要排除的因素,如灯光和服装);另一方面,我们在面部感知到的许多相似之处不会反映在像素级的比较中。在这种情况下,模型的性能(以准确率衡量-正确分类的百分比)约为70.5%,考虑到随机模型的平均准确率约为2.5%,我认为这是相当令人印象深刻的。

第一个框架是明确的:给定一张图像,我们想知道它是谁的脸,所以这就是我们要问模型的问题。该函数将图像映射到主体标识符。

Model=Sequential([Dense(128,Input_Shape=(X_Train。Shape[1],),Activate=';relu&39;),BatchNormalization(),Dense(64,Activate=';Relu&39;),BatchNormalization(),Dense(32),Dense(Y_Train)。Shape[1],Activate=';Softmax';)]))型号。编译(CATEGRICAL_CROSENTROPY';,OPTIMIZER=#39;ADAM&39;)模型。拟合(X_系列,Y_系列,历元=1200)。

我玩了几个变种,这似乎是最好的关于层数,他们的大小和激活功能。它的测试准确率平均约为70.9%-这是一个微小的进步。我认为部分挑战在于,分类人脸需要相对复杂的特征,但我们拥有的训练数据非常少(特别是考虑到每个类别的正例数量),所以如果网络太小,模型要么无法找到模式,要么如果网络太大,模型就无法找到模式。

让我们尝试一种不那么直接的框架。我们知道,如果两个图像属于同一个人,它们应该是相对相似的,反之亦然。因此,我们可以训练模型来比较人脸,而不是训练模型来识别人脸。在本例中,我们只有两个类,而不是40个类(每个科目一个):“Same Person”或“Not Same Person”。

最好的体系结构被证明非常类似于第一种方法模型的两个(“横向”)串联,我认为这相当整洁。

由于渐变消失的问题,我不得不采用较慢的学习速度,随着损失的减少,我的学习速度会变得更慢。

这一次我们有一个不平衡的分类任务,所以我给了积极类更大的权重。

训练耗时更长,在少数情况下(100人中约有5人)没有收敛,需要重新开始。

另一个不同之处在于,使用这种框架,推断并不简单。取而代之的是,我们在输入图像和每个训练图像上运行模型,并挑选模型认为与输入图像最相似的图像的主题。

Model=Sequential([Dense(256,Input_Shape=(X_Train。Shape[1],),ACTIVATION=';REU&39;),BatchNormalization(),Dense(128,ACTIVATION=';REU&39;),BatchNormalization(),Dense(64),BatchNormalization(),Dense(2,ACTIVATION=';Softmax&39;)])模型。编译(LOSS=';CATEGORIC_CROSENTROPY';,优化器=TF.。眼镜蛇。优化器。亚当(学习率=。0001))对于范围(45)内的i:HIST=型号。FIT(X_TRAIN,TO_CATEGORIC(Y_TRAIN),EPOCHS=10,CLASS_WEIGHT={0:1,1:79},VERBOSE=0)LAST_LOSS=HIST。历史[';损失][-1]lr=。0001如果LAST_LOSS<;=。1:LR=。00001型号。编译(LOSS=';CATEGORIC_CROSENTROPY';,优化器=TF.。眼镜蛇。优化器。ADAM(LEARING_RATE=LR))。

该模型的准确率平均为74.4%,比第一种方法和基线都有所提高。然而,结果的差异更大,导致跑得更差和更好。在这个问题上,不同的框架产生了相当大的差异。

在看到第二种方法更好的平均,但也有更大的扩展后,我想知道是否有可能创建一个模型,使用非线性计算图对两者进行优化。想法是这样的:每个输入样本将包含两个面,每个面将“穿过”几个致密层。图像将由相同的图层分别变换,生成的表示将以两种方式使用:

将这两个表示连接起来,在几个更密集的层之后,对它们是否属于同一个人进行分类。

X1=输入(Shape=(Pre_X_Train。Shape[1],),name=';face1';)x2=输入(Shape=(Pre_X_Train。Shape[1],),name=';face2';)L1=Dense(128,ACTIVATION=';REU';,INPUT_SHA形=(x1.。Shape[1],),Name=';Face_REP1';)BN1=BatchNormalization(Name=';Batch_Norm1';)L2=Dense(64,ACTIVATION=';RELU&39;,Input_Shape=(128,),Name=';Face_Rep2&39;)BN2=BatchNormalization(Name=';Batch_Norm2';)L3=Dense(。,input_Shape=(64,),name=';face_rep3';)O1=Dense(40,Activate=';Softmax';,Input_Shape=(32,),name=';face_class';)R1=BN2(L2(BN1(L1(X1)R2=BN2(L2(BN1(L1(X2)C1=Conatenate([R1,R2。)I L4=密集(64,激活=';重新U';,输入_形状=(128,),名称=';比较_密集';)BN3=BatchNormalization(名称=';Batch_Norm3';)O2=密集(2,激活=';Softmax';,输入_形状=(64,),名称=';比较_资源';)face1_res=O1(L3(R1))face2_res=O1(L3(R2))COMPARISON_RES=O2(BN3(L4(C1)MODEL=MODEL(INPUTS=[x1,x2],OUTPUTS=[face1_res,face2_res,compison_res])TF。眼镜蛇。公用事业。PLOT_MODEL(MODEL,';Model.png';,show_Shares=True)模型。编译(优化器=tf。眼镜蛇。优化器。亚当(学习率=。0005),损耗=[TF.。眼镜蛇。损失。类别_交叉标记,TF。眼镜蛇。损失。分类交叉操作,加权分类交叉操作([1,79]),],损失权重=[。1、.。1、1.])。对于范围内的i(130):HIST=型号。FIT([X1_系列,X2_系列],[y1_系列,y2_系列,Y3_系列],纪元=10,详细=0)LAST_LOSS=HIST。历史记录[';COMPARISON_RES_LOSS';][-1]lr=。如果LAST_LOSS<;=,则为0005。5:LR=。0001如果LAST_LOSS<;=。1:LR=。00001型号。编译(优化器=tf。眼镜蛇。优化器。ADAM(LEARING_RATE=LR),损耗=[TF.。眼镜蛇。损失。类别_交叉标记,TF。眼镜蛇。损失。分类交叉操作,加权分类交叉操作([1,39]),],损失权重=[。05、。05,1。])

这款车是训练时间最长的。平均准确率为73.3%,优于基线和第一种方法,但不如第二种方法,但稳定性好得多,没有发生不收敛事件。因此,这一组合似乎确实使我们能够同时享受这两个世界:在保持稳定性的同时性能稍好一些。

在这种情况下,以另一种非直截了当的方式框定任务会产生更好的模型性能。

请记住,此实验是在玩具数据集和问题上进行的,结果不一定适用于所有问题。然而,它突显了我尝试不同框架的潜力,展望未来,当我处理受监督的任务时,我将努力注意可供选择的框架。

这篇文章的源代码可以在这里找到。没有我想的那么整洁,但我想已经足够清楚了。