BILSTM-CRF
声明:本系列转载自createmomo大神的博客https://createmomo.github.io,并在其中加入一些新的内容,如有侵权请及时联系。
2.6 推断新句子的标签
在前面的部分中,我们学习了BiLSTM-CRF模型的结构和CRF损失函数的细节。您可以通过各种开源框架(Keras,Chainer,TensorFlow等)实现您自己的BiLSTM-CRF模型。最重要的事情之一是在这些框架上自动计算模型的反向传播,因此您不需要自己实现反向传播来训练模型(即计算梯度和更新参数)。此外,一些框架已经实现了CRF层,因此只需添加一行代码就可以非常轻松地将CRF层与您自己的模型相结合。
在本节中,我们将探讨在模型准备好时如何在测试期间推断出句子的标签。
第1步:BiLSTM-CRF模型的emission和transition score
我们有一个3个字的句子: x = [ w 0 , w 1 , w 2 ] x=[w_0, w_1, w_2] x=[w0,w1,w2]。此外,假设我们已经获得了BiLSTM模型的emission score和CRF层的transition score:
l 1 l_1 l1 | l 2 l_2 l2 | |
---|---|---|
w 0 w_0 w0 | w 01 w_{01} w01 | w 02 w_{02} w02 |
w 1 w_1 w1 | w 11 w_{11} w11 | w 12 w_{12} w12 |
w 2 w_2 w2 | w 21 w_{21} w21 | w 22 w_{22} w22 |
x i j x_{ij} xij表示 w i w_i wi的分数被标记为 l j l_j lj。
l 1 l_1 l1 | l 2 l_2 l2 | |
---|---|---|
l 1 l_1 l1 | t 11 t_{11} t11 | t 12 t_{12} t12 |
l 2 l_2 l2 | t 21 t_{21} t21 | t 22 t_{22} t22 |
t i j t_{ij} tij是标签 i i i转移到标签 j j j的分数
第2步:开始推理
如果您熟悉Viterbi算法,这部分对您来说很容易。但如果你不是,请不要担心。与前一节类似,我将逐步解释算法。我们将从句子的左侧到右侧运行推理算法,如下所示:
w
0
w_0
w0
w
0
w_0
w0–>
w
1
w_1
w1
w
0
w_0
w0–>
w
1
w_1
w1–>
w
2
w_2
w2
您将看到两个变量: o b s obs obs和 p r e v i o u s previous previous。 p r e v i o u s previous previous存储前面步骤的最终结果。 o b s obs obs表示来自当前单词的信息。
a l p h a 0 alpha_0 alpha0是成绩最好的历史, a l p h a 1 alpha_1 alpha1是其对应的索引。这两个变量的细节将在它们出现时进行解释。请看下图:您可以将这两个变量视为狗在探索森林时沿路行驶的“标记”,这些“标记”将有助于帮助他找到回家的路。
w
0
w_0
w0:
o
b
s
=
[
x
01
,
x
02
]
obs=[x_{01}, x_{02}]
obs=[x01,x02]
p
r
e
v
i
o
u
s
=
N
o
n
e
previous=None
previous=None
目前,我们正在观察第一个词 w 0 w_0 w0。到目前为止, w 0 w_0 w0的最佳标签很简单。例如,如果 o b s = [ x 01 = 0.2 , x 02 = 0.8 ] obs=[x_{01}=0.2, x_{02}=0.8] obs=[x01=0.2,x02=0.8],显然, w 0 w_0 w0的最佳标签应该是 l 2 l_2 l2,由于标签之间只有一个单词且没有转换,因此不使用转换分数。
w
0
w_0
w0 -->
w
1
w_1
w1:
o
b
s
=
[
x
11
,
x
12
]
obs=[x_{11, x_{12}}]
obs=[x11,x12]
p
r
e
v
i
o
u
s
=
[
x
01
,
x
02
]
previous=[x_{01}, x_{02}]
previous=[x01,x02]
1).扩展
p
r
e
v
i
o
u
s
previous
previous:
p
r
e
v
i
o
u
s
=
(
p
r
e
v
i
o
u
s
[
1
]
p
r
e
v
i
o
u
s
[
1
]
p
r
e
v
i
o
u
s
[
0
]
p
r
e
v
i
o
u
s
[
0
]
)
=
(
x
02
x
02
x
01
x
01
)
previous=\left(^{previous[0] \quad previous[0]}_{previous[1] \quad previous[1]}\right)=\left(^{x_{01} \quad x_{01}}_{x_{02} \quad x_{02}}\right)
previous=(previous[1]previous[1]previous[0]previous[0])=(x02x02x01x01)
2).扩展 o b s obs obs
o b s = ( o b s [ 0 ] o b s [ 1 ] o b s [ 0 ] o b s [ 1 ] ) = ( x 11 x 12 x 11 x 12 ) obs=\left(^{obs[0] \quad obs[1]}_{obs[0] \quad obs[1]}\right)=\left(^{x_{11} \quad x_{12}}_{x_{11} \quad x_{12}}\right) obs=(obs[0]obs[1]obs[0]obs[1])=(x11x12x11x12)
3).计算 p r e v i o u s previous previous, o b s obs obs, t r a n s i t i o n transition transition分数和
s c o r e s = ( x 02 x 02 x 01 x 01 ) + ( x 11 x 12 x 11 x 12 ) + ( t 21 t 22 t 11 t 12 ) scores=\left(^{x_{01} \quad x_{01}}_{x_{02} \quad x_{02}}\right) + \left(^{x_{11} \quad x_{12}}_{x_{11} \quad x_{12}}\right) + \left(^{t_{11} \quad t_{12}}_{t_{21} \quad t_{22}}\right) scores=(x02x02x01x01)+(x11x12x11x12)+(t21t22t11t12)
然后:
s c o r e s = ( x 02 + x 11 + t 21 x 02 + x 12 + t 22 x 01 + x 11 + t 11 x 01 + x 12 + t 12 ) scores=\left(^{x_{01}+x_{11}+t_{11} \quad x_{01}+x_{12}+t_{12}}_{x_{02}+x_{11}+t{21} \quad x_{02}+x_{12}+t_{22}}\right) scores=(x02+x11+t21x02+x12+t22x01+x11+t11x01+x12+t12)
当我们计算所有路径的总分时,您可能会发现这与前面的部分没有区别,并对此产生疑惑。请耐心细致,您很快就会看到差异。
更改下一次迭代的
p
r
e
v
i
o
u
s
previous
previous值:
p r e v i o u s = [ max ( s c o r e s [ 00 ] , s c o r e s [ 10 ] ) , max ( s c o r e s [ 01 ] , s c o r e s [ 11 ] ) ] previous=[\max (scores[00], scores[10]),\max (scores[01],scores[11])] previous=[max(scores[00],scores[10]),max(scores[01],scores[11])]
例如,如果你的分数是:
s c o r e s = ( x 02 + x 11 + t 21 x 02 + x 12 + t 22 x 01 + x 11 + t 11 x 01 + x 12 + t 12 ) = ( 0.5 0.4 0.2 0.3 ) scores=\left(^{x_{01}+x_{11}+t_{11} \quad x_{01}+x_{12}+t_{12}}_{x_{02}+x_{11}+t{21} \quad x_{02}+x_{12}+t_{22}}\right)=\left( ^{0.2 \quad 0.3}_{0.5 \quad 0.4}\right) scores=(x02+x11+t21x02+x12+t22x01+x11+t11x01+x12+t12)=(0.50.40.20.3)
我们下一次迭代的 p r e v i o u s previous previous将是:
p r e v i o u s = [ max ( s c o r e s [ 00 ] , s c o r e s [ 10 ] ) , max ( s c o r e s [ 01 ] , s c o r e s [ 11 ] ) ] = [ 0.5 , 0.4 ] previous=[\max (scores[00], scores[10]),\max (scores[01],scores[11])] = [0.5, 0.4] previous=[max(scores[00],scores[10]),max(scores[01],scores[11])]=[0.5,0.4]
p r e v i o u s previous previous是什么意思? p r e v i o u s previous previous列表存储当前单词对每个标签的最大分数。
[示例开始]
例如:
在我们的语料库中,我们总共有2个标签,
l
a
b
e
l
1
(
l
1
)
label1(l_1)
label1(l1)和
l
a
b
e
l
2
(
l
2
)
label2(l_2)
label2(l2),这两个标签的索引分别为0和1。
p
r
e
v
i
o
u
s
[
0
]
previous[0]
previous[0]是以第0个标签
l
1
l_1
l1结束的路径的最大分数,类似的
p
r
e
v
i
o
u
s
[
1
]
previous[1]
previous[1]是以
l
2
l_2
l2结束的路径的分数。在每次迭代过程中,我们仅仅保留每个标签对应的最优路径的信息(
p
r
e
v
i
o
u
s
=
[
max
(
s
c
o
r
e
s
[
00
]
,
s
c
o
r
e
s
[
10
]
)
,
max
(
s
c
o
r
e
s
[
01
]
,
s
c
o
r
e
s
[
11
]
)
]
previous=[\max(scores[00], scores[10]),\max( scores[01], scores[11])]
previous=[max(scores[00],scores[10]),max(scores[01],scores[11])])。分数较少的路径信息将被丢弃。
[示例结束]
回到我们的主要任务:
同时,我们还有两个变量来存储历史信息(分数和索引),即
a
l
p
h
a
0
alpha_0
alpha0和
a
l
p
h
a
1
alpha_1
alpha1。
本次迭代,我们将添加最好的分数到
a
l
p
h
a
0
alpha_0
alpha0。为方便起见,每个标签的最高分都有下划线。
s c o r e s = ( x 02 + x 11 + t 21 ‾ x 02 + x 12 + t 22 ‾ x 01 + x 11 + t 11 x 01 + x 12 + t 12 ) = ( 0.5 ‾ 0.4 ‾ 0.2 0.3 ) scores=\left(^{x_{01}+x_{11}+t_{11} \quad x_{01}+x_{12}+t_{12}}_{\underline{x_{02}+x_{11}+t{21}} \quad \underline{x_{02}+x_{12}+t_{22}}}\right)=\left( ^{0.2 \quad 0.3}_{\underline{0.5} \quad \underline{0.4}}\right) scores=(x02+x11+t21x02+x12+t22x01+x11+t11x01+x12+t12)=(0.50.40.20.3)
a l p h a 0 = [ ( s c o r e s [ 10 ] , s c o r e s [ 11 ] ) ] = [ ( 0.5 , 0.4 ) ] alpha_0=[(scores[10],scores[11])]=[(0.5,0.4)] alpha0=[(scores[10],scores[11])]=[(0.5,0.4)]
另外,相应的列的索引被保存在 a l p h a 1 alpha_1 alpha1:
a l p h a 1 = [ ( C o l u m n I n d e x ( s c o r e s [ 10 ] ) , C o l u m n I n d e x ( s c o r e s [ 11 ] ) ) ] = [ ( 1 , 1 ) ] alpha_1=[(ColumnIndex(scores[10]),ColumnIndex(scores[11]))]=[(1,1)] alpha1=[(ColumnIndex(scores[10]),ColumnIndex(scores[11]))]=[(1,1)]
其中,
l
1
l_1
l1的索引是0,
l
2
l_2
l2的索引是1,所以
(
1
,
1
)
=
(
l
2
,
l
2
)
(1, 1)=(l_2, l_2)
(1,1)=(l2,l2),这意味着对于当前的单词
w
i
w_i
wi和标签
l
(
i
)
l^(i)
l(i):
(
1
,
1
)
=
(
l
2
,
l
2
)
=
(
当
路
径
是
l
(
i
−
1
)
=
l
2
‾
−
>
l
(
i
)
=
l
1
‾
时
我
们
可
以
得
到
最
大
分
数
0.5
,
当
路
径
是
l
(
i
−
1
)
=
l
2
‾
−
>
l
(
i
)
=
l
2
‾
时
我
们
可
以
得
到
最
大
分
数
0.4
)
(1, 1)=(l_2, l_2)=(当路径是\underline{l^{(i-1)}=l_2} -> \underline{l^{(i)}=l_1}时我们可以得到最大分数0.5, 当路径是\underline{l^{(i-1)}=l_2} -> \underline{l^{(i)}=l_2}时我们可以得到最大分数0.4)
(1,1)=(l2,l2)=(当路径是l(i−1)=l2−>l(i)=l1时我们可以得到最大分数0.5,当路径是l(i−1)=l2−>l(i)=l2时我们可以得到最大分数0.4)
l ( i − 1 ) l^{(i-1)} l(i−1)是前一个单词 w i − 1 w_{i-1} wi−1对应的标签
w
0
w_0
w0 -->
w
1
w_1
w1 -->
w
2
w_2
w2:
o
b
s
=
[
x
21
,
x
22
]
obs=[x_{21}, x_{22}]
obs=[x21,x22]
p
r
e
v
i
o
u
s
=
[
0.5
,
0.4
]
previous=[0.5, 0.4]
previous=[0.5,0.4]
1).扩展 p r e v i o u s previous previous:
p r e v i o u s = ( p r e v i o u s [ 1 ] p r e v i o u s [ 1 ] p r e v i o u s [ 0 ] p r e v i o u s [ 0 ] ) = ( 0.4 0.4 0.5 0.5 ) previous=\left(^{previous[0] \quad previous[0]}_{previous[1] \quad previous[1]}\right)=\left(^{0.5 \quad 0.5}_{0.4 \quad 0.4}\right) previous=(previous[1]previous[1]previous[0]previous[0])=(0.40.40.50.5)
2).扩展 o b s obs obs
o b s = ( o b s [ 0 ] o b s [ 1 ] o b s [ 0 ] o b s [ 1 ] ) = ( x 21 x 22 x 21 x 22 ) obs=\left(^{obs[0] \quad obs[1]}_{obs[0] \quad obs[1]}\right)=\left(^{x_{21} \quad x_{22}}_{x_{21} \quad x_{22}}\right) obs=(obs[0]obs[1]obs[0]obs[1])=(x21x22x21x22)
3).计算 p r e v i o u s previous previous, o b s obs obs, t r a n s i t i o n transition transition分数和
s c o r e s = ( 0.4 0.4 0.5 0.5 ) + ( x 21 x 22 x 21 x 22 ) + ( t 21 t 22 t 11 t 12 ) scores=\left(^{0.5 \quad 0.5}_{0.4 \quad 0.4}\right) +\left(^{x_{21} \quad x_{22}}_{x_{21} \quad x_{22}}\right)+ \left(^{t_{11} \quad t_{12}}_{t_{21} \quad t_{22}}\right) scores=(0.40.40.50.5)+(x21x22x21x22)+(t21t22t11t12)
然后:
s c o r e s = ( 0.4 + x 21 + t 21 0.4 + x 22 + t 22 0.5 + x 21 + t 11 0.5 + x 22 + t 12 ) scores=\left(^{0.5+x_{21}+t_{11} \quad 0.5+x_{22}+t_{12}}_{0.4+x_{21}+t{21} \quad 0.4+x_{22}+t_{22}}\right) scores=(0.4+x21+t210.4+x22+t220.5+x21+t110.5+x22+t12)
更改下一次迭代的 p r e v i o u s previous previous值:
p r e v i o u s = [ max ( s c o r e s [ 00 ] , s c o r e s [ 10 ] ) , max ( s c o r e s [ 01 ] , s c o r e s [ 11 ] ) ] previous=[\max (scores[00], scores[10]),\max (scores[01],scores[11])] previous=[max(scores[00],scores[10]),max(scores[01],scores[11])]
比方说,我们在这次迭代中得到的分数是:
s c o r e s = ( 0.8 ‾ 0.7 0.6 0.9 ‾ ) scores=\left( ^{0.6 \quad \underline{0.9}}_{\underline{0.8} \quad 0.7}\right) scores=(0.80.70.60.9)
因此,我们可以获得最新的 p r e v i o u s previous previous:
p r e v i o u s = [ 0.8 , 0.9 ] previous=[0.8, 0.9] previous=[0.8,0.9]
实际上, p r e v i o u s p [ 0 ] previousp[0] previousp[0]和 p r e v i o u s [ 1 ] previous[1] previous[1]之间的较大的一个是最好的预测结果的分数。与此同时,每个标签的最大分数和索引将被添加到 a l p h a 0 alpha_0 alpha0和 a l p h a 1 alpha_1 alpha1中:
a
l
p
h
a
0
=
[
(
0.5
,
0.4
)
,
(
s
c
o
r
e
s
[
10
]
,
s
c
o
r
e
s
[
01
]
)
‾
]
alpha_0=[(0.5,0.4),\underline{(scores[10],scores[01])}]
alpha0=[(0.5,0.4),(scores[10],scores[01])]
=
[
(
0.5
,
0.4
)
,
(
0.8
,
0.9
)
‾
]
\quad \quad \quad=[(0.5,0.4),\underline{(0.8,0.9)}]
=[(0.5,0.4),(0.8,0.9)]
a
l
p
h
a
1
=
[
(
1
,
1
)
,
(
1
,
0
)
‾
]
alpha_1=[(1,1),\underline{(1,0)}]
alpha1=[(1,1),(1,0)]
第3步:找出得分最高的最佳路径
在该步骤中,
p
r
e
v
i
o
u
s
p
[
0
]
previousp[0]
previousp[0]和
p
r
e
v
i
o
u
s
[
1
]
previous[1]
previous[1]将被将被用于找到最高的分数。我们将从最后一个到第一个元素去查找最优路线。
w
1
w_1
w1 -->
w
2
w_2
w2:
首先,检查
a
l
p
h
a
0
alpha_0
alpha0和
a
l
p
h
a
1
alpha_1
alpha1最后一个元素:(0.8, 0.9)和(1, 0)。0.9是最高分数,其对应的位置是1,因此对应的标签是
l
2
l_2
l2。继续从
a
l
p
h
a
1
alpha_1
alpha1中对应位置获得
w
1
w_1
w1对应的标签索引, 即(1, 0)[1]=0。索引0表示
w
1
w_1
w1对应的标签是
l
1
l_1
l1。因此我们可以得到
w
1
−
>
w
2
w_1 -> w_2
w1−>w2的最佳路径是
l
1
−
>
l
2
l_1 -> l_2
l1−>l2。
w 0 w_0 w0 --> w 1 w_1 w1:
第二,我们继续向前移动并获得 a l p h a 1 alpha_1 alpha1的上一个元素:(1, 1)。从上面可知 w 1 w_1 w1的标签是 l 1 l_1 l1(标签对应的索引为0),因此我们可以得到 w 0 w_0 w0对应的标签索引为(1,1)[0]=1。所以我们可以得到 w 0 − > w 1 w_0 -> w_1 w0−>w1的最佳路径是 l 2 − > l 1 l_2 -> l_1 l2−>l1。
最终可以得到 w 0 − > w 1 − > w 2 w_0 -> w_1 -> w_2 w0−>w1−>w2的最佳路径是 l 2 − > l 1 − > l 2 l_2 -> l_1 -> l_2 l2−>l1−>l2
参考
[1] Lample, G., Ballesteros, M., Subramanian, S., Kawakami, K. and Dyer, C., 2016. Neural architectures for named entity recognition. arXiv preprint arXiv:1603.01360. https://arxiv.org/abs/1603.01360