我正在尝试在Keras中合并两个顺序模型。以下是代码:
model1 = Sequential(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=[ # 输入层和卷积层 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),# 输出层Dense(5, activation='softmax')return model
以下是错误日志:
File “/nics/d/home/dsawant/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py”, line 392, in is_keras_tensor raise ValueError(‘Unexpectedly found an instance of type
' + str(type(x)) + '
. ‘ ValueError: Unexpectedly found an instance of type<class 'keras.models.Sequential'>
. Expected a symbolic tensor instance.
更多日志:
ValueError: Layer merge_1 was called with an input that isn’t a symbolic tensor. Received type: class ‘keras.models.Sequential’. Full input: [keras.models.Sequential object at 0x2b32d518a780, keras.models.Sequential object at 0x2b32d521ee80]. All inputs to the layer should be tensors.
如何合并这两个使用不同窗口大小的顺序模型,并对它们应用如’max’、’sum’等函数?
回答:
使用函数式API可以带来所有可能性。
在使用函数式API时,你需要跟踪输入和输出,而不仅仅是定义层。
你定义一个层,然后用输入张量调用该层以获取输出张量。模型和层可以以完全相同的方式被调用。
对于合并层,我更喜欢使用其他更直观的合并层,例如Add()
、Multiply()
和Concatenate()
等。
from keras.layers import *mergedOut = Add()([model1.output,model2.output]) #Add() -> 创建一个合并层,对输入求和 #第二个括号“调用”该层,并使用两个模型的输出张量 #它要求model1和model2具有相同的输出形状
这个想法同样适用于所有后续层。我们不断更新输出张量,将其传递给每个层并获取新的输出(如果我们有兴趣创建分支,我们会为每个感兴趣的输出使用不同的变量来跟踪它们):
mergedOut = Flatten()(mergedOut) mergedOut = Dense(256, activation='relu')(mergedOut)mergedOut = Dropout(.5)(mergedOut)mergedOut = Dense(128, activation='relu')(mergedOut)mergedOut = Dropout(.35)(mergedOut)# 输出层mergedOut = Dense(5, activation='softmax')(mergedOut)
现在我们已经创建了“路径”,是时候创建Model
了。创建模型就像告诉它从哪些输入张量开始,到哪里结束一样简单:
from keras.models import ModelnewModel = Model([model1.input,model2.input], mergedOut) #如果想要多个输入或输出,请使用列表
请注意,由于这个模型有两个输入,你必须使用列表中的两个不同的X_training
变量来训练它:
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)