zoukankan      html  css  js  c++  java
  • 吴恩达deeplearning之CNN—人脸识别与风格化转换 one-shot learning

    1.什么是人脸识别
      这部分演示了百度总部大楼的人脸识别系统,员工刷脸进出办公区,在这个演示中主要应用到了人脸识别技术和活体检测。
    人脸识别的术语:
    1)face verification:输入图像、名字ID判断输入图像是不是名字ID指定的用户
    2)face recognition:有一个包含K个用户的数据库,拿到一幅图片,然后判断图片中的人是不是在数据库中,在输出指定用户name,不在就输出未识别。
      人脸识别要比人脸验证要困难的多,在人脸验证中准确率99%也许可以接受,但是放到包含100个用户的人脸识别数据集下,这个误差就会被放大,意味着1%的概率会出错。在后续我们首先构建人脸验证系统作为基本模块,如果准确率够高就可以把它用在识别系统上。人脸验证系统的难点在于解决one-shot learning(一次学习)问题。


    2. one-shot learning
      one-shot的意思是你需要通过单单一张图片,就能去识别这个人,但是在深度学习中只有一个训练样本时,它的表现并不好,那么如何去解决这个问题呢?
      假如员工数据库有四个员工,当某个员工来的时候,你想通过人脸识别系统判断他是不是四个员工之一,系统需要做的是仅仅通过一张照片,来识别前面这个人。所以在one-shot学习问题中只能通过一个样本来进行学习以能够认出同一个人,大多数人脸识别系统都要解决这个问题,因为在你的数据库中每个雇员可能都只有一张照片。有一种办法是将人的照片输入卷积神经网络,使用softmax单元输出5个标签,分别对应四个员工和四个都不是,但是这样的效果并不好,假如有新的员工加入你的团队,你就需要重新训练你的神经网络,这个确实有些糟糕。

      要让人脸识别做到一次学习,为了能有更好的效果,你需要做的是学习similarity函数,详细的说就是下图中d表示的函数,d以两张图片作为输入,然后输出这两张图片的差异值,如果是同一个人的两张照片,希望输出一个很小的值,如果是两个差异很大的人的照片d输出一个很大的值。这样新加入一个员工只许将其的照片加入到数据库中即可,不需要重新训练模型。


    3.Siamese网络
      Siamese网络就是实现上节函数d的训练,你经常会看到如下的网络结构,输入一个图像经过一系列的卷积、池化和全连接层最终得到一个特征向量,有时候会将其输入softmax单元来做分类,但是在这里我们不需要将其输入softmax单元。加入输出的特征向量大小是128维,将其命名为f(x(1))f(x(1)),你可以将其看成输入图像的编码。

      建立一个人脸识别系统的方法是,如果你要比较两个图片的话,把两个图片喂入有相同网络结构和参数的神经网络,然后分别得到一个128维的向量,两个图像的编码分别命名为f(x(1))f(x(1))、f(x(2))f(x(2)),x(1)x(1)、x(2)x(2)分别表示输入的两张图片,那么将两张图片的编码只差可以定义为:
    d(x(1),x(2))=||f(x(1))−f(x(2))||22
    d(x(1),x(2))=||f(x(1))−f(x(2))||22

    对于两个不同的输入,运行相同的卷积神经网络,然后比较他们这一般叫做Siamese网络架构[1]。

      从上面的描述可知,计算两个图片的网络结构有着同样的参数,所以实际只需要训练一个网络,它计算得到的编码可以用于计算函数d,换句话说其实就是神经网络的参数定义了一个编码函数f(xi)f(xi)可以将图片转换成向量编码。所以我们需要做的就是训练这个网络,使其在两张图片是同一个人的时候距离函数尽可能的小,不是同一个人的时候距离函数尽可能的大。


    4.Triplet损失
      想要通过神经网络来学到好的人脸图像编码,方法之一是定义三元组损失函数然后用梯度下降,为了应用三元组损失函数,你需要比较成对的图像。
      用Triplet的术语来说,你通常会看到anchor(A)、positive(P))、negtative(N)三幅图像,positive是和anchor是同一个人,negative和anchor是不同的人,所以我们希望我们的网络参数能满足:
    d(A,P)−d(A,N)≤0
    d(A,P)−d(A,N)≤0
    其中:d(A,P)=||f(A)−f(P)||2d(A,P)=||f(A)−f(P)||2,d(A,N)=||f(A)−f(N)||2d(A,N)=||f(A)−f(N)||2,这个函数还存在一个问题就是如果d(A,P)d(A,P)和d(A,N)都为0也满足上不等式,但是这并不是我们所想要的,为了避免网络最终学出上面情况,我们在公式中加入超参数αα,公式变形为:
    d(A,P)−d(A,N)+α≤0
    d(A,P)−d(A,N)+α≤0


    Triplet损失函数的定义:
      Triplet损失函数的定义基于A、P、N三张图片,损失函数可以表示为:
    l(A,P,N)=max(d(A,P)−d(A,N)+α,0)
    l(A,P,N)=max(d(A,P)−d(A,N)+α,0)

      所以只要能使d(A,P)−d(A,N)+α≤0d(A,P)−d(A,N)+α≤0损失函数的值就为0,如果d(A,P)−d(A,N)+α>0d(A,P)−d(A,N)+α>0大于0就会得到一个正损失。损失函数只关心d(A,P)−d(A,N)+α≤0d(A,P)−d(A,N)+α≤0,但是并不关心小多少。整个网络的代价函数表示为:
    J=∑i=1ml(Ai,Pi,Ni)
    J=∑i=1ml(Ai,Pi,Ni)
    ,
      假如你有一个1万张图片的训练样本集,包含1000个人,那么平均每个人有10张图片,将其构建成A、P、N的三元组组合,从而训练网络结构,最终通过梯度下降来训练你的网络。

      随机的选择图片构成三元组组合可以达到目的,但是这样的训练样本集很容易就能满足d(A,P)−d(A,N)+α≤0d(A,P)−d(A,N)+α≤0的条件,我们在选择训练样本集 的时候更多应该关注A和N之间差异比较小的图像,从而让网络在这些图像上有更好的区分度[2]。

    5.面部验证与二分类
      这部分分享了一种把人脸识别转变成二分类问题的方法。这种方法选取一对Siamese网络结构,使其同时计算图像的embedings,然后将这些embeding输入到逻辑回归单元进行预测,如果是同一个人就输出1,不是同一个人就输出0,这种方法可以替代Triplet损失,最后的逻辑回归单元
    yˆ=σ(∑k=1128|f(x(i))k−f(x(j))k|)+b
    y^=σ(∑k=1128|f(x(i))k−f(x(j))k|)+b
    其中:k为embeding的下标。因为是Siamese网络结构,上下两个网络结构的参数是完全一致的。


    参考文献
    [1] DeepFace closing the gap to human level performance. Taigeman et.al 2014
    [2] FaceNet:A unified embeding for face recognition and clustering.Schroff et al.2015
    ---------------------
    作者:ice_actor
    来源:CSDN
    原文:https://blog.csdn.net/ice_actor/article/details/78603042
     

  • 相关阅读:
    Oracle:Using the DBMS_STATSpackage
    Oracle partitioning is not always a good idea.
    Oracle: Benefits and consequences of the NOLOGGING option
    Oracle :Insert ways.
    Oracle:临时表的统计信息
    C#中使用DTS来导入数据及相关问题
    [收藏]CSS网页制作时实现自动换行的小技巧
    新加了牛人的Blog链接
    在.Net下使用Access 的日期类型 及与js的日历控件交互
    在程序中生成PDF
  • 原文地址:https://www.cnblogs.com/wuhh123/p/10854799.html
Copyright © 2011-2022 走看看