如何在Keras中连接两个层?

120

我有一个包含两个层的神经网络示例。第一层接收两个参数并输出一个结果。第二个层应该接收第一层的输出和一个额外的参数作为输入。它应该长成这样:

x1  x2  x3
 \  /   /
  y1   /
   \  /
    y2

所以,我创建了一个有两个层的模型并尝试合并它们,但是出现了错误:The first layer in a Sequential model must get an "input_shape" or "batch_input_shape" argument. 在代码行 result.add(merged) 上。

模型:

first = Sequential()
first.add(Dense(1, input_shape=(2,), activation='sigmoid'))

second = Sequential()
second.add(Dense(1, input_shape=(1,), activation='sigmoid'))

result = Sequential()
merged = Concatenate([first, second])
ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)
result.add(merged)
result.compile(optimizer=ada_grad, loss=_loss_tensor, metrics=['accuracy'])

我认为这个问题在人工智能中被称为分层融合,主要用于多模态数据。 - sugab
3个回答

145
您遇到了这个错误是因为定义为Sequential()result 只是模型的容器,并且您尚未为其定义输入。
针对您试图构建的内容,将result设置为接受第三个输入x3
first = Sequential()
first.add(Dense(1, input_shape=(2,), activation='sigmoid'))

second = Sequential()
second.add(Dense(1, input_shape=(1,), activation='sigmoid'))

third = Sequential()
# of course you must provide the input to result which will be your x3
third.add(Dense(1, input_shape=(1,), activation='sigmoid'))

# lets say you add a few more layers to first and second.
# concatenate them
merged = Concatenate([first, second])

# then concatenate the two outputs

result = Concatenate([merged,  third])

ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)

result.compile(optimizer=ada_grad, loss='binary_crossentropy',
               metrics=['accuracy'])

然而,我建议使用函数式API来构建具有这种输入结构的模型。

以下是一个实现您需求的示例供您参考:

from keras.models import Model
from keras.layers import Concatenate, Dense, LSTM, Input, concatenate
from keras.optimizers import Adagrad

first_input = Input(shape=(2, ))
first_dense = Dense(1, )(first_input)

second_input = Input(shape=(2, ))
second_dense = Dense(1, )(second_input)

merge_one = concatenate([first_dense, second_dense])

third_input = Input(shape=(1, ))
merge_two = concatenate([merge_one, third_input])

model = Model(inputs=[first_input, second_input, third_input], outputs=merge_two)
ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)
model.compile(optimizer=ada_grad, loss='binary_crossentropy',
               metrics=['accuracy'])

回答评论中的问题:

  1. 结果和合并如何连接?假设您的意思是它们如何连接起来。

连接的方法如下:

  a        b         c
a b c   g h i    a b c g h i
d e f   j k l    d e f j k l

即行只是连接在一起。

  1. 现在,x1被输入到第一个,x2被输入到第二个,x3被输入到第三个。

1
second_input 通过一个 Dense 层并入了 first_input,而 first_input 也是通过一个 Dense 层的。third_input 通过一个 Dense 层,并与之前拼接(merged)的结果一起进行拼接。 - parsethis
3
使用函数式 API 的第二种方法可行,但在 Keras 2.0.2 中使用 Sequential-model 的第一种方法对我来说不起作用。我大致检查了实现并发现调用“Concatenate([...])”并没有什么作用,此外,你不能将其添加到顺序模型中。我认为人们实际上仍然需要使用过时的方法“Merge([...], 'concat')”,直到他们更新 Keras。你认为呢? - LFish
我有两个模型,最后一层都是 Dense(number_of_sleep_stages, activation='softmax')。对于连接后的模型,我的输入应该是什么? merge = Concatenate([model1, model2]) final_model = Model(outputs = merge, inputs = ???) - Digvijay Sawant
它应该是两个模型的输入,输入为[ input1,input2 ]。这是我在没有看到您的模型的情况下所能做的最好的事情。 - parsethis
4
在Keras中,“Concatenate()”和“concatenate()”层有什么区别? - Leevo
显示剩余6条评论

12

在上面接受的答案的基础上补充说明,以帮助那些正在使用 tensorflow 2.0 的人



import tensorflow as tf

# some data
c1 = tf.constant([[1, 1, 1], [2, 2, 2]], dtype=tf.float32)
c2 = tf.constant([[2, 2, 2], [3, 3, 3]], dtype=tf.float32)
c3 = tf.constant([[3, 3, 3], [4, 4, 4]], dtype=tf.float32)

# bake layers x1, x2, x3
x1 = tf.keras.layers.Dense(10)(c1)
x2 = tf.keras.layers.Dense(10)(c2)
x3 = tf.keras.layers.Dense(10)(c3)

# merged layer y1
y1 = tf.keras.layers.Concatenate(axis=1)([x1, x2])

# merged layer y2
y2 = tf.keras.layers.Concatenate(axis=1)([y1, x3])

# print info
print("-"*30)
print("x1", x1.shape, "x2", x2.shape, "x3", x3.shape)
print("y1", y1.shape)
print("y2", y2.shape)
print("-"*30)

结果:

------------------------------
x1 (2, 10) x2 (2, 10) x3 (2, 10)
y1 (2, 20)
y2 (2, 30)
------------------------------

8
你可以尝试使用 model.summary() (注意 concatenate_XX (Concatenate) 层的大小)进行实验。
# merge samples, two input must be same shape
inp1 = Input(shape=(10,32))
inp2 = Input(shape=(10,32))
cc1 = concatenate([inp1, inp2],axis=0) # Merge data must same row column
output = Dense(30, activation='relu')(cc1)
model = Model(inputs=[inp1, inp2], outputs=output)
model.summary()

# merge row must same column size
inp1 = Input(shape=(20,10))
inp2 = Input(shape=(32,10))
cc1 = concatenate([inp1, inp2],axis=1)
output = Dense(30, activation='relu')(cc1)
model = Model(inputs=[inp1, inp2], outputs=output)
model.summary()

# merge column must same row size
inp1 = Input(shape=(10,20))
inp2 = Input(shape=(10,32))
cc1 = concatenate([inp1, inp2],axis=1)
output = Dense(30, activation='relu')(cc1)
model = Model(inputs=[inp1, inp2], outputs=output)
model.summary()

您可以在此处查看笔记本的详细信息: https://nbviewer.jupyter.org/github/anhhh11/DeepLearning/blob/master/Concanate_two_layer_keras.ipynb


4
在Keras中,Concatenate()concatenate()层有什么区别? - Leevo
2
你弄清楚它们的区别了吗?一个是Keras类,另一个是TensorFlow方法。 - abacusreader

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接