0%

One-Shot与Simaese网络

人脸识别是CNN的另一种典型应用。在人脸识别任务中,我们要完成的任务是对于任意的输入人脸图像,判断该图像是否为数据库中某一人的照片。但由于实际应用的限制,我们往往只能获取某人的单张照片作为数据集,通过单张数据训练模型来进行人脸识别的问题就被称为One-Shot问题

上图即为One-Shot问题的范例,对于第一张输入图像,识别系统应该判断出她是第二个人,而对于第二张图像,识别系统应该判断出她不属于四个人中

对于One-Shot问题,传统的分类方法很难奏效。首先每个人的训练样本只有一张,其次对于分类器的输出向量,其维度应与数据库内人总数+1(用额外的一位表示不在数据集里)相同。但由于数据库内人数可能不断扩增(能通过门禁的员工数增加),我们不可能人数每变化一次就训练一个新的模型,所以我们需要新的方法去解决One-Shot问题

首先我们定义判断两张人脸图像是否为同一个人的标准$\tau$,当其值越小,即$d(x_1,x_2)$越小时,则表示这两张图像的相似度越大

有了图像相似度后,我们就可以训练一个将图像编码的网络,然后将数据库内的图片和输入图片的编码依次对比查看他们的相似度,就可以得出结论。这就是Siamese网络的思想

Siamese网络将输入图像通过卷积层和全连接层处理后得到一个$128$维的特征向量,通过计算两张图片间的距离d即可判定其是否为同一人像,d的一种定义为向量差的模长

只要我们设法将这个网络训练成任意表示同一人像的两张图像间的$\tau$尽可能小,不同人像的两张图像的$\tau$尽可能大,就解决了One-Shot问题

为了实现上述目标,Siamese网络的损失函数的定义使用了三元组损失(triple loss)的方法。所谓三元组就是选择一张图像作为基准(Anchor),一张为相同人像的图像(Positive)和一张非相同人像的图像(Negative)。根据d的定义应有

但如果这样定义,当所有图像的特征向量全为0时,是总满足的($0=0$),故我们需要加偏移量使不等式左侧远小于不等式右侧,这样才能显著的将P和N区分开,即

据此定义一对三元组的损失函数L为

则整个训练集上的Loss为

为了训练Siamese网络,我们要用训练集生成尽可能多的三元组m对。当训练好Siamese网络后,利用网络处理得到输入图像的特征向量,再和预存的已知向量进行匹配,当$d(x^{(1)},x^{(2)})$小于阈值$\tau$时,人脸匹配成功,即解决了One-Shot问题