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

训练TensorFlow编解码器模型时遇ValueError:输入张量数量不匹配

TensorFlow编解码器模型训练时ValueError问题排查与解决

你训练TensorFlow编解码器模型时,调用model.fit的第一个epoch就触发ValueError,错误信息如下:

Exception has occurred: ValueError
Layer "functional" expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'data:0' shape=(None, 128) dtype=float32>]
File "D:\workspace\Machine Learning 545\PSU_classes\cs445_group_project\code\Keras Music Genres Classification\encoder_decoder_feature_extractor.py", line 177, in train_encoder_decoder_model
model.fit(x = X_train,
File "D:\workspace\Machine Learning 545\PSU_classes\cs445_group_project\code\Keras Music Genres Classification\encoder_decoder_feature_extractor.py", line 217, in
trained_model = train_encoder_decoder_model(encoder_decoder_model, X_train, y_train, X_test, y_test)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Layer "functional" expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'data:0' shape=(None, 128) dtype=float32>]

模型定义代码

def define_encoder_decoder_model(num_features):
    # Define the encoder
    encoder_inputs = Input(shape=(None, num_features))
    encoder_hidden1 = Dense(100, activation='relu')(encoder_inputs)
    encoder_hidden2 = Dense(50, activation='relu')(encoder_hidden1)
    encoder_lstm = LSTM(25, return_state=True)
    encoder_outputs, state_h, state_c = encoder_lstm(encoder_hidden2)
    encoder_states = [state_h, state_c]

    # Define the decoder
    decoder_inputs = Input(shape=(None, 25))
    decoder_hidden1 = Dense(50, activation='relu')(decoder_inputs)
    decoder_hidden2 = Dense(100, activation='relu')(decoder_hidden1)
    decoder_lstm = LSTM(num_features, return_sequences=True, return_state=True)
    decoder_outputs, _, _ = decoder_lstm(decoder_hidden2, initial_state=encoder_states)
    decoder_dense = Dense(num_features, activation='softmax')
    decoder_outputs = decoder_dense(decoder_outputs)

    # Define the model that will turn encoder_inputs and decoder_inputs into decoder_outputs
    model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

    # Compile the model
    model.compile(optimizer='adam', loss='categorical_crossentropy', 
                  metrics=['accuracy', 'precision', 'recall', 'f1_score'])

    # Summary of the model
    model.summary()

    return model

训练调用代码

def train_encoder_decoder_model(model, X_train, y_train, X_test, y_test):
    """
    Trains an encoder-decoder model using the provided data.

    Args:
        model: The encoder-decoder model to train.
        X_train: The input training data.
        y_train: The target training data.
        X_test: The input test data.
        y_test: The target test data.

    Returns:
        The trained encoder-decoder model.
    """
    print("shapes: X_train:", np.shape(X_train)," y_train: ", np.shape(y_train)," X_test: ", np.shape(X_test)," y_test: ", np.shape(y_test))
    # Train the model
    # append to a file the training log for each epoch
    file_logger = FileLogger('training.log')
    y_train_T = tf.convert_to_tensor(np.array([y_train]).T)
    y_test_T = tf.convert_to_tensor(np.array([y_test]).T)
    #x_train = tf.convert_to_tensor(X_train)
    y_train = X_train
    y_test = X_test
    model.fit(x = X_train,
              y= y_train,
              batch_size=100,
              epochs=100,
              verbose=2,
              validation_data=(X_test, y_test),
              callbacks=[file_logger])
    return model

补充信息:这是一个编解码器模型,X_train与y_train相同,X_test与y_test相同。训练集形状为(799,128),测试集形状为(299,128),特征为float64类型。


错误原因

  1. 输入数量不匹配:模型通过Model([encoder_inputs, decoder_inputs], decoder_outputs)定义,明确要求接收两个输入张量(编码器输入和解码器输入),但调用model.fit时只传入了单个X_train,导致输入数量不符合模型预期。
  2. 数据维度不匹配:模型中的LSTM层要求输入为三维张量(样本数, 时间步, 特征数),但当前训练数据是二维数组(799,128),缺少时间步维度,同时解码器输入的shape=(None,25)也未对应到合理的输入数据。

解决步骤

步骤1:调整输入数据维度

为LSTM层补充时间步维度,假设每个样本的时间步为1(若128为特征数),同时构造符合解码器输入形状的张量:

# 调整编码器输入维度:(样本数, 时间步, 特征数)
X_train_enc = np.expand_dims(X_train, axis=1)  # 形状变为(799, 1, 128)
X_test_enc = np.expand_dims(X_test, axis=1)    # 形状变为(299, 1, 128)

# 构造解码器输入,匹配shape=(None,25),示例用全零张量(可根据任务逻辑替换为合理输入)
X_train_dec = np.zeros((X_train.shape[0], 1, 25))  # 形状(799,1,25)
X_test_dec = np.zeros((X_test.shape[0], 1, 25))    # 形状(299,1,25)

# 调整目标输出维度,匹配解码器输出的三维结构
y_train_target = np.expand_dims(X_train, axis=1)
y_test_target = np.expand_dims(X_test, axis=1)

步骤2:修改model.fit的输入参数

将两个输入以列表形式传入x参数,验证数据也同步调整:

def train_encoder_decoder_model(model, X_train, y_train, X_test, y_test):
    print("shapes: X_train:", np.shape(X_train)," y_train: ", np.shape(y_train)," X_test: ", np.shape(X_test)," y_test: ", np.shape(y_test))
    file_logger = FileLogger('training.log')
    
    # 调整输入和目标维度
    X_train_enc = np.expand_dims(X_train, axis=1)
    X_train_dec = np.zeros((X_train.shape[0], 1, 25))
    X_test_enc = np.expand_dims(X_test, axis=1)
    X_test_dec = np.zeros((X_test.shape[0], 1, 25))
    y_train_target = np.expand_dims(X_train, axis=1)
    y_test_target = np.expand_dims(X_test, axis=1)
    
    model.fit(x=[X_train_enc, X_train_dec],
              y=y_train_target,
              batch_size=100,
              epochs=100,
              verbose=2,
              validation_data=([X_test_enc, X_test_dec], y_test_target),
              callbacks=[file_logger])
    return model

步骤3:优化任务逻辑(可选)

如果是自编码任务,当前解码器输入shape=(None,25)的设计可能不够合理,建议调整解码器输入层形状与编码器输入一致(shape=(None, num_features)),并修改后续Dense层参数,让模型逻辑更自洽,避免使用全零输入这类临时方案。


内容的提问来源于stack exchange,提问作者elbilo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:49:54