Две параллельные модели для семантической сегментации в Keras

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

Я хочу создать две параллельные модели для семантической сегментации изображений в 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 изначально не позволяет автоматизированно обрабатывать входные данные, поэтому ясность в структуре входных и выходных массивов является критически важным аспектом при обучении. Удачи в вашей разработке!

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

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