人脸识别、神经风格迁移
监督学习:实现检测活体
定义:根据已有的数据集,知道输入和输出结果之间的关系。根据这种已知的关系,训练得到一个最优的模型。也就是说,在监督学习中训练数据既有特征(feature)又有标签(label),通过训练,让机器可以自己找到特征和标签之间的联系,在面对只有特征没有标签的数据时,可以判断出标签。
通俗一点,可以把机器学习理解为我们教机器如何做事情。
监督学习的分类:回归(Regression)、分类(Classification)
回归(Regression)
回归问题是针对于连续型变量的。
举个栗子:预测房屋价格
分类(Classification)
和回归最大的区别在于,分类是针对离散型的,输出的结果是有限的。
举个栗子:估计肿瘤性质
无监督学习
定义:我们不知道数据集中数据、特征之间的关系,而是要根据聚类或一定的模型得到数据之间的关系。
可以这么说,比起监督学习,无监督学习更像是自学,让机器学会自己做事情,是没有标签(label)的。
人脸识别:一对一
人脸验证:多找一
人脸验证的难处在于:一次学习,意思是数据库保存一张图片,就能一直验证这个人。
One-Shot学习(One-shot learning)
所以要让人脸识别能够做到一次学习,为了能有更好的效果,你现在要做的应该是学习Similarity函数。详细地说,你想要神经网络学习这样一个用
d
d
d表示的函数,
d(img1,img2) = degree of difference between images
{\text{d(img1,img2) = degree of difference between images}}
d(img1,img2) = degree of difference between images,它以两张图片作为输入,然后输出这两张图片的差异值。如果你放进同一个人的两张照片,你希望它能输出一个很小的值,如果放进两个长相差别很大的人的照片,它就输出一个很大的值。所以在识别过程中,如果这两张图片的差异值小于某个阈值
τ
\tau
τ,它是一个超参数,那么这时就能预测这两张图片是同一个人,如果差异值大于
τ
\tau
τ,就能预测这是不同的两个人,这就是解决人脸验证问题的一个可行办法。
Siamese 网络(Siamese network)
如何训练你的神经网络学会这个函数
d
d
d。
建立一个人脸识别系统的方法就是,如果你要比较两个图片的话,例如这里的第一张(编号1)和第二张图片(编号2),你要做的就是把第二张图片喂给有同样参数的同样的神经网络,然后得到一个不同的128维的向量(编号3),这个向量代表或者编码第二个图片,我要把第二张图片的编码叫做
f
(
x
(
2
)
)
f({x^{(2)}})
f(x(2))。这里我用
x
(
2
)
{x^{(2)}}
x(2)和
x
(
1
)
{x^{(1)}}
x(1)仅仅代表两个输入图片,他们没必要非是第一个和第二个训练样本,可以是任意两个图片。
最后如果你相信这些编码很好地代表了这两个图片,你要做的就是定义 d d d,将 x ( 2 ) {x^{(2)}} x(2)和 x ( 1 ) {x^{(1)}} x(1)的距离定义为这两幅图片的编码之差的范数, d ( x ( 1 ) , x ( 2 ) ) = ∣ f ( x ( 1 ) ) − f ( x ( 2 ) ) ∣ 2 2 d({x^{(1)}},{x^{(2)}}) = {\left| {f({x^{(1)}}) - f({x^{(2)}})} \right|_2}^2 d(x(1),x(2))=∣∣∣f(x(1))−f(x(2))∣∣∣22。
对于两个不同的输入,运行相同的卷积神经网络,然后比较它们,这一般叫做Siamese网络架构。
4.4 Triplet 损失(Triplet 损失)
但是如何定义实际的目标函数,能够让你的神经网络学习并做到?
答:用三元组损失函数达到这个目的。
要想通过学习神经网络的参数来得到优质的人脸图片编码,方法之一就是定义三元组损失函数然后应用梯度下降。
这就是为什么叫做三元组损失,它代表你通常会同时看三张图片
把这些写成公式的话,你想要的是网络的参数或者编码能够满足以下特性,也就是说你想要
∥
f
(
A
)
−
f
(
P
)
∥
2
{\left\| {f(A) - f(P)} \right\|^2}
∥f(A)−f(P)∥2,你希望这个数值很小,准确地说,你想让它小于等
f
(
A
)
f(A)
f(A)和
f
(
N
)
f(N)
f(N)之间的距离,或者说是它们的范数的平方(即:
∥
f
(
A
)
−
f
(
P
)
∥
2
⩽
∥
f
(
A
)
−
f
(
N
)
∥
2
{\left\| {f(A) - f(P)} \right\|^2} \leqslant {\left\| {f(A) - f(N)} \right\|^2}
∥f(A)−f(P)∥2⩽∥f(A)−f(N)∥2)。(
∥
f
(
A
)
−
f
(
P
)
∥
2
{\left\| {f(A) - f(P)} \right\|^2}
∥f(A)−f(P)∥2)当然这就是
d
(
A
,
P
)
d(A,P)
d(A,P),(
∥
f
(
A
)
−
f
(
N
)
∥
2
{\left\| {f(A) - f(N)} \right\|^2}
∥f(A)−f(N)∥2)这是
d
(
A
,
N
)
d(A,N)
d(A,N),你可以把
d
d
d看作是距离(distance)函数,这也是为什么我们把它命名为
d
d
d。
现在如果我把方程右边项移到左边,最终就得到:
∥
f
(
A
)
−
f
(
P
)
∥
2
⩽
∥
f
(
A
)
−
f
(
N
)
∥
2
{\left\| {f(A) - f(P)} \right\|^2} \leqslant {\left\| {f(A) - f(N)} \right\|^2}
∥f(A)−f(P)∥2⩽∥f(A)−f(N)∥2
现在我要对这个表达式做一些小的改变,有一种情况满足这个表达式,但是没有用处,就是把所有的东西都学成0,如果f总是输出0,即0-0≤0,这就是0减去0还等于0,如果所有图像的f都是一个零向量,那么总能满足这个方程。所以为了确保网络对于所有的编码不会总是输出0,也为了确保它不会把所有的编码都设成互相相等的。另一种方法能让网络得到这种没用的输出,就是如果每个图片的编码和其他图片一样,这种情况,你还是得到0-0。
∥ f ( A ) − f ( P ) ∥ 2 − ∥ f ( A ) − f ( N ) ∥ 2 + α ⩽ 0 {\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} + \alpha \leqslant 0 ∥f(A)−f(P)∥2−∥f(A)−f(N)∥2+α⩽0
这里的 α \alpha α是另一个超参数,这个就可以阻止网络输出无用的结果。它也叫做间隔(margin).
定义损失函数:
这是一个三元组定义的损失,整个网络的代价函数应该是训练集中这些单个三元组损失的总和。假如你有一个10000个图片的训练集,里面是1000个不同的人的照片,你要做的就是取这10000个图片,然后生成这样的三元组,然后训练你的学习算法,对这种代价函数用梯度下降,这个代价函数就是定义在你数据集里的这样的三元组图片上。
这里为什么损失函数是这个,意义是啥??
它代表的不应该是两个图片是否是同一个人吗?
注意,为了定义三元组的数据集你需要成对的A和P,即同一个人的成对的图片,为了训练你的系统你确实需要一个数据集,里面有同一个人的多个照片。这是为什么在这个例子中,我说假设你有1000个不同的人的10000张照片,也许是这1000个人平均每个人10张照片,组成了你整个数据集。如果你只有每个人一张照片,那么根本没法训练这个系统。当然,训练完这个系统之后,你可以应用到你的一次学习问题上,对于你的人脸识别系统,可能你只有想要识别的某个人的一张照片。但对于训练集,你需要确保有同一个人的多个图片,至少是你训练集里的一部分人,这样就有成对的Anchor和Positive图片了。
只有选择难的三元组梯度下降法才能发挥作用
定义了这些包括、和图片的数据集之后,你还需要做的就是用梯度下降最小化我们之前定义的代价函数J
人脸验证与二分类
选取Siamese网络,使其同时计算这些嵌入,比如说128维的嵌入(编号1),或者更高维,然后将其输入到逻辑回归单元,然后进行预测,如果是相同的人,那么输出是1,若是不同的人,输出是0。这就把人脸识别问题转换为一个二分类问题,训练这种系统时可以替换Triplet loss的方法。
神经风格迁移(我很喜欢!)
卷积网络中深度较大的层真正在做什么,这样有助于理解如何实现神经风格迁移。
疑问:为什么代价函数使用梯度下降算法就可以不断的变好啊?它不仅仅是求导吗???
代价函数
要构建一个神经风格迁移系统,让我们为生成的图像定义一个代价函数,你接下看到的是,通过最小化代价函数,你可以生成你想要的任何图像。
记住我们的问题,给你一个内容图像C,给定一个风格图片S,而你的目标是生成一个新图片G。为了实现神经风格迁移,你要做的是定义一个关于G的代价函数J用来评判某个生成图像的好坏,我们将使用梯度下降法J(G)去最小化,以便于生成这个图像。
怎么判断生成图像的好坏呢?我们把这个代价函数定义为两个部分。
J
content
(
C
,
G
)
{J_{{\text{content}}}}(C,G)
Jcontent(C,G)
第一部分被称作内容代价,这是一个关于内容图片和生成图片的函数,它是用来度量生成图片的内容与内容图片的内容有多相似。
J
style
(
S
,
G
)
{J_{{\text{style}}}}(S,G)
Jstyle(S,G)
然后我们会把结果加上一个风格代价函数,也就是关于和的函数,用来度量图片的风格和图片的风格的相似度。
J
(
G
)
=
α
J
c
o
n
t
e
n
t
(
C
,
G
)
+
β
J
s
t
y
l
e
(
S
,
G
)
J(G) = \alpha {J_{content}}(C,G) + \beta {J_{style}}(S,G)
J(G)=αJcontent(C,G)+βJstyle(S,G)
最后我们用两个超参数和来来确定内容代价和风格代价,两者之间的权重用两个超参数来确定。
内容代价函数
假如说,你用隐含层 l l l来计算内容代价,如果 l l l是个很小的数,比如用隐含层1,这个代价函数就会使你的生成图片像素上非常接近你的内容图片。然而如果你用很深的层,那么那就会问,内容图片里是否有狗,然后它就会确保生成图片里有一个狗。所以在实际中,这个 l l l层在网络中既不会选的太浅也不会选的太深。
风格代价函数
每个通道有每个通道的作用,查看两个通道的相关性。
疑问:对于风格代价函数,不理解!