【问题标题】:adding CRF layer to LSTM flattens out learning curve将 CRF 层添加到 LSTM 使学习曲线变平
【发布时间】:2020-04-06 21:39:08
【问题描述】:

我已经在带有 tensorflow 后端(tf 版本 1.13.1)的 keras 中实现了一个 bi-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 损失函数不是通过均方误差测量的?

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

【问题讨论】:

    标签: python keras deep-learning lstm crf


    【解决方案1】:

    您的网络看起来不错。
    我将尝试进行一些更改和迭代 -

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

    【讨论】:

      猜你喜欢
      • 2017-04-27
      • 2019-05-04
      • 1970-01-01
      • 2011-01-21
      • 2020-11-06
      • 2016-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多