英乌尔都语注意力翻译模型训练损失函数维度不匹配问题求助
英-乌尔都语注意力翻译模型:维度匹配问题解决方案
核心问题拆解
你的Seq2Seq注意力模型当前的输出结构和目标序列形状不兼容:
- 模型通过循环生成19个独立输出张量(对应乌尔都语序列长度Ty=19),每个张量形状为
(batch_size, 5930)(目标词汇量) - 目标序列
train_urdu_seq是二维数组(19620,19),Keras无法自动将其与多输出列表匹配,导致维度不匹配错误
错误logits and labels must have the same first dimension, got logits shape [100,5930] and labels shape [1900]的本质是:Keras误将(100,19)的目标序列当成了单输出的标签张量,而模型每个输出需要的是(100,)的单步标签。
两种可行修复方案
方案1:合并模型输出为单个张量(推荐)
把循环中生成的19个输出张量拼接成一个三维张量,让输出形状(batch_size, Ty, vocab_size)直接匹配目标序列的(batch_size, Ty)结构,完美适配sparse_categorical_crossentropy。
修改模型构建函数的输出部分:
def modelf(Tx,Ty,n_a, n_s, total_eng_vocab, total_urdu_vocab): X=Input(shape=(english_length,)) s0 = Input(shape=(n_s,), name='s0') c0 = Input(shape=(n_s,), name='c0') s=s0 c=c0 outputs = [] embedding_layer=tf.keras.layers.Embedding(total_eng_vocab,64,input_length=english_length)(X) a = Bidirectional(LSTM(n_a,return_sequences=True))(embedding_layer) for t in range(Ty): context=one_step_attention(a,s) _,s,c=post_activation_LSTM_cell(context,initial_state = [s,c] ) out = output_layer(s) outputs.append(out) # 关键修改:将输出列表拼接为三维张量 outputs = tf.stack(outputs, axis=1) # 拼接后形状为(m, 19, 5930) model=tf.keras.models.Model(inputs=[X,s0,c0],outputs=outputs) return model
修改后,模型输出与目标序列维度完全对齐,无需改动model.compile和model.fit代码即可正常训练。
方案2:拆分目标序列为列表形式
如果要保留模型的多输出列表结构,需要把目标序列拆分为19个单步标签的列表,每个列表元素对应模型的一个输出:
# 将目标序列拆分为19个形状为(19620,)的张量 targets = [train_urdu_seq[:, t] for t in range(Ty)] # 训练时传入拆分后的目标列表 model.compile(loss = 'sparse_categorical_crossentropy', optimizer = opt, metrics = ['accuracy']) model.fit([train_eng_seq, s0, c0], targets, epochs=50, batch_size=100)
额外优化建议
- 损失过高问题:独热编码会大幅增加计算开销,且
categorical_crossentropy在大词汇量场景下数值不稳定,优先使用sparse_categorical_crossentropy。 - 学习率调整:当前Adam学习率0.005偏高,建议先降至0.001,避免模型训练初期震荡。
- 注意力softmax轴验证:确认自定义
softmax(axis=1)的合理性——如果a的形状为(batch_size, Tx, 2*n_a),该轴设置正确(对输入序列位置归一化)。
内容的提问来源于stack exchange,提问作者Ahmad SARMAD ALI
相关产品推荐
相关产品推荐

