Как совместить две предварительно подготовленные модели в керасе? - PullRequest
0 голосов
/ 23 октября 2019

Я хотел бы объединить две модели с предварительной подготовкой (DenseNet169 и InceptionV3), или это могут быть любые две. Следовали инструкциям по следующей ссылке, но не сработало. Попробовал и конкатенацию, и конкатенацию, все равно получая ошибку. Я мог где-то ошибиться. Это мой первый вопрос от stackoverflow, и помощь будет принята с благодарностью. https://datascience.stackexchange.com/questions/39407/how-to-make-two-parallel-convolutional-neural-networks-in-keras Первый случай: я пытался без пула

model1 = DenseNet169(weights='imagenet', include_top=False, input_shape=(300,300,3))
out1 = model1.output    

model2 = InceptionV3(weights='imagenet', include_top=False, input_shape=(300,300,3))
out2 = model2.output

from keras.layers import concatenate 
from keras.layers import Concatenate 

x = concatenate([out1, out2])  # merge the outputs of the two   models
out = Dense(10, activation='softmax')(x)  # final layer of the network

Я получил эту ошибку:

ValueError: Для слоя Concatenate требуются входные данные с соответствующими формами, за исключением конкатось. Получил входные формы: [(Нет, 9, 9, 1664), (Нет, 8, 8, 2048)]

Второй случай: пробовал со средним пулом, мог объединить, но получил ошибку в процессе обучения

model1 = DenseNet169(weights='imagenet', include_top=False, pooling='avg', input_shape=(300,300,3))
out1 = model1.output   

model2 = InceptionV3(weights='imagenet', include_top=False, pooling='avg', input_shape=(300,300,3))
out2 = model2.output

x = concatenate([out1, out2])  # merge the outputs of the two models
out = Dense(10, activation='softmax')(x)  # final layer of the network

model = Model(inputs=[model1.input, model2.input], outputs=[out])

model.compile(optimizer=Adam(), loss='categorical_crossentropy',metrics=['accuracy'])
history = model.fit_generator(generator=data_generator_train,
                          validation_data=data_generator_val,
                          epochs=20,
                          verbose=1
                         )

Ошибка во втором случае: ValueError: Ошибка при проверке ввода модели: список массивов Numpy, передаваемых в вашу модель, не соответствует размеру, ожидаемому моделью. Ожидается увидеть 2 массива (ов), но вместо этого получен следующий список из 1 массива: [array ([[[[0.17074525, 0.10469133, 0.08226486], [0.19852941, 0.13124999, 0.11642157], [0.36528033, 0.3213197, 0.3085095],. .., [0.19082414, 0.17801011, 0.15840226 ...

Ответы [ 2 ]

0 голосов
/ 23 октября 2019

Вторая структура случая - Истина, но учтите, что вы объединяете две модели, и у каждой модели есть свой собственный ввод, если входные данные для обеих моделей совпадают, просто подгоните модель, повторив ввод следующим образом:

model.fit([X_train,X_train], y_train)

Я сам реализую вашу проблему, и она работает абсолютно хорошо.

model1 = DenseNet169(weights='imagenet', include_top=False)
model2 = InceptionV3(weights='imagenet', include_top=False)

model1_out = model1.output
model1_out=GlobalAveragePooling2D()(model1_out)

model2_out = model2.output
model2_out=GlobalAveragePooling2D()(model2_out)

x = concatenate([model1_out, model2_out])

x = Dense(10, activation='softmax')(x) 

model=Model(inputs=[model1.input,model2.input],outputs=x)

model.fit([X_train,X_train], y_train)
0 голосов
/ 23 октября 2019

Второй случай: Поскольку ваша модель ожидает два входа, ваши data_generator_train и data_generator_val должны вернуть / выдать список из двух входов для соответствующих моделей и выходных данных. Этого можно добиться, обновив возвращаемое значение метода __data_generation

def __data_generation(...):
    ...
    # consider X as input image and y as the label of your model
    return [X, X], keras.utils.to_categorical(y, num_classes=self.n_classes)

Первый случай: Поскольку пространственный размер вывода модели2 (8x8) отличается (меньше) довыход модели1 (9x9), вы можете применить нулевое заполнение к выходу модели2 перед конкатенацией.

out1 = model1.output
out2 = model2.output
out2 = ZeroPadding2D(((0,1), (0,1)))(out2)
x = concatenate([out1, out2])

Для первого случая вам также нужно изменить генератор данных, как во втором случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...