如何为两级填充的LSTM-CNN二分类模型添加掩码机制?
对话级掩码传递的实现方案
1. 核心思路
你已经通过Embedding层的mask_zero=True处理了句子内填充的掩码,现在需要手动生成**对话级(utterance级)**的掩码,标记哪些utterance是填充的,再将掩码应用到utterance的特征向量上,确保后续层忽略这些无效数据。
2. 具体实现步骤
步骤1:生成对话级掩码
填充的utterance对应的文本部分全为0,通过检查text_input的词维度求和是否为0,即可生成掩码:
# 生成对话级掩码:1表示有效utterance,0表示填充utterance mask = tf.cast(tf.reduce_sum(tf.abs(text_input), axis=-1) != 0, tf.float32) # 扩展维度,匹配后续特征向量的形状([batch_size, max_conv, 1]) mask = tf.expand_dims(mask, axis=-1)
步骤2:应用掩码到utterance特征
将生成的掩码与Utterance级LSTM输出的隐藏向量相乘,把填充utterance的特征置为0:
hidden_vectors_masked = hidden_vectors * mask
步骤3:确保掩码传递到后续层
用掩码后的特征与对话行为标签拼接,后续的Conv1D和GlobalMaxPooling1D会自动忽略全0的填充utterance(因为全0序列的最大值不会影响最终结果)。
修改后的完整代码
def create_model(conv_activation='sigmoid',kernel_size=4,filters=32,learning_rate=0.0001): EMBED_SIZE = 100 EPOCHS=2 max_conv=max_conversation_length max_words=length_long_sentence BATCH_SIZE=128 total_features=input_size DA_tags_size=len(unique_tag_set) text_size=max_words DA_size=text_size+DA_tags_size ac_size=DA_size+max_acoustic_len all_input=Input(shape=(max_conv,total_features,)) text_input=tf.slice(all_input, [0,0,0], [-1, -1,text_size]) tags_input=tf.slice(all_input, [0,0,text_size], [-1, -1,DA_tags_size]) acoustic_input=tf.slice(all_input,[0,0,DA_size],[-1,-1,-1]) # 生成对话级掩码 mask = tf.cast(tf.reduce_sum(tf.abs(text_input), axis=-1) != 0, tf.float32) mask = tf.expand_dims(mask, axis=-1) # 句子内掩码由Embedding自动处理 text_emb = Embedding(vocab_size, EMBED_SIZE, weights=[embedding_matrix],input_length=max_words, name='embedding',trainable=False,mask_zero=True)(text_input) hidden_vectors=TimeDistributed(Bidirectional(LSTM(units=128, return_sequences=False)) ,name='utterance_lstm')(text_emb ) # 应用对话级掩码 hidden_vectors_masked = hidden_vectors * mask combined= Concatenate(axis=-1)([hidden_vectors_masked, tags_input]) conv_0=Conv1D(filters=filters, kernel_size=kernel_size, padding='same', activation='relu')(combined) maxpool_1=GlobalMaxPooling1D()(conv_0) out=Dense(32, activation='relu')(maxpool_1) output = Dense(units=1,kernel_regularizer=l2(0.01))(out) output=Activation(conv_activation)(output) model = Model(inputs=all_input, outputs=output) # 补充优化器定义(原代码缺失) opt = tf.keras.optimizers.Adam(learning_rate=learning_rate) losses=tf.keras.losses.BinaryCrossentropy() model.compile(optimizer=opt, loss=losses, metrics=['accuracy']) print(model.summary()) return model
关键说明
- 句子内掩码:
Embedding层的mask_zero=True已经让内部的双向LSTM自动忽略句子中的填充词,无需额外处理。 - 对话级掩码:通过文本部分的非零和判断有效utterance,将填充utterance的特征置为0后,后续的卷积和池化层会自然忽略这些无效数据。
- 补充了原代码中缺失的优化器定义,避免编译报错。
内容的提问来源于stack exchange,提问作者Aizayousaf
相关产品推荐
相关产品推荐

