在 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.outputmodel2.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 个顺序模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Keras 的顺序模型中更改输入形状

如何在 Keras 中将顺序模型添加到预训练模型?

Keras:如何在顺序模型中获取图层形状

尝试在 Keras 中加载顺序模型时出现“KeyError:0”

使用 keras 顺序模型获得较差的分类精度

Keras,Tensorflow:将两个不同的模型输出合并为一个