Keras Transformer训练报错:目标数据缺失与输入不匹配求助
Keras Transformer双语文本翻译模型训练报错解决
问题详情
在构建Keras Transformer双语文本翻译模型时,训练阶段出现报错,代码及报错信息如下:
训练代码
import numpy as np import tensorflow as tf from tensorflow import keras import keras_nlp xLines = np.genfromtxt('data-1.ar', dtype='str', delimiter=',') yLines = np.genfromtxt('data-1.en', dtype='str', delimiter=',') vectorize_layer = TextVectorization( standardize=custom_standardization, max_tokens=maxTokens, split="whitespace", ngrams=None, output_mode="int", output_sequence_length=outputLength ) vectorize_layer.adapt(vocab_data) def vectorize_text(text): text = tf.expand_dims(text, -1) return vectorize_layer(text) arDataset = vectorize_text(xLines) enDataset = vectorize_text(yLines) print(arDataset.shape) # 输出(99, 22) print(enDataset.shape) # 输出(99, 22) # 编码器部分 encoder_inputs = keras.Input(shape=(None,), dtype="int64", name="encoder_inputs") x = keras_nlp.layers.TokenAndPositionEmbedding( vocabulary_size=maxTokens, sequence_length=outputLength, embedding_dim=EMBED_DIM, mask_zero=True, )(encoder_inputs) encoder_outputs = keras_nlp.layers.TransformerEncoder( intermediate_dim=INTERMEDIATE_DIM, num_heads=NUM_HEADS )(inputs=x) encoder = keras.Model(encoder_inputs, encoder_outputs) # 解码器部分 decoder_inputs = keras.Input(shape=(None,), dtype="int64", name="decoder_inputs") encoded_seq_inputs = keras.Input(shape=(None, EMBED_DIM), name="decoder_state_inputs") x = keras_nlp.layers.TokenAndPositionEmbedding( vocabulary_size=maxTokens, sequence_length=outputLength, embedding_dim=EMBED_DIM, mask_zero=True, )(decoder_inputs) x = keras_nlp.layers.TransformerDecoder( intermediate_dim=INTERMEDIATE_DIM, num_heads=NUM_HEADS )(decoder_sequence=x, encoder_sequence=encoded_seq_inputs) x = keras.layers.Dropout(0.5)(x) decoder_outputs = keras.layers.Dense(enChars, activation="softmax")(x) decoder = keras.Model( [decoder_inputs, encoded_seq_inputs], decoder_outputs, ) decoder_outputs = decoder([decoder_inputs, encoder_outputs]) # 构建Transformer模型 transformer = keras.Model( [encoder_inputs, decoder_inputs], decoder_outputs, name="transformer", ) transformer.summary() transformer.compile( "rmsprop", loss="categorical_crossentropy", metrics=["accuracy"] ) transformer.fit([arDataset,enDataset], epochs=100)
首次报错
ValueError: Target data is missing. Your model was compiled with loss=categorical_crossentropy, and therefore expects target data to be provided in
fit().
更新尝试后的报错
修改fit参数为以下两种形式后:
transformer.fit(arDataset,enDataset, epochs=100) transformer.fit(x=arDataset,y=enDataset, epochs=100)
仍报错:
ValueError: Layer "transformer" expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, 22) dtype=int64>]
报错原因
- 首次报错:
fit()仅传入了模型的输入数据,未提供训练所需的目标标签,而categorical_crossentropy损失要求必须明确传入目标值。 - 更新后报错:Transformer模型需要两个输入(编码器的阿语输入、解码器的英语输入),但调用
fit时仅传入了一个输入给x参数;同时目标标签为整数格式,与categorical_crossentropy要求的one-hot编码不匹配。
修复步骤
1. 调整训练数据的输入与目标格式
Transformer训练时,解码器输入和目标序列需要错位处理(避免模型直接看到完整答案):
# 解码器输入:去掉英语序列的最后一个token decoder_input_data = enDataset[:, :-1] # 目标标签:去掉英语序列的第一个token target_data = enDataset[:, 1:]
2. 修正损失函数
由于目标标签是整数类型,改用SparseCategoricalCrossentropy替代categorical_crossentropy,无需提前做one-hot转换:
transformer.compile( optimizer="rmsprop", loss=keras.losses.SparseCategoricalCrossentropy(from_logits=False), metrics=["accuracy"] )
注:如果后续去掉解码器输出层的
softmax激活,需将from_logits设为True,数值计算更稳定。
3. 正确调用fit方法
传入模型所需的两个输入,以及处理后的目标标签:
transformer.fit( x=[arDataset, decoder_input_data], y=target_data, epochs=100 )
额外优化建议
- 分离双语词汇表:当前代码用同一个
TextVectorization层处理阿语和英语,会导致词汇混淆,建议为两种语言分别创建TextVectorization层,各自适配对应语料。 - 添加特殊标记:训练时建议在英语序列开头添加
<start>标记、结尾添加<end>标记,让模型更清晰地识别序列边界,提升翻译效果。
内容的提问来源于stack exchange,提问作者webber
相关产品推荐
相关产品推荐

