人脸识别与神经风格迁移
一、什么是人脸识别?
- 人脸验证问题:
输入一张人脸图片和姓名(或者ID),判断图片中的人是否是姓名指向的人,一对一问题。 - 人脸识别问题:
输入一张人脸图片,判断图片中的人是否是数据库中存储的人员信息中的一个,一对多问题。
二、One-Shot learning
-
One-Shot learning(一次学习问题):
每个人的训练样本只包含一张照片,需要通过单单一张图片就能去识别这个人。 -
相似函数:
d ( i m g 1 , i m g 2 ) d(img1,img2) d(img1,img2) = 两张图片之间的差异度
若 d ( i m g 1 , i m g 2 ) ≤ τ d(img1,img2)≤ \tau d(img1,img2)≤τ则判断是一个人;反之不是 -
相似函数如何解决了一次学习问题:
假设要识别5个人脸,我们会使用有5个输出softmax卷积神经网络,然后对这个小样本训练集进行训练,CNN人脸识别效果会很差;若后面要添加新员工,需要修改输出和重新训练。
使用相似函数,就可以一个函数解决所有样本,所有样本训练一个函数。
三、Siamese 网络
- 下图的神经网络最后一层没有连接softmax层,而是通过一个FC输出了128个features,这128个features就可以看作是输入图片的encoding,即原始图片表示成了这128个features。
对于不同的输入图片,都需要通过相同的CNN网络来输出encoding,再将encoding带入相似函数中去比较。如输入了两张图片 x ( 1 ) x^{(1)} x(1)和 x ( 2 ) x^{(2)} x(2),两张图片的相似度可由CNN全输出层 f ( x ( 1 ) ) f(x^{(1)}) f(x(1))和 f ( x ( 2 ) ) f(x^{(2)}) f(x(2))的范式表示: d ( f ( x ( 1 ) ) , f ( x ( 2 ) ) ) d(f(x^{(1)}),f(x^{(2)})) d(f(x(1)),f(x(2)))= ∣ ∣ f ( x ( 1 ) ) − f ( x ( 2 ) ) ∣ ∣ 2 ||f(x^{(1)})-f(x^{(2)})||^2 ∣∣f(x(1))−f(x(2))∣∣2
CNN训练的目标为:
- 若 x ( i ) x^{(i)} x(i)和 x ( j ) x^{(j)} x(j)是同一个人, ∣ ∣ f ( x ( i ) ) − f ( x ( j ) ) ∣ ∣ 2 ||f(x^{(i)})-f(x^{(j)})||^2 ∣∣f(x(i))−f(x(j))∣∣2要很小
- 若 x ( i ) x^{(i)} x(i)和 x ( j ) x^{(j)} x(j)不是同一个人, ∣ ∣ f ( x ( i ) ) − f ( x ( j ) ) ∣ ∣ 2 ||f(x^{(i)})-f(x^{(j)})||^2 ∣∣f(x(i))−f(x(j))∣∣2要很大
四、Triplet Loss
为了定义人脸识别CNN的损失函数,引入Triplet Loss(三元组损失函数)。
如下图,Triplet Loss需要三张图片进行比较:
(1)Anchor【目标】;(2)Positive【正例】;(3)Negative【反例】
将Anchor(A)分别与Positive§和Negative(N)进行比较。
希望A与P的相似函数小一些,A与N的相似函数大一些,即:
∣
∣
f
(
A
)
−
f
(
P
)
∣
∣
2
≤
∣
∣
f
(
A
)
−
f
(
N
)
∣
∣
2
||f(A)-f(P)||^2≤||f(A)-f(N)||^2
∣∣f(A)−f(P)∣∣2≤∣∣f(A)−f(N)∣∣2
∣
∣
f
(
A
)
−
f
(
P
)
∣
∣
2
−
∣
∣
f
(
A
)
−
f
(
N
)
∣
∣
2
≤
0
||f(A)-f(P)||^2-||f(A)-f(N)||^2≤0
∣∣f(A)−f(P)∣∣2−∣∣f(A)−f(N)∣∣2≤0
当CNN输出
∣
∣
f
(
x
)
||f(x)
∣∣f(x)都是0或都相等时,上述式子也都成立的,但不希望CNN训练出这样的参数;因此我们添加一个间隔
α
α
α:
∣
∣
f
(
A
)
−
f
(
P
)
∣
∣
2
−
∣
∣
f
(
A
)
−
f
(
N
)
∣
∣
2
≤
−
α
||f(A)-f(P)||^2-||f(A)-f(N)||^2≤-α
∣∣f(A)−f(P)∣∣2−∣∣f(A)−f(N)∣∣2≤−α
习惯
α
α
α在左边:
∣
∣
f
(
A
)
−
f
(
P
)
∣
∣
2
−
∣
∣
f
(
A
)
−
f
(
N
)
∣
∣
2
+
α
≤
0
||f(A)-f(P)||^2-||f(A)-f(N)||^2+α≤0
∣∣f(A)−f(P)∣∣2−∣∣f(A)−f(N)∣∣2+α≤0
α也被称为边界margin,类似 S V M SVM SVM中的margin,作用是拉大Anchor和Positive 图片对和Anchor和Negative 图片对之间的差距。
损失函数:
给出三张图片:A、P、N
L
(
A
,
P
,
N
)
=
m
a
x
(
∣
∣
f
(
A
)
−
f
(
P
)
∣
∣
2
−
∣
∣
f
(
A
)
−
f
(
N
)
∣
∣
2
+
α
,
0
)
L(A,P,N)=max(||f(A)-f(P)||^2-||f(A)-f(N)||^2+α,0)
L(A,P,N)=max(∣∣f(A)−f(P)∣∣2−∣∣f(A)−f(N)∣∣2+α,0)
只要小于0,损失函数值就为0;大于0就会得到一个大于0的正数损失函数值
m个样本损失函数:
J
=
∑
i
=
1
m
L
(
A
(
i
)
,
P
(
i
)
,
N
(
i
)
)
J=\sum\limits_{i=1}^mL{(A^{(i)},P^{(i)},N^{(i)})}
J=i=1∑mL(A(i),P(i),N(i))
在训练的时候,要保证一个人包含很多照片
,否则无法使用这种方法。如:10k张照片包含1k个不同的人脸,平均一个人有10张照片。
如果随机的选择A、P、N,
d
(
A
,
P
)
+
α
≤
d
(
A
,
N
)
d(A,P)+α≤d(A,N)
d(A,P)+α≤d(A,N)很容易满足,因为A和N之间很容易有很多不同。所有我们应该选择比较“难”训练的三元组去训练网络。
如选择
d
(
A
,
P
)
≈
d
(
A
,
N
)
d(A,P)≈d(A,N)
d(A,P)≈d(A,N)的三元组,这样CNN就会竭尽全力去满足这个式子,使算法效率更加高效。
相关论文:
Florian Schroff, Dmitry Kalenichenko, James Philbin (2015). FaceNet: A Unified Embedding forFace Recognition and Clustering
五、面部验证与二分类
可以将两张图片分别经过CNN得到128个features,再将两个图片的features作为逻辑回归的输入。如下图所示。
逻辑的输出:0表示两张图片不是同一个人;1表示两张图片是同一个人。
训练集从原来的三元组变成现在的二元组了,两个CNN的结构和参数都是相同的。逻辑回归的输出
y
^
\hat{y}
y^可表示为:
y
^
=
σ
(
∑
k
=
1
128
w
k
⋅
∣
f
(
x
(
i
)
)
k
−
f
(
x
(
j
)
)
k
∣
+
b
)
\hat{y}=σ(\sum\limits_{k=1}^{128}w_k\cdot|f(x^{(i)})_k-f(x^{(j)})_k|+b)
y^=σ(k=1∑128wk⋅∣f(x(i))k−f(x(j))k∣+b)
中间的绝对值可以换成
(
f
(
x
(
i
)
)
k
−
f
(
x
(
j
)
)
k
)
2
f
(
x
(
i
)
)
k
+
f
(
x
(
j
)
)
k
\frac {(f(x^{(i)})_k-f(x^{(j)})_k)^2} {f(x^{(i)})_k+f(x^{(j)})_k}
f(x(i))k+f(x(j))k(f(x(i))k−f(x(j))k)2,这个公式也被叫做
X
\cal X
X方相似度:
y
^
=
σ
(
∑
k
=
1
128
w
k
⋅
(
f
(
x
(
i
)
)
k
−
f
(
x
(
j
)
)
k
)
2
f
(
x
(
i
)
)
k
+
f
(
x
(
j
)
)
k
+
b
)
\hat{y}=σ(\sum\limits_{k=1}^{128}w_k\cdot\frac {(f(x^{(i)})_k-f(x^{(j)})_k)^2} {f(x^{(i)})_k+f(x^{(j)})_k}+b)
y^=σ(k=1∑128wk⋅f(x(i))k+f(x(j))k(f(x(i))k−f(x(j))k)2+b)
为了加速运算,可以对数据库中的图片提前计算CNN的输出 f ( x ) f(x) f(x),保存 f ( x ) f(x) f(x)即可;因为编码层输出 f ( x ) f(x) f(x)比原始图片数据量少很多,所以无须保存模板图片,只要保存每个模板的 f ( x ) f(x) f(x)即可,节约存储空间。在进行测试时,只需要计算新的图片的 f ( x ( i ) ) f(x^{(i)}) f(x(i)),再和数据库中存储的 f ( x ( j ) ) f(x^{(j)}) f(x(j))进行比较即可。
六、什么是神经风格转换?
如下图,用右边图片的风格去描述左边的图片。
Content©:内容图片
Style(S):风格图片
Generated(G):生成图片
七、什么是深度卷积网络?
本小节内容来源
在进行神经风格迁移之前,我们先来从可视化的角度看一下卷积神经网络每一层到底是什么样子?它们各自学习了哪些东西。
以Alex网络为例子:
首先来看第一层隐藏层,遍历所有训练样本,找出让该层激活函数输出最大的9块图像区域;然后再找出该层的其它单元(不同的滤波器通道)激活函数输出最大的9块图像区域;最后共找9次,得到9 x 9的图像如下所示,其中每个3 x 3区域表示一个运算单元。
可以看出,第一层隐藏层一般检测的是原始图像的边缘和颜色阴影等简单信息。
继续看CNN的更深隐藏层,随着层数的增加,捕捉的区域更大,特征更加复杂,从边缘到纹理再到具体物体。
八、代价函数
本小节为神经风格迁移定义代价函数。
定义代价函数为
J
(
G
)
J(G)
J(G),
J
(
G
)
J(G)
J(G)由两部分组成:
J
(
G
)
=
α
⋅
J
c
o
n
t
e
n
t
(
C
,
G
)
+
β
⋅
J
s
t
y
l
e
(
S
,
G
)
J(G)=α\cdot J_{content}(C,G)+β\cdot J_{style}(S,G)
J(G)=α⋅Jcontent(C,G)+β⋅Jstyle(S,G)
J c o n t e n t ( C , G ) J_{content}(C,G) Jcontent(C,G)表示C和G之间内容的相似程度, J s t y l e ( S , G ) J_{style}(S,G) Jstyle(S,G)表示S和G之间风格的相似程度。
接下来要做的是:
- 随机初始化G:100X100X3
- 使用梯度下降去最小化
J
(
G
)
J(G)
J(G)
G : = G − ∂ ∂ G J ( G ) G:=G-\frac {\partial}{\partial G}J(G) G:=G−∂G∂J(G)
具体例子如下图:
C和S图:
梯度下降过程:
神经风格迁移学习的是G的像素值
九、内容代价函数
先看看代价函数中的 J c o n t e n t ( C , G ) J_{content}(C,G) Jcontent(C,G):
- 选择之前就训练好的CNN模型,即使用pre-train ConvNet;如选择AlexNet。
- 使用中间层(第
l
l
l层隐藏层)来计算代价函数。
如果使用太深,该层可能判断的是不是狗,若C和G图片都有狗,这两张图片的输出就很相似了。
如果使用太浅,C和G在像素上非常相近,就没有迁移效果了。 - 比较C和G在 l l l层的激活函数输出 a [ l ] ( C ) a^{[l](C)} a[l](C)和 a [ l ] ( G ) a^{[l](G)} a[l](G)。
所以
J
c
o
n
t
e
n
t
(
C
,
G
)
J_{content}(C,G)
Jcontent(C,G)可定义为:
J
c
o
n
t
e
n
t
(
C
,
G
)
=
1
2
∣
∣
a
[
l
]
(
C
)
−
a
[
l
]
(
G
)
∣
∣
2
J_{content}(C,G)=\frac {1}{2}||a^{[l](C)}-a^{[l](G)}||^2
Jcontent(C,G)=21∣∣a[l](C)−a[l](G)∣∣2
接下来使用梯度下降调整G,使 J c o n t e n t ( C , G ) J_{content}(C,G) Jcontent(C,G)达到最小。
十、风格代价函数
将图片的风格定义为
l
l
l层中各个通道之间激活函数值的相关系数(乘积)。即定义风格为通道之间的相关性
例如:
CNN如下图所示:
我们取出第
l
l
l层隐藏层的输出,假设di
l
l
l层的通道数是5,第
l
l
l层隐藏层的输出为如下图所示:
每个通道提取图片的特征风格不同,如下图所示第一个通道获取的是图片中黄色风格特征,第二个获取的是图片中垂直纹理特征。
这两个通道的相关性可以理解为:
当有垂直条纹的地方,都是黄色的,那么正相关性很高。
在这里将两个通道值乘积之和
表示为两个通道之间的相关性系数。因为有黄色和垂直的时候,两个值都会很高,乘积也会很高。
所以定义风格矩阵(style matrix)为:
G
k
k
′
[
l
]
=
∑
i
=
1
n
H
[
l
]
∑
j
=
1
n
W
[
l
]
a
i
j
k
[
l
]
a
i
j
k
′
[
l
]
G^{[l]}_{kk'}=\sum\limits_{i=1}^{n^{[l]}_H}\sum\limits_{j=1}^{n^{[l]}_W}a^{[l]}_{ijk}a^{[l]}_{ijk'}
Gkk′[l]=i=1∑nH[l]j=1∑nW[l]aijk[l]aijk′[l]
- G k k ′ [ l ] G^{[l]}_{kk'} Gkk′[l]表示第 l l l第 k k k个通道和第 k ′ k' k′个通道之间的风格矩阵。 k k k和 k ′ k' k′范围为 1 1 1~ n C [ l ] n^{[l]}_C nC[l]
- G [ l ] G^{[l]} G[l]是一个 n C [ l ] × n C [ l ] n^{[l]}_C\times n^{[l]}_C nC[l]×nC[l]的矩阵
- 若第 k k k个通道和第 k ′ k' k′个通道风格相近,那么 G k k ′ [ l ] G^{[l]}_{kk'} Gkk′[l]会较大;反之较小。
所以
G
[
l
]
(
S
)
G^{[l](S)}
G[l](S)代表了S图第
l
l
l层的风格,
G
[
l
]
(
G
)
G^{[l](G)}
G[l](G)代表了G图第
l
l
l层的风格。想要风格相近,就是要拉近这两个矩阵的距离,所以
J
s
t
y
l
e
[
l
]
(
S
,
G
)
J^{[l]}_{style}(S,G)
Jstyle[l](S,G)可以定义为:
J
s
t
y
l
e
[
l
]
(
S
,
G
)
=
1
2
⋅
n
H
[
l
]
⋅
n
W
[
l
]
⋅
n
C
[
l
]
∑
k
=
1
n
C
[
l
]
∑
k
′
=
1
n
C
[
l
]
∣
∣
G
k
k
′
[
l
]
[
S
]
−
G
k
k
′
[
l
]
[
G
]
∣
∣
F
2
J^{[l]}_{style}(S,G)=\frac {1} {2 \cdot n^{[l]}_H\cdot n^{[l]}_W\cdot n^{[l]}_C}\sum\limits_{k=1}^{n^{[l]}_C}\sum\limits_{k'=1}^{n^{[l]}_C}||G^{[l][S]}_{kk'}-G^{[l][G]}_{kk'}||^2_F
Jstyle[l](S,G)=2⋅nH[l]⋅nW[l]⋅nC[l]1k=1∑nC[l]k′=1∑nC[l]∣∣Gkk′[l][S]−Gkk′[l][G]∣∣F2
- ∣ ∣ G k k ′ [ l ] [ S ] − G k k ′ [ l ] [ G ] ∣ ∣ F 2 ||G^{[l][S]}_{kk'}-G^{[l][G]}_{kk'}||^2_F ∣∣Gkk′[l][S]−Gkk′[l][G]∣∣F2就是计算风格矩阵元素相减的平方和
- 1 2 ⋅ n H [ l ] ⋅ n W [ l ] ⋅ n C [ l ] \frac {1} {2 \cdot n^{[l]}_H\cdot n^{[l]}_W\cdot n^{[l]}_C} 2⋅nH[l]⋅nW[l]⋅nC[l]1是归一化处理
为了提取更多的风格,我们可以使用多层的风格矩阵相加计算风格代价函数,所以风格代价函数可以表示为:
J
s
t
y
l
e
(
S
,
G
)
=
∑
l
λ
[
l
]
⋅
J
s
t
y
l
e
[
l
]
(
S
,
G
)
J_{style}(S,G)=\sum\limits_{l}λ^{[l]}\cdot J^{[l]}_{style}(S,G)
Jstyle(S,G)=l∑λ[l]⋅Jstyle[l](S,G)
- λ [ l ] λ^{[l]} λ[l]:累加过程中各层 J s t y l e [ l ] ( S , G ) J^{[l]}_{style}(S,G) Jstyle[l](S,G)的权重系数,为超参数
十一、一维到三维的推广
n维的就用n维的filter进行卷积
2
D
2D
2D到
1
D
1D
1D:
心电图
- 输入: 14 × 1 14\times1 14×1
- filter尺寸: 5 × 1 5\times1 5×1,数量: 16 16 16
- 输出的卷积结果: 10 × 16 10\times16 10×16
2
D
2D
2D到
3
D
3D
3D:
3维CT扫描图
- 输入: 14 × 14 × 14 × 1 14\times14\times14\times1 14×14×14×1
- filter尺寸: 5 × 5 × 5 × 1 5\times5\times5\times1 5×5×5×1,数量: 16 16 16
- 输出的卷积结果: 10 × 10 × 10 × 16 10\times10\times10\times16 10×10×10×16