TensorFlow编码器-解码器RNN出现x==y断言失败InvalidArgumentError报错
报错原因
核心原因是你向tfa.seq2seq.BasicDecoder传入sequence_length参数后,解码器默认会开启自动截断逻辑:输出的rnn_output会自动对齐到当前批次内最大的序列长度,而非和decoder输入的固定长度对齐。
从报错信息可以看到,当前训练批次内最长的序列长度为4,因此解码器输出的预测结果维度为[32, 4, target_vocab_size],但你传入的标签y_train固定填充到了7位,维度为[32, 7],二者维度不匹配触发了损失函数的断言报错。
解决方法
推荐采用以下方案处理:
方案1(最常用):关闭解码器自动截断,手动实现掩码损失
首先在调用解码器时添加impute_finished=False参数,强制解码器输出和decoder输入长度一致的结果:final_outputs, final_state, final_sequence_lengths = decoder( decoder_embeddings, initial_state=encoder_state, sequence_length=sequence_lengths, impute_finished=False)然后自定义掩码损失函数,计算损失时自动忽略填充位置的误差:
def masked_sparse_categorical_crossentropy(y_true, y_pred): # 生成掩码,真实序列位置为1,填充位置为0 mask = tf.sequence_mask(sequence_lengths, maxlen=tf.shape(y_true)[1], dtype=tf.float32) # 计算原始损失 loss = tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred) # 应用掩码 loss = loss * mask # 返回平均损失(仅计算真实序列位置) return tf.reduce_sum(loss) / tf.reduce_sum(mask)编译模型时使用该自定义损失即可:
model.compile(optimizer="adam", loss=masked_sparse_categorical_crossentropy)方案2:对齐标签和输出维度
如果你需要保留解码器的自动截断逻辑,需要在训练时将每个批次的y_train同步截断到当前批次的最大sequence_length值,保证标签和预测结果的维度一致。该方案需要自定义训练循环,实现成本高于方案1。
额外建议检查seq_length数组的取值是否正确,确保所有值都不超过y_train的最大填充长度7,避免出现其他维度异常。
内容的提问来源于stack exchange,提问作者jda5
相关产品推荐
相关产品推荐

