整体思路
训练流程和传统的神经网络类似,构建loss function,然后根据BP算法进行训练,不同之处在于传统的神经网络的训练准则是针对每帧数据,即每帧数据的训练误差最小,而CTC的训练准则是基于序列(比如语音识别的一整句话)的,比如最大化 p ( z ∣ x ) p(z|x) p(z∣x),序列化的概率求解比较复杂,因为一个输出序列可以对应很多的路径,所有引入前后向算法来简化计算。
前期准备
- 输入
x x x,长度为T - 输出集合
A A A表示正常的输出
A ′ = A ⋃ { b l a n k } A'=A \bigcup \{blank\} A′=A⋃{blank}表示输出全集
A ′ T A'^T A′T表示输入x对应的输出元素集合 - 输出序列
π \pi π表示输出路径
l l l表示输出label序列
F \mathcal{F} F表示路径到label序列的映射关系 - 概率
y k t y_k^t ykt表示时间t输出k的概率
p ( π ∣ x ) = ∏ t = 1 T y π t t p(\pi|x)=\displaystyle\prod_{t=1}^{T}y_{\pi_t}^{t} p(π∣x)=t=1∏Tyπtt表示基于输入x的输出 π \pi π路径的概率
p ( l ∣ x ) = ∑ π ∈ F − 1 ( l ) p ( π ∣ x ) p(l|x)=\displaystyle\sum_{\pi \in \mathcal{F}^{-1}(l)}p(\pi|x) p(l∣x)=π∈F−1(l)∑p(π∣x)表示输出label序列的概率是多条路径的概率和。
前后向算法
考虑到计算
p
(
l
∣
x
)
p(l|x)
p(l∣x)需要计算很多条路径的概率,随着输入长度呈指数化增加,可以引入类似于HMM的前后向算法来计算该概率值。
为了引入blank节点,在label首尾以及中间插入blank节点,如果label序列原来的长度为U,那么现在变为U’=2U+1。
前向
前向变量为
α
(
t
,
u
)
\alpha(t,u)
α(t,u),表示t时刻在节点u的前向概率值,其中
u
∈
[
1
,
2
U
+
1
]
u\in [1,2U+1]
u∈[1,2U+1].
初始化值如下:
α
(
1
,
1
)
=
y
b
1
\alpha(1,1)=y_b^1
α(1,1)=yb1
α
(
1
,
2
)
=
y
l
1
1
\alpha(1,2)=y_{l_1}^1
α(1,2)=yl11
α
(
1
,
u
)
=
0
,
∀
u
>
2
\alpha(1,u)=0, \forall u>2
α(1,u)=0,∀u>2
递推关系:
α
(
t
,
u
)
=
y
l
u
′
t
∑
i
=
f
(
u
)
u
α
(
t
−
1
,
i
)
\alpha(t,u)=y_{l'_{u}}^t\displaystyle\sum_{i=f(u)}^{u}\alpha(t-1,i)
α(t,u)=ylu′ti=f(u)∑uα(t−1,i)
其中
f
(
u
)
=
{
u
−
1
if
l
u
′
=
b
l
a
n
k
or
l
u
−
2
′
=
l
u
′
u
−
2
otherwise
f(u) = \begin{cases} u-1 & \quad \text{if } l'_u=blank \text{ or }l'_{u-2}=l'_u\\ u-2 & \quad \text{otherwise}\\ \end{cases}
f(u)={u−1u−2if lu′=blank or lu−2′=lu′otherwise
注:如果l表示{c,a,t},那么l’表示为{b,c,b,a,b,t,b},所以原来在l中的下标u为2,在l’中的下标u变为4。
α
(
t
,
u
)
=
0
∀
u
<
U
′
−
2
(
T
−
t
)
−
1
\alpha(t,u)=0 \forall u< U'-2(T-t)-1
α(t,u)=0∀u<U′−2(T−t)−1对应于上图中的右上角部分,因为时间的限制,有些节点不可能到达最后的终止节点。
根据上图,很容易理解前向的递推关系。
后向
初始化值:
β
(
T
,
U
′
)
=
1
\beta(T,U')=1
β(T,U′)=1
β
(
T
,
U
′
−
1
)
=
1
\beta(T,U'-1)=1
β(T,U′−1)=1
β
(
T
,
u
)
=
0
,
∀
u
<
U
′
−
2
\beta(T,u)=0, \forall u<U'-2
β(T,u)=0,∀u<U′−2
α
(
1
,
u
)
=
0
,
∀
u
>
2
\alpha(1,u)=0, \forall u>2
α(1,u)=0,∀u>2
递推关系:
β
(
t
,
u
)
=
∑
i
=
u
g
(
u
)
β
(
t
+
1
,
i
)
y
l
i
′
t
+
1
\beta(t,u)=\displaystyle\sum_{i=u}^{g(u)}\beta(t+1,i)y_{l'_{i}}^{t+1}
β(t,u)=i=u∑g(u)β(t+1,i)yli′t+1
其中
g
(
u
)
=
{
u
+
1
if
l
u
′
=
b
l
a
n
k
or
l
u
+
2
′
=
l
u
′
u
+
2
otherwise
g(u) = \begin{cases} u+1 & \quad \text{if } l'_u=blank \text{ or }l'_{u+2}=l'_u\\ u+2 & \quad \text{otherwise}\\ \end{cases}
g(u)={u+1u+2if lu′=blank or lu+2′=lu′otherwise
取log
概率计算在log计算,避免underflow,其中log加可以通过以下形式转化:
l
n
(
a
+
b
)
=
l
n
a
+
l
n
(
1
+
e
l
n
b
−
l
n
a
)
ln(a+b)=lna+ln(1+e^{lnb-lna})
ln(a+b)=lna+ln(1+elnb−lna)
##训练
loss function
CTC的loss function使用最大似然:
L
(
S
)
=
∑
(
x
,
z
)
∈
S
L
(
x
,
z
)
L(S)=\displaystyle\sum_{(x,z)\in S}L(x,z)
L(S)=(x,z)∈S∑L(x,z)
L
(
x
,
z
)
=
−
l
n
p
(
z
∣
x
)
L(x,z)=-lnp(z|x)
L(x,z)=−lnp(z∣x)
根据前后向变量,可以求得:
p
(
z
∣
x
)
=
∑
u
=
1
∣
z
′
∣
α
(
t
,
u
)
β
(
t
,
u
)
p(z|x)=\displaystyle\sum_{u=1}^{|z'|}\alpha(t,u)\beta(t,u)
p(z∣x)=u=1∑∣z′∣α(t,u)β(t,u)
∣
z
′
∣
|z'|
∣z′∣表示z对应的label长度的U’,
α
(
t
,
u
)
β
(
t
,
u
)
\alpha(t,u)\beta(t,u)
α(t,u)β(t,u)表示t时刻经过节点u的所有路径的概率和。
L
(
x
,
z
)
=
−
l
n
∑
u
=
1
∣
z
′
∣
α
(
t
,
u
)
β
(
t
,
u
)
L(x,z)=-ln\displaystyle\sum_{u=1}^{|z'|}\alpha(t,u)\beta(t,u)
L(x,z)=−lnu=1∑∣z′∣α(t,u)β(t,u)
bp训练
y
k
t
y_k^t
ykt表示t时刻输出k的概率
a
k
t
a_k^t
akt表示t时刻对应输出节点k在做softmax转换之前的值
∂
L
(
x
,
z
)
∂
y
k
t
=
−
1
p
(
z
∣
x
)
∂
p
(
z
∣
x
)
∂
y
k
t
\frac{\partial L(x,z)}{\partial y_k^t}=-\frac{1}{p(z|x)}\frac{\partial p(z|x)}{\partial y_k^t}
∂ykt∂L(x,z)=−p(z∣x)1∂ykt∂p(z∣x)
只需要考虑t时刻经过k节点的路径即可
∂
p
(
z
∣
x
)
∂
y
k
t
=
∑
u
∈
B
(
z
,
k
)
∂
α
(
t
,
u
)
β
(
t
,
u
)
∂
y
k
t
\frac{\partial p(z|x)}{\partial y_k^t}=\displaystyle\sum_{u\in B(z,k)}\frac{\partial \alpha(t,u)\beta(t,u)}{\partial y_k^t}
∂ykt∂p(z∣x)=u∈B(z,k)∑∂ykt∂α(t,u)β(t,u)
其中
B
(
z
,
k
)
B(z,k)
B(z,k)表示节点为k的集合
考虑到
α
(
t
,
u
)
β
(
t
,
u
)
=
∑
π
∈
X
(
t
,
u
)
∏
t
=
1
T
y
π
t
t
\alpha(t,u)\beta(t,u)=\displaystyle\sum_{\pi \in X(t,u)}\displaystyle\prod_{t=1}^{T}y_{\pi_t}^{t}
α(t,u)β(t,u)=π∈X(t,u)∑t=1∏Tyπtt
其中
X
(
t
,
u
)
X(t,u)
X(t,u)表示所有在t时刻经过节点u的路径。
所以
∂
p
(
z
∣
x
)
∂
y
k
t
=
∑
u
∈
B
(
z
,
k
)
α
(
t
,
u
)
β
(
t
,
u
)
y
k
t
\frac{\partial p(z|x)}{\partial y_k^t}=\displaystyle\sum_{u\in B(z,k)}\frac{\alpha(t,u)\beta(t,u)}{y_k^t}
∂ykt∂p(z∣x)=u∈B(z,k)∑yktα(t,u)β(t,u)
可以到损失函数对
y
k
t
y_k^t
ykt偏导数
∂
L
(
x
,
z
)
∂
y
k
t
=
−
1
p
(
z
∣
x
)
y
k
t
∑
u
∈
B
(
z
,
k
)
α
(
t
,
u
)
β
(
t
,
u
)
\frac{\partial L(x,z)}{\partial y_k^t}=-\frac{1}{p(z|x)y_k^t}\displaystyle\sum_{u\in B(z,k)}{\alpha(t,u)\beta(t,u)}
∂ykt∂L(x,z)=−p(z∣x)ykt1u∈B(z,k)∑α(t,u)β(t,u)
同时可以得到损失函数对于
a
k
t
a_k^t
akt偏导数
∂
L
(
x
,
z
)
∂
a
k
t
=
y
k
t
−
1
p
(
z
∣
x
)
∑
u
∈
B
(
z
,
k
)
α
(
t
,
u
)
β
(
t
,
u
)
\frac{\partial L(x,z)}{\partial a_k^t}=y_k^t-\frac{1}{p(z|x)}\displaystyle\sum_{u\in B(z,k)}{\alpha(t,u)\beta(t,u)}
∂akt∂L(x,z)=ykt−p(z∣x)1u∈B(z,k)∑α(t,u)β(t,u)
推导参考:
后续可以使用BPTT算法得到损失函数对神经网络参数的偏导。
参考
《Supervised Sequence Labelling with Recurrent Neural Networks》 chapter7