基于Keras实现《带CRF的层级编码器对话行为序列标注》的双向LSTM架构
基于Keras实现论文中的层级双向LSTM(Utterance压缩阶段)
我来帮你梳理如何用Keras实现这篇论文里的核心层级编码逻辑——先把每个Utterance压缩为M维向量,再以此为基础构建对话级的序列标注模型(后续衔接CRF)。
核心思路拆解
论文要求以对话为训练单位:每个对话是多轮Utterance的序列,每轮Utterance又是单词N维向量的序列。第一步的核心是对每一轮Utterance单独编码,用双向LSTM输出固定长度的M维向量,这一步可以通过Keras的TimeDistributed层实现“批量处理每个Utterance”的效果。
代码实现步骤
1. 导入依赖模块
from keras.models import Model from keras.layers import Input, Bidirectional, LSTM, TimeDistributed, Dense # 后续对接CRF需要的层(基于keras_contrib实现) from keras_contrib.layers import CRF from keras_contrib.losses import crf_loss from keras_contrib.metrics import crf_accuracy
2. 定义输入层
先明确输入数据形状:假设训练集有num_dialogues个对话,每个对话最多max_utterances轮,每轮最多max_words个单词,每个单词是N维向量。输入层定义如下:
# 输入形状:(对话数, 单对话最大轮数, 单轮最大词数, 词向量维度N) dialogue_input = Input(shape=(max_utterances, max_words, N))
3. Utterance级编码(压缩为M维向量)
用TimeDistributed把双向LSTM包裹起来,这样就能对每个对话里的每一轮Utterance单独执行编码,输出对应的M维向量:
# 方案1:双向LSTM的两个方向各输出M//2维,concat后得到恰好M维向量 utterance_encoder = TimeDistributed( Bidirectional(LSTM(units=M//2, return_sequences=False), merge_mode='concat') )(dialogue_input) # 此时utterance_encoder的形状为:(None, max_utterances, M) # 每个位置对应对话里一轮Utterance的M维压缩向量 # 方案2:如果需要先得到2*M维的双向输出,再通过Dense层压缩到M维(更灵活) # utterance_encoder = TimeDistributed( # Bidirectional(LSTM(units=M, return_sequences=False), merge_mode='concat') # )(dialogue_input) # utterance_encoder = TimeDistributed(Dense(M, activation='tanh'))(utterance_encoder)
4. 对话级编码+CRF序列标注
拿到所有Utterance的M维向量后,就可以继续构建对话级的模型,最后对接CRF层完成对话行为的序列标注(每个Utterance对应一个行为标签):
# 对话级双向LSTM:处理Utterance序列,提取上下文关联特征 dialogue_lstm = Bidirectional(LSTM(units=H, return_sequences=True))(utterance_encoder) # 对接CRF层,假设对话行为标签总数为num_labels crf_layer = CRF(num_labels) output = crf_layer(dialogue_lstm)
5. 模型编译与训练
model = Model(inputs=dialogue_input, outputs=output) # 编译模型,使用CRF专用的损失函数和评估指标 model.compile(optimizer='adam', loss=crf_loss, metrics=[crf_accuracy]) # 假设训练数据X_train(形状匹配输入层)、y_train(标签序列,形状为(None, max_utterances)) model.fit(X_train, y_train, epochs=10, batch_size=32, validation_split=0.1)
关键细节提示
- 数据预处理:必须把所有对话填充到统一的
max_utterances长度,每轮Utterance填充到统一的max_words长度,保证输入张量形状一致。 - 双向LSTM的merge_mode:除了
concat,还可以用sum、ave等方式合并双向输出,你可以根据论文里的具体描述选择。 - CRF层兼容问题:如果使用较新版本的Keras,keras_contrib可能存在兼容问题,也可以考虑替换为TensorFlow Addons中的CRF实现。
内容的提问来源于stack exchange,提问作者ilim




