Ошибка работы с несколькими входами Keras при передаче словаря в model.fit

Вопрос или проблема

Я работаю над моделью с несколькими входами и выходами. Передача выходов в model.fit в виде словаря работает хорошо, но если я хочу сделать то же самое с входами, я всегда получаю следующую ошибку:

Недопустимая форма ввода для входного тензора("data_1:0", форма=(None, 48, 2), dtype=float32). Ожидаемая форма (None, 1), но вход имеет несовместимую форму (None, 48, 2)

Аргументы, полученные от Functional.call():
  • inputs={'Linear_inputs': 'tf.Tensor(shape=(None, 1), dtype=float32)', 'LSTM_inputs': 'tf.Tensor(shape=(None, 48, 2), dtype=float32)'}
  • training=True
  • mask={'Linear_inputs': 'None', 'LSTM_inputs': 'None'}

Процесс завершился с кодом 1

Мой код для построения и обучения:

#входные слои
Linear_inputs = tf.keras.layers.Input(shape=(1,), name="Linear_inputs")
LSTM_inputs = tf.keras.layers.Input(shape=(step_size, 2), name="LSTM_inputs")

#общий путь
#x = tf.keras.layers.LSTM(50, activation='tanh', return_sequences=True)(inputs)
#x = tf.keras.layers.Dropout(0.1)(x)
#x = tf.keras.layers.Dense(100, activation='relu')(inputs)
#x = tf.keras.layers.Dropout(0.1)(x)

#ветка скорости ротора
rpm = tf.keras.layers.Dense(4, activation='tanh', kernel_regularizer="l1l2", kernel_initializer="he_uniform")(Linear_inputs)
Y_rpm = tf.keras.layers.Dense(1, activation='sigmoid', name="Y_rpm", kernel_regularizer="l1l2", kernel_initializer="he_uniform")(rpm)

#ветка активной мощности
kW = tf.keras.layers.LSTM(40, activation='tanh', kernel_regularizer="l2", kernel_initializer="RandomNormal")(LSTM_inputs)
kW = tf.keras.layers.Dropout(0.1)(kW)
kW = tf.keras.layers.Dense(30, activation='tanh')(kW)
kW = tf.keras.layers.Dropout(0.1)(kW)
Y_kW = tf.keras.layers.Dense(1, activation='sigmoid', name="Y_1_C")(kW)

#ветка температуры переднего подшипника
f_C = tf.keras.layers.LSTM(40, activation='tanh', kernel_regularizer="l2", kernel_initializer="RandomNormal")(LSTM_inputs)
f_C = tf.keras.layers.Dropout(0.1)(f_C)
f_C = tf.keras.layers.Dense(30, activation='tanh')(f_C)
f_C = tf.keras.layers.Dropout(0.1)(f_C)
Y_f_C = tf.keras.layers.Dense(1, activation='sigmoid', name="Y_2_C")(f_C)

#ветка температуры заднего подшипника
r_C = tf.keras.layers.LSTM(40, activation='tanh', kernel_regularizer="l2", kernel_initializer="RandomNormal")(LSTM_inputs)
r_C = tf.keras.layers.Dropout(0.1)(r_C)
r_C = tf.keras.layers.Dense(30, activation='tanh')(r_C)
r_C = tf.keras.layers.Dropout(0.1)(r_C)
Y_r_C = tf.keras.layers.Dense(1, activation='sigmoid', name="Y_O_C")(r_C)

#создание модели и оптимизатора
gearing_model = tf.keras.Model(inputs=[Linear_inputs, LSTM_inputs], outputs=[Y_rpm, Y_kW, Y_f_C, Y_r_C])

optimizer = Adam(learning_rate=0.0001)
#optimizer = Adam(learning_rate=0.00001)

#определение потерь
losses = {"Y_rpm": "mse", "Y_1_C": "mse", "Y_2_C": "mse", "Y_O_C": "mse"}
lossWeights = {"Y_rpm": 1.0, "Y_1_C": 1.0, "Y_2_C": 1.0, "Y_O_C": 1.0}

#компиляция модели
gearing_model.compile(optimizer=optimizer, loss=losses, loss_weights=lossWeights, metrics=["mse", "mse", "mse", "mse"])

reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor="loss", factor=0.5, patience=3)

print(gearing_model.summary())

print(X_train_1_lin.shape)
print(X_train_1_lstm.shape)

history0 = gearing_model.fit({"Linear_inputs": X_train_1_lin, "LSTM_inputs": X_train_1_lstm},
                    {"Y_rpm": Y_train_1_lin, "Y_1_C": Y_train_1_lstm[:, 0], "Y_2_C": Y_train_1_lstm[:, 1], "Y_O_C": Y_train_1_lstm[:, 2]},
                    epochs=30, batch_size=128, callbacks=reduce_lr, shuffle=False)


history1 = gearing_model.fit([X_train_2_lin, X_train_2_lstm],
                    {"Y_rpm": Y_train_2_lin, "Y_1_C": Y_train_2_lstm[:, 0], "Y_2_C": Y_train_2_lstm[:, 1], "Y_O_C": Y_train_2_lstm[:, 2]},
                    epochs=30, batch_size=128, callbacks=reduce_lr, shuffle=False)

history2 = gearing_model.fit([X_train_3_lin, X_train_3_lstm],
                    {"Y_rpm": Y_train_3_lin, "Y_1_C": Y_train_3_lstm[:, 0], "Y_2_C": Y_train_3_lstm[:, 1], "Y_O_C": Y_train_3_lstm[:, 2]},
                    epochs=30, batch_size=128, callbacks=reduce_lr, shuffle=False)

Я использую Python 3.12 и Keras 3.4.0.

Передача входов, как это сделано в history1 и history2, работает, но словарь в history0 не работает. У меня нет проблем с выходами. Если я поменяю X_train_1_lin на X_train_1_lstm, это сработает – но я не могу найти причину. Любые предложения приветствуются!

Попробуйте определить ваши входы модели как словарь:

tf.keras.Model(inputs={"Linear_inputs":Linear_inputs, "LSTM_inputs":LSTM_inputs], outputs=[Y_rpm, Y_kW, Y_f_C, Y_r_C])

Ссылка:
https://github.com/keras-team/keras/issues/20136

Ответ или решение

Решение проблемы с несколькими входами в Keras при использовании словаря в model.fit

При работе с нейронными сетями в Keras, особенно при использовании нескольких входов и выходов, важно правильно передавать данные в модель. В данном случае возникла ошибка при попытке передать входные данные в формате словаря во время обучения модели. Рассмотрим детали проблемы и пути её решения.

Описание проблемы

Вы столкнулись с ошибкой, связанной с несовпадением форматов входных данных:

Invalid input shape for input Tensor("data_1:0", shape=(None, 48, 2), dtype=float32). Expected shape (None, 1), but input has incompatible shape (None, 48, 2)

Это сообщение указывает на то, что первый вход вашей модели ожидает данные с формой (None, 1), тогда как по факту передается массив с формой (None, 48, 2) для другого входа, что, в свою очередь, приводит к несовпадению.

Причины ошибки

  1. Структура ввода: Когда вы вызываете gearing_model.fit(), Keras ожидает, что входные данные будут переданы в соответствии с определенной структурой. Когда вы передаете данные в виде словаря, важно, чтобы ключи словаря соответствовали именам входов, определенным при создании модели.

  2. Неправильная или неполная передача данных: Поскольку код работает в случае вызова model.fit() с массивами, но не со словарем, проблема может заключаться в несоответствии между названиями входов и фактическими массивами данных.

Решение проблемы

  1. Определите входные данные в словаре: Попробуйте инициализировать модель, используя словарь для входных данных. Это обеспечивает более явную связь между именами входов и самими данными.

    Пример:

    inputs = {
       "Linear_inputs": Linear_inputs,
       "LSTM_inputs": LSTM_inputs
    }
    gearing_model = tf.keras.Model(inputs=inputs, outputs=[Y_rpm, Y_kW, Y_f_C, Y_r_C])
  2. Проверка данных: Убедитесь, что массивы, передаваемые в model.fit(), имеют соответствующие размеры. Например:

    print("Форма линейных данных:", X_train_1_lin.shape)  # Должно быть (num_samples, 1)
    print("Форма LSTM данных:", X_train_1_lstm.shape)      # Должно быть (num_samples, 48, 2)
  3. Использование отметки имен входов: При вызове fit, передавайте данные как словарь, где ключи соответствуют именам входов:

    history0 = gearing_model.fit(
       {"Linear_inputs": X_train_1_lin, "LSTM_inputs": X_train_1_lstm},
       {
           "Y_rpm": Y_train_1_lin, 
           "Y_1_C": Y_train_1_lstm[:, 0], 
           "Y_2_C": Y_train_1_lstm[:, 1], 
           "Y_O_C": Y_train_1_lstm[:, 2]
       },
       epochs=30,
       batch_size=128,
       callbacks=reduce_lr,
       shuffle=False
    )

Заключение

Использование модели с несколькими входами требует четкого определения форматов входных и выходных данных. Применяя подход с использованием словаря при передаче данных, вы можете облегчить процесс и избежать несовпадений. Внимательно проверяйте размеры и названия ваших массивов данных. Это поможет вам успешно обучить вашу модель без ошибок.

Оцените материал
Добавить комментарий

Капча загружается...