Объединить 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: слой merge_1 был вызван с входом, который не является символический тензор. Полученный тип: класс ' keras.модели.Последовательный". Полный ввод: [keras.модели.Последовательный объект на 0x2b32d518a780, керрас.модели.Последовательный объект в 0x2b32d521ee80]. Все входы слой должен быть тензором.
как объединить эти 2 последовательные модели, которые используют разные размеры окон и применяют функции например, "Макс", "сумма" и т. д.?
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)