一、后端:tf.keras.backend.concatenate()
后端函数应该在“内部”层中使用。您只能在Lambda 层、自定义层、自定义损失函数、自定义指标等中使用它。
它直接作用于“张量”。
如果您不深入定制,这不是您的选择。 (在您的示例代码中这是一个糟糕的选择——请参阅最后的详细信息)。
如果你深入研究 keras 代码,你会注意到Concatenate 层在内部使用了这个函数:
import keras.backend as K
class Concatenate(_Merge):
#blablabla
def _merge_function(self, inputs):
return K.concatenate(inputs, axis=self.axis)
#blablabla
那么,Layer:keras.layers.Concatenate(axis=-1)
与任何其他 keras 层一样,您实例化并调用 张量。
相当直截了当:
#in a functional API model:
inputTensor1 = Input(shape) #or some tensor coming out of any other layer
inputTensor2 = Input(shape2) #or some tensor coming out of any other layer
#first parentheses are creating an instance of the layer
#second parentheses are "calling" the layer on the input tensors
outputTensor = keras.layers.Concatenate(axis=someAxis)([inputTensor1, inputTensor2])
这不适合顺序模型,除非前一层输出一个列表(这是可能的,但不常见)。
最后,来自层模块的连接函数:keras.layers.concatenate(inputs, axis=-1)
这不是层。这是一个返回由内部Concatenate 层生成的张量的函数。
代码很简单:
def concatenate(inputs, axis=-1, **kwargs):
#blablabla
return Concatenate(axis=axis, **kwargs)(inputs)
旧函数
在 Keras 1 中,人们的函数旨在接收“层”作为输入并返回输出“层”。他们的名字与merge这个词有关。
但由于 Keras 2 没有提及或记录这些,我可能会避免使用它们,如果找到旧代码,我可能会将其更新为适当的 Keras 2 代码。
为什么是_keras_shape这个词?
这个后端函数不应该在高级代码中使用。编码器应该使用了Concatenate 层。
atoms_bonds_features = Concatenate(axis=-1)([atoms, summed_bond_features])
#just this line is perfect
Keras 层将_keras_shape 属性添加到其所有输出张量中,Keras 使用此属性来推断整个模型的形状。
如果您在层或损失/度量“外部”使用任何后端函数,您的输出张量将缺少此属性,并且会出现错误,告知 _keras_shape 不存在。
编码人员通过手动添加属性创建了一个糟糕的解决方法,而它应该由适当的 keras 层添加。 (这现在可能有效,但如果 keras 更新,此代码将中断,而正确的代码将保持正常)