在 Keras 中合并 2 个顺序模型
Posted
技术标签:
【中文标题】在 Keras 中合并 2 个顺序模型【英文标题】:Merge 2 sequential models in Keras 【发布时间】:2018-02-09 07:33:53 【问题描述】:我试图在 keras 中合并 2 个顺序模型。代码如下:
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 at 0x2b32d518a780, keras.models.Sequential 对象在 0x2b32d521ee80]。所有输入到 层应该是张量。
如何合并这 2 个使用不同窗口大小的 Sequential 模型并对它们应用“max”、“sum”等函数?
【问题讨论】:
你需要合并两个模型的输出层,我不认为你可以在keras中合并编译好的模型。你应该看看keras' functional API 检查:***.com/questions/44872982/… 知道了。我以为我们可以。值得一试。谢谢你的链接 编译不会影响创建/更改模型的任何内容。但是当您更改时,您将不得不再次编译以进行培训。 (在 keras 中编译只是:“为训练设置优化器和损失函数”,仅此而已)。如果你不打算训练,你甚至不需要“编译”一个模型,它可以做所有事情,包括预测,当它没有编译时,除了训练。 【参考方案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
变量对其进行训练:
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)
【讨论】:
所以当我们想要合并 2 个模型时,我们不能将这 2 个模型声明为 Sequential()?我们必须使用函数式 API。当我调用 Concatenate() 时,我不断收到上述问题中所述的错误。在这种情况下我们不能使用 Sequential() 是否正确? 你可以保留顺序模型,没问题,但最终模型不能顺序,这是不可行的。错误消息是关于:“调用层时您没有传递张量”。您很可能正在传递模型。请注意我的回答中的model1.output
和 model2.output
张量。 ---- model1
是模型,model1.output
是张量。
最终模型是一个功能性的Model
,其中包含两个Sequential
模型和一些附加层。
我发现很难理解最后一部分。我正在用相同的训练数据训练我的两个模型。这是我的 fit() 函数 - model.fit([train_data, train_data], train_labels, batch_size=256, epochs=5, validation_data=(test_data, test_labels), verbose=1, callbacks=callbacks)
我仍然收到错误消息:ValueError: The model expects 2input arrays, but only received one array. Found: array with shape (1807, 6000, 1)
这可能是因为validation_data
,它也需要两个输入,就像你对train_data
所做的那样。以上是关于在 Keras 中合并 2 个顺序模型的主要内容,如果未能解决你的问题,请参考以下文章