Вопрос или проблема
Я хочу создать две параллельные модели для семантической сегментации изображений в Keras.
input1 = Input(shape=(480,480,3))
input2 = Input(shape=(480,480,1))
c1_1 = Conv2D(filters=64, kernel_size=(3,3), activation='relu', padding='same')(input1)
c1_1 = MaxPool2D(strides=(2,2))(c1_1)
c2_1 = Conv2D(filters=16, kernel_size=(3,3), activation='relu', padding='same')(input2)
c2_1 = MaxPool2D(strides=(2,2))(c2_1)
(...)
# Объединение моделей:
c = concatenate([c1_n, c2_n], axis=3)
c = UpSampling2D(size=(2,2))(c)
c = Conv2D(filters=512, kernel_size=(3,3), activation='relu', padding='same')(c)
(...)
output_layer = Conv2D(6, kernel_size=(1,1), activation='softmax')(c)
model = Model([input1, input2], output_layer)
model.compile(optimizer=Adam(2e-4), loss="categorical_crossentropy", metrics=['categorical_accuracy'])
def my_generator(x_train, y_train, batch_size):
data_generator = ImageDataGenerator(
(...).flow(x_train, x_train, batch_size, seed=42)
mask_generator = ImageDataGenerator(
(...).flow(y_train, y_train, batch_size, seed=42)
while True:
x_batch, _ = data_generator.next()
y_batch, _ = mask_generator.next()
yield [x_batch[:,:,:,:3], x_batch[:,:,:,3]], y_batch
#X = [72, 480, 480, 4]
#Y = [72, 480, 480, 5]
model.fit_generator(my_generator(X, Y, 7),
steps_per_epoch = 60,
validation_data = (X_test, Y_test),
epochs=150, verbose=2)
Но у меня ошибка:
ValueError: Ошибка при проверке входа модели: список массивов Numpy, который вы передаете модели, не соответствует ожидаемому размеру модели. Ожидалось увидеть 2 массива, но вместо этого был получен следующий список из 1 массива: [array([[[[ 0.33891213, 0.37238494, 0.33054393, 0. ],
[ 0.34728033, 0.38493724, 0.33472803, 0. ],
[ 0.35146444, 0.39330544, 0.35983264, 0. ],
....
Вы можете помочь мне с моей ошибкой или сказать, правильна ли эта предположение?
Это, вероятно, уже устаревший вопрос, но на случай, если кто-то другой столкнется с проблемой, посмотрите по эту ссылку.
В основном, ваша модель ожидает два входа, как здесь определено:
model = Model([input1, input2], output_layer)
Поэтому вам нужно передать список из двух входов той же формы, что вы определили здесь:
input1 = Input(shape=(480,480,3))
input2 = Input(shape=(480,480,1))
Ответ или решение
Чтобы создать две параллельные модели для семантической сегментации в Keras, как указано в вашем вопросе, необходимо правильно настроить архитектуру модели и обработку данных. Ваша первоначальная идея является хорошей, но, как указывает ошибка, вы передаете неправильное количество входных данных в модель. Давайте разберемся подробнее по шагам.
1. Архитектура модели
В вашем примере вы создаете две отдельные входные точки: input1
, которая принимает изображения с тремя каналами (например, RGB), и input2
, которая принимает изображения с одним каналом (например, маски). Обратите внимание, что нужно убедиться, что количество данных, которые вы передаете в модель, соответствует количеству ожидаемых входов.
Пример создания модели с двумя параллельными входами выглядит следующим образом:
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, concatenate
from keras.models import Model
from keras.optimizers import Adam
# Определение входов
input1 = Input(shape=(480, 480, 3))
input2 = Input(shape=(480, 480, 1))
# Модель для первого входа
c1_1 = Conv2D(filters=64, kernel_size=(3,3), activation='relu', padding='same')(input1)
c1_1 = MaxPooling2D(strides=(2,2))(c1_1)
# Модель для второго входа
c2_1 = Conv2D(filters=16, kernel_size=(3,3), activation='relu', padding='same')(input2)
c2_1 = MaxPooling2D(strides=(2,2))(c2_1)
# Объединение моделей
c = concatenate([c1_1, c2_1], axis=-1) # Используйте axis=-1 для объединения по каналам
c = UpSampling2D(size=(2, 2))(c)
c = Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same')(c)
# Выходной слой
output_layer = Conv2D(6, kernel_size=(1, 1), activation='softmax')(c)
# Создание модели
model = Model(inputs=[input1, input2], outputs=output_layer)
# Компиляция модели
model.compile(optimizer=Adam(learning_rate=2e-4), loss="categorical_crossentropy", metrics=['categorical_accuracy'])
2. Генератор данных
При создании генератора данных для передачи входных данных в модель важно, чтобы он возвращал именно два массива, что соответствует вашим входным данным. Ваша функция-генератор имеет правильный подход, но вам нужно модифицировать возврат данных, чтобы корректно обрабатывать массивы.
Пример функции-генератора:
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
def my_generator(x_train, y_train, batch_size):
data_generator = ImageDataGenerator().flow(x_train, batch_size=batch_size, seed=42)
mask_generator = ImageDataGenerator().flow(y_train, batch_size=batch_size, seed=42)
while True:
x_batch = data_generator.next() # Извлекаем батч изображений
y_batch = mask_generator.next() # Извлекаем батч масок
# Возвращаем массив, содержащий два входа
yield [x_batch[:,:,:,:3], x_batch[:,:,:,3:]], y_batch # Убедитесь, что y_batch имеет размерность (batch_size, 480, 480, num_classes)
# Подготовка и запуск модели
model.fit(my_generator(X, Y, batch_size=7),
steps_per_epoch=60,
validation_data=(X_test, Y_test),
epochs=150, verbose=2)
3. Устранение ошибок
Ошибка, которую вы получаете (ValueError
), указывает на то, что вы передаете не два массива, как ожидает ваша модель. Убедитесь, что в вызове model.fit
вы передаете правильно структурированный массив из двух входных данных, соответствующих input1
и input2
.
Заключение
Следуя вышеизложенным рекомендациям, вы сможете создать параллельные модели для семантической сегментации в Keras. Важно тщательно проверять структуру данных, которые передаются в модель, чтобы избегать возможных ошибок. Команда Keras изначально не позволяет автоматизированно обрабатывать входные данные, поэтому ясность в структуре входных и выходных массивов является критически важным аспектом при обучении. Удачи в вашей разработке!