将 CRF 层添加到 LSTM 使学习曲线变平

adding CRF layer to LSTM flattens out learning curve

我已经在 keras 中使用 tensorflow 后端(tf 版本 1.13.1)实现了一个双 LSTM 命名实体标记器。给定一个单词标记序列,网络的任务是用实体类型标签标记序列中的每个元素。随后,我在网络顶部添加了一个条件随机场 (CRF) 层;在最先进的命名实体标注器中,CRF 通常用于通过对序列中的相邻元素施加邻接约束来改进 bi-LSTM 的结果。

这是网络代码。由于数据的性质,循环执行自定义小批量训练。

from keras.models import Sequential
from keras.layers import LSTM, Dense, TimeDistributed, Bidirectional, Dropout
from keras import optimizers
from keras_contrib.layers import CRF

model = Sequential()
model.add(Bidirectional(LSTM(params['hidden_size'], return_sequences=True), input_shape=(params['max_seq_len'], params['emb_size'])))
model.add(Dropout(params['dropout']))
model.add(TimeDistributed(Dense(params['n_classes'], activation=params['activation'])))
model.add(CRF(params['n_classes'], sparse_target=True))

model.compile(loss=crf.loss_function, optimizer='sgd'), metrics=['mse']) 

for epoch in range(params['n_epochs']):

    for X,y in data:

        X = X.reshape(1, params['max_seq_len'], params['emb_size'])
        y = y.reshape(1, params['max_seq_len'], 1)

        history = model.fit(X, y, epochs=1, batch_size=params['batch_size'], verbose=1)

我希望通过添加 CRF 层来提​​高网络性能;然而,它不仅没有改善结果,而且还完全拉平了学习曲线,这是通过均方误差衡量的(在下面的均方误差底部面板图中显示,每个时期的平均值)。这令人费解,尤其是因为损失不断减少(如下面损失的顶部面板图所示,同样是每个时期的平均值)。此外,该模型在测试集上的性能降至零。

在CRF上执行有没有错误?还是因为CRF损失函数不是用均方误差来衡量的?

SO 问题中提供了可用于重现问题的模拟数据集(与此处相同的实现,但没有 CRF 层)。

您的网络看起来不错。
我会尝试的一些更改和迭代如下 -

  1. 而不是使用 mse 使用 crf_marginal_accuracy 并使用 learn_mode='marginal'.
    初始化 crf 这是因为您使用的是 NER 模型,而不是使用 one-hot 编码器作为 sparse_target=True
  2. 使用 adam 优化器,因为 sgd 在计算时不会考虑整个数据集,但是对于 TimeDistributed 模型,如果你有超过 3 个 dims,sgd 不会优化。
  3. 可能要使用 crf_loss 作为损失函数。