在Keras合并2个连续模型

Dig*_*ant 14 python machine-learning neural-network conv-neural-network keras

我试图在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
Run Code Online (Sandbox Code Playgroud)

这是错误日志:

文件"/nics/d/home/dsawant/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py",线路392,在is_keras_tensor提高ValueError异常("意外地发现类型的实例' + str(type(x)) + '." ValueError异常:意外地发现了一个类型的实例<class 'keras.models.Sequential'>.期望一个符号张量实例.

更多日志:

ValueError:使用不是符号张量的输入调用图层merge_1.收到类型:class'keras.models.Sequential'.完整输入:[keras.models.Sequential object at 0x2b32d518a780,keras.models.Sequential object at 0x2b32d521ee80].该层的所有输入都应该是张量.

如何合并使用不同窗口大小的这两个Sequential模型并将"max","sum"等函数应用于它们?

Dan*_*ler 19

使用功能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
Run Code Online (Sandbox Code Playgroud)

同样的想法适用于以下所有层.我们不断更新输出张量,将它提供给每一层并获得一个新输出(如果我们对创建分支感兴趣,我们将为每个感兴趣的输出使用不同的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)
Run Code Online (Sandbox Code Playgroud)

现在我们创建了"路径",是时候创建了Model.创建模型就像告诉它开始的输入张量以及结束的位置:

from keras.models import Model

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

请注意,由于此模型有两个输入,因此您必须X_training在列表中使用两个不同的vars 进行训练:

newModel.fit([X_train_1, X_train_2], Y_train, ....)    
Run Code Online (Sandbox Code Playgroud)

现在,假设您只需要一个输入,并且model1和model2将采用相同的输入.

功能API通过创建输入张量并将其提供给模型(我们称模型就像它们是图层一样)非常容易:

commonInput = Input(input_shape)

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

mergedOut = Add()([out1,out2])
Run Code Online (Sandbox Code Playgroud)

在这种情况下,模型会考虑这个输入:

oneInputModel = Model(commonInput,mergedOut)
Run Code Online (Sandbox Code Playgroud)

  • 你可以保留顺序模型,没问题,但最终模型不能是顺序的,这是不可行的。错误消息是关于:“调用层时您没有传递张量”。您很可能正在传递模型。请注意我的答案中的 `model1.output` 和 `model2.output` 张量。---- `model1` 是一个模型,而 `model1.output` 是一个张量。 (2认同)
  • 最终的模型是一个功能性的“模型”,它包含两个“顺序”模型和其路径中的一些附加层。 (2认同)