Вопрос или проблема
Я пытаюсь подать последовательную модель по батчам. Для воспроизводимости моего примера предположим, что мои данные следующие:
X=np.random.rand(24,432)
Y=np.random.rand(24,432)
Моя цель – подавать модель по батчам. 24 точки за раз (вектор 24 x 1), 432 раза.
Я построил свою модель следующим образом:
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=12)
model = keras.Sequential([
keras.layers.Flatten(input_shape=(1,)),
keras.layers.Dense(64, activation=tf.nn.relu),
keras.layers.Dense(32, activation=tf.nn.relu),
keras.layers.Dropout(0.25),
keras.layers.Dense(2, activation=tf.nn.sigmoid),
])
model.compile(optimizer="adam",
loss="binary_crossentropy",
metrics=['accuracy'])
#train_generator = batch_generator(X_train, y_train, 12)
history=model.fit(X_train, y_train, epochs=200, batch_size=12, validation_split=0.3)
early_stopping_monitor = EarlyStopping(patience=100)
history=model.fit_generator(train_generator,epochs=20)
test_loss, test_acc = model.evaluate(X_test, y_test)
print('Потеря модели:',test_loss, 'Точность модели: ',test_acc)
Однако я получаю эту ошибку:
WARNING:tensorflow:Модель была сконструирована с формой (None, 1) для ввода KerasTensor(type_spec=TensorSpec(shape=(None, 1), dtype=tf.float32, name="flatten_24_input"), name="flatten_24_input", description="созданный слоем 'flatten_24_input'"), но была вызвана с вводом с несовместимой формой (None, 432)
ИЗМЕНЕНИЕ:
X=np.array(X[0:10368]).reshape(24,432)
Y=np.array(Y[0:10368]).reshape(24,432)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=12)
model = keras.Sequential([
keras.layers.Flatten(batch_input_shape=(None, 432, 2)),
keras.layers.Dense(64, activation=tf.nn.relu),
keras.layers.Dense(2, activation=tf.nn.sigmoid),
])
model.compile(optimizer="adam",
loss="binary_crossentropy",
metrics=['accuracy'])
history=model.fit(X_train, y_train, epochs=200, batch_size=32, validation_split=0.3)
test_loss, test_acc = model.evaluate(X_test, y_test)
print('Потеря модели:',test_loss, 'Точность модели: ',test_acc)
СЕЙЧАС ВЫДАЕТ:
ValueError: Вход 0 слоя dense_17 несовместим со слоем: ожидался ось -1 формы ввода с значением 864, но получен ввод с формой (None, 432)
Основная проблема здесь заключается в том, что ваши метки – Y, которые вы инициализируете случайным образом в начале, имеют размерность 432, в то время как ваш конечный слой имеет размерность 2, и вы используете бинарную кросс-энтропию. Это означает, что вы пытаетесь предсказать вектор размерности 432 как бинарную классификацию.
Но это не причина, по которой вы получаете сообщение об ошибке. Чтобы исправить ошибку, вы можете использовать batch_input_shape(None, 432, 1)
вместо input_shape(1, )
. Как только вы исправите это, вы получите ошибку значения:
ValueError: логиты и метки должны иметь одну и ту же форму ((None, 2) против (None, 432))
Что, в свою очередь, исправляется описанным выше способом.
Ответ или решение
Для обучения модели Keras в пакетном режиме (batch mode) следует учитывать множество важных аспектов, чтобы избежать ошибок и обеспечить правильность процесса обучения. Ваша цель заключается в том, чтобы модель обрабатывала 24 точки за раз (или 24 x 1 вектор), повторяя этот процесс 432 раза. Давайте детально рассмотрим Ваш пример и ключевые шаги, которые необходимо выполнить, чтобы успешно интегрировать подачу данных в пакетах в Keras.
Шаг 1: Подготовка данных
Ваша изначальная форма данных нескольких массивов, которая задана следующим образом:
X = np.random.rand(24, 432)
Y = np.random.rand(24, 432)
Однако, подобная структура затрудняет работу с моделью, поскольку при обучении модель ожидает данные в определенном формате. После выполнения reshaping ("изменения формы") массива X
и Y
, вы можете сделать следующее:
X = np.random.rand(10368).reshape(-1, 432) # Теперь 24 точки по 432 значения
Y = np.random.rand(10368).reshape(-1, 432)
Таким образом, Вы получите 24 примера, каждый из которых представляет собой 432 значения.
Шаг 2: Создание модели
Создайте последовательную модель с использованием Keras, которая будет соответствовать размерности Ваших данных. Наиболее важной частью является использование подходящей конфигурации для входных данных:
model = keras.Sequential([
keras.layers.Flatten(input_shape=(432,)), # Мы ожидаем 432 элемента на каждой итерации
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(32, activation='relu'),
keras.layers.Dropout(0.25),
keras.layers.Dense(432, activation='sigmoid') # Финальный слой должен соответствовать размеру Y
])
Шаг 3: Компиляция модели
Компилируйте модель, выбрав подходящие параметры:
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
Шаг 4: Подача данных в модель
Модель можно обучать как обычным образом, используя fit
, так и с помощью генераторов. Если вы хотите использовать пакетную подачу данных, вам потребуется создать генератор:
def data_generator(X, Y, batch_size):
while True:
for start in range(0, len(X), batch_size):
end = min(start + batch_size, len(X))
yield X[start:end], Y[start:end]
Теперь вы можете использовать этот генератор в fit_generator
:
batch_size = 12
train_generator = data_generator(X_train, y_train, batch_size)
history = model.fit(train_generator, steps_per_epoch=len(X_train) // batch_size, epochs=200, validation_split=0.3)
Шаг 5: Оценка модели
По завершении тренировки, вы можете оценить свою модель, используя тестовую выборку:
test_loss, test_acc = model.evaluate(X_test, y_test)
print('Модель потерь:', test_loss, 'Точность модели:', test_acc)
Заключение
Ваша исходная проблема связана с неправильным определением структуры входных данных и несоответствующими размерами выходных данных. Настраивая модель в соответствии с размерами ваших массивов и используя генераторы для пакетной подачи данных, Вы сможете эффективно обучать свою модель и минимизировать вероятность ошибок. Не забывайте тестировать и валидировать модель для достижения более высокой точности и надежности.