Объедините 2 последовательные модели в Keras

Я пытаюсь объединить 2 последовательные модели в keras. Вот код:

model1 = Sequential(layers=[
    # input layers and convolutional layers
    Conv1D(128, kernel_size=12, strides=4, padding='valid', activation='relu', input_shape=input_shape),
    MaxPooling1D(pool_size=6),
    Conv1D(256, kernel_size=12, strides=4, padding='valid', activation='relu'),
    MaxPooling1D(pool_size=6),
    Dropout(.5),

])

model2 = Sequential(layers=[
    # input layers and convolutional layers
    Conv1D(128, kernel_size=20, strides=5, padding='valid', activation='relu', input_shape=input_shape),
    MaxPooling1D(pool_size=5),
    Conv1D(256, kernel_size=20, strides=5, padding='valid', activation='relu'),
    MaxPooling1D(pool_size=5),
    Dropout(.5),

])

model = merge([model1, model2], mode = 'sum')
Flatten(),
Dense(256, activation='relu'),
Dropout(.5),
Dense(128, activation='relu'),
Dropout(.35),
# output layer
Dense(5, activation='softmax')
return model

Вот журнал ошибок:

Файл "/nics/d/home/dsawant/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", строка 392, в is_keras_tensor     raise ValueError ( "Неожиданно нашел экземпляр типа ' + str(type(x)) + '". ValueError: Неожиданно найден экземпляр введите <class 'keras.models.Sequential'>. Ожидаемый символический тензор экземпляр.

Еще несколько журналов:

ValueError: Layer merge_1 вызывается с входом, который не является символический тензор. Полученный тип: класс 'keras.models.Sequential'. Полный ввод: [keras.models.Sequential object на 0x2b32d518a780, keras.models.Sequential на 0x2b32d521ee80]. Все входные данные для слой должен быть тензором.

Как я могу объединить эти 2 последовательные модели, которые используют разные размеры окон и применяют к ним такие функции, как "max", "sum" и т.д.

Ответ 1

Использование функционального API предоставляет вам все возможности.

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

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

Для слоя слияния я предпочитаю использовать другие уровни слияния, которые более интуитивно понятны, например Add(), Multiply() и Concatenate().

from keras.layers import *

mergedOut = Add()([model1.output,model2.output])
    #Add() -> creates a merge layer that sums the inputs
    #The second parentheses "calls" the layer with the output tensors of the two models
    #it will demand that both model1 and model2 have the same output shape

Эта же идея применяется ко всем следующим слоям. Мы продолжаем обновлять выходной тензор, предоставляя его каждому слою и получая новый результат (если бы мы интересовались созданием ветвей, мы бы использовали разные var для каждого интересующего продукта, чтобы отслеживать их):

mergedOut = Flatten()(mergedOut)    
mergedOut = Dense(256, activation='relu')(mergedOut)
mergedOut = Dropout(.5)(mergedOut)
mergedOut = Dense(128, activation='relu')(mergedOut)
mergedOut = Dropout(.35)(mergedOut)

# output layer
mergedOut = Dense(5, activation='softmax')(mergedOut)

Теперь, когда мы создали "путь", пришло время создать Model. Создание модели - это как рассказ о том, какие входные тензоры начинаются и где они заканчиваются:

from keras.models import Model

newModel = Model([model1.input,model2.input], mergedOut)
    #use lists if you want more than one input or output    

Обратите внимание, что, поскольку эта модель имеет два входа, вы должны обучить ее двум различным X_training vars в списке:

newModel.fit([X_train_1, X_train_2], Y_train, ....)    

Теперь предположим, что вам нужен только один вход, и как model1, так и model2 будут принимать одинаковый вход.

Функциональный API позволяет это довольно легко, создавая входной тензор и подавая его в модели (мы называем модели, как если бы они были слоями):

commonInput = Input(input_shape)

out1 = model1(commonInput)    
out2 = model2(commonInput)    

mergedOut = Add()([out1,out2])

В этом случае Модель рассмотрит этот ввод:

oneInputModel = Model(commonInput,mergedOut)