You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>]


报错原因

  1. 首次报错:fit()仅传入了模型的输入数据,未提供训练所需的目标标签,而categorical_crossentropy损失要求必须明确传入目标值。
  2. 更新后报错: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:01:02