如何合并具有相同输入的keras序列模型?

最后发布: 2017-08-29 04:47:05


问题

我正在尝试用keras创建我的第一个合奏模型。 我的数据集中有3个输入值和一个输出值。

from keras.optimizers import SGD,Adam
from keras.layers import Dense,Merge
from keras.models import Sequential

model1 = Sequential()
model1.add(Dense(3, input_dim=3, activation='relu'))
model1.add(Dense(2, activation='relu'))
model1.add(Dense(2, activation='tanh'))
model1.compile(loss='mse', optimizer='Adam', metrics=['accuracy'])

model2 = Sequential()
model2.add(Dense(3, input_dim=3, activation='linear'))
model2.add(Dense(4, activation='tanh'))
model2.add(Dense(3, activation='tanh'))
model2.compile(loss='mse', optimizer='SGD', metrics=['accuracy'])

model3 = Sequential()
model3.add(Merge([model1, model2], mode = 'concat'))
model3.add(Dense(1, activation='sigmoid'))
model3.compile(loss='binary_crossentropy', optimizer='Adam', metrics=['accuracy'])

model3.input_shape

整体模型(模型3)编译没有任何错误,但在拟合模型时,我必须传递两次相同的输入model3.fit([X,X],y) 我认为这是一个不必要的步骤,而不是传递输入两次我想为我的整体模型有一个共同的输入节点。 我该怎么做?

python keras keras-layer ensemble-learning
回答

Keras 功能API似乎更适合您的用例,因为它允许计算图更灵活。 例如:

from keras.layers import concatenate
from keras.models import Model
from keras.layers import Input, Merge
from keras.layers.core import Dense
from keras.layers.merge import concatenate

# a single input layer
inputs = Input(shape=(3,))

# model 1
x1 = Dense(3, activation='relu')(inputs)
x1 = Dense(2, activation='relu')(x1)
x1 = Dense(2, activation='tanh')(x1)

# model 2 
x2 = Dense(3, activation='linear')(inputs)
x2 = Dense(4, activation='tanh')(x2)
x2 = Dense(3, activation='tanh')(x2)

# merging models
x3 = concatenate([x1, x2])

# output layer
predictions = Dense(1, activation='sigmoid')(x3)

# generate a model from the layers above
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# Always a good idea to verify it looks as you expect it to 
# model.summary()

data = [[1,2,3], [1,1,3], [7,8,9], [5,8,10]]
labels = [0,0,1,1]

# The resulting model can be fit with a single input:
model.fit(data, labels, epochs=50)

笔记:

  • Keras版本之间的API可能略有不同(版本2之前和之后)
  • 上面的示例为每个模型指定了不同的优化器和损失函数。 但是,由于fit()只被调用一次(在模型3上),相同的设置 - 模型3的设置 - 将适用于整个模型。 为了在训练子模型时有不同的设置,它们必须分别适合() - 请参阅@Daniel的评论。

编辑:根据评论更新笔记


回答

etov的答案是一个很好的选择。

但是假设你已经准备好了model1model2并且你不想更改它们,你可以创建第三个模型:

singleInput = Input((3,))

out1 = model1(singleInput)   
out2 = model2(singleInput)
#....
#outN = modelN(singleInput)

out = Concatenate()([out1,out2]) #[out1,out2,...,outN]
out = Dense(1, activation='sigmoid')(out)

model3 = Model(singleInput,out)

如果你已准备好所有模型并且不想更改它们,你可以拥有这样的东西(未经测试):

singleInput = Input((3,))
output = model3([singleInput,singleInput])
singleModel = Model(singleInput,output)