论文笔记:End

今天来将一些 End-to-end Sequence Labeling via Bi-directional LSTM-CNN-CRF 这篇文章吧,这是一篇CMU的工作。简单来说就是用一个完全End-to-end的模型来解决sequence labeling的问题,在NER和POStagging的问题上做了测试,达到了state-of-the-art,亮点在于不需要繁琐的feature engineering了。

Introduction

在Introduction中,作者就大概阐述了整个End-to-end model的architecture。

We first use convolutional
neural networks (CNNs) (LeCun et al.,
1989) to encode character-level information of a
word into its character-level representation. Then
we combine character- and word-level representations
and feed them into bi-directional LSTM
(BLSTM) to model context information of each
word. On top of BLSTM, we use a sequential
CRF to jointly decode labels for the whole sentence.

用CNN去得到char-level representation,然后结合char-level和word-level(word vectors)输入一个Bi-LSTM在建模上下文信息,最后我们再用一个sequential的CRF去decode label。

Model Architecture

CNN for char-level representation

为什么我们需要CNN来encode char-level的信息?因为char-level可以比较好的表示一些词的一些构词特性。比如一些前缀后缀,pre-,post-,un-,im,或者ing、ed等等。

基本的结构和图像的有

分享一个github里面开源的Keras实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def (self):
"""
Build and compile the Character Level CNN model
Returns: None
"""
inputs = Input(shape=(self.input_size,), name='sent_input', dtype='int64')
# Embedding layers
x = Embedding(self.alphabet_size + 1, self.embedding_size, input_length=self.input_size)(inputs)
# Convolution layers
for cl in self.conv_layers:
x = Convolution1D(cl[0], cl[1])(x)
x = ThresholdedReLU(self.threshold)(x)
if cl[2] != -1:
x = MaxPooling1D(cl[2])(x)
x = Flatten()(x)
# Fully connected layers
for fl in self.fully_connected_layers:
x = Dense(fl)(x)
x = ThresholdedReLU(self.threshold)(x)
x = Dropout(self.dropout_p)(x)
# Output layer
predictions = Dense(self.num_of_classes, activation='softmax')(x)
# Build and compile model
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer=self.optimizer, loss=self.loss)
self.model = model
print("CharCNNZhang model built: ")
self.model.summary()

参考https://github.com/chaitjo/character-level-cnn/blob/master/models/char_cnn_zhang.py

CharCNN的其他的一些原理以及技术分享

https://blog.csdn.net/liuchonge/article/details/70947995

BI-LSTM to Encode Context Information

LSTM unit不需要过多介绍了,简单来说通过构造一个gradient的highway以及与forget、output、input gate之间的互动来解决一部分vanishing gradient的问题。

至于Bidirectional RNN,https://www.youtube.com/watch?v=uRFegQXnY54

这个有介绍。因为LSTM只能通过过去predict未来,但是有的时候我们也需要知道句子后面的context,这个时候用Bi-directional RNN会有不错的效果。

Bi-directional RNN 用人话来讲就是,除了forward的一个LSTM,再加一个backward的LSTM,神经网络的forward pass就是上图中紫色的$a^{<1>},a^{<2>},a^{<3>},a^{<4>}$,然后绿色的$a^{<4>},a^{<3>},a^{<2>},a^{<1>}$,backward pass就是反过来。最后每一个time slot都会得到两个hidden state,一个紫色的一个绿色的,一般来说把他们的表示concat然后输入一个activation function(比如softmax)或者当做feature输入别的判别函数即可。

CRF

我们融合了char、word-level的representation,再加上了context information,通过Bi-LSTM得到了一个隐藏层的表示。接下来我们将这个表示输入一个CRF进行predict。
我们令$z = {z_1, cdots, z_n }$表示我们之前影藏层得到的vector(feature vector)
我们用$y = { y_1, cdots, y_n }$表示我们生成的对应的每一个label
我们用$Y(z)$来表示可能的label的集合。
所以我们的条件概率可以这样表示$P(y | z; W,b)$

最后训练的目标就是得到最大的Maximum Likelihood
$L(W,b) = sum_i log p(y | z; W,b)$
最后在做Decoding的时候我们只要search label sequence $y^{star}$,是的他条件概率最大就可以了!
$y^{star} = argmax_{y in Y(z)} p(y | z; W, b)$

最后整体的模型