在没有输入层的情况下,是否可以在Keras Functional API中创建模型



我想在Keras中创建一个由2个卷积层、一个平坦层和一个密集层组成的模型。这将是一个具有共享权重的模型,因此没有任何预定义的输入层。

可以使用顺序方式:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(10,3,2,'valid',activation=tf.nn.relu))
model.add(tf.keras.layers.Conv2D(20,3,2,'valid',activation=tf.nn.relu))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(200,activation=tf.nn.relu))

但是,使用Functional API会产生一个TypeError:

model2 = tf.keras.layers.Conv2D(10,3,2,'valid',activation=tf.nn.relu)
model2 = tf.keras.layers.Conv2D(20,3,2,'valid',activation=tf.nn.relu)(model2)
model2 = tf.keras.layers.Flatten()(model2)
model2 = tf.keras.layers.Dense(200,activation=tf.nn.relu)(model2)

错误:

TypeError: Inputs to a layer should be tensors. Got: <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fb060598100>

这样做是不可能的,还是我错过了什么?

keras sequential api设计得更易于使用,因此不如函数式api灵活。这样做的好处是,无论你传递给输入"层"形状的数据是什么形状,都可以自动推断出它。缺点是这个更容易使用的模型被简化了,所以你不能做像使用多个输入这样的事情。

来自keras文档:

在以下情况下,顺序模型不合适:

  • 您的模型有多个输入或多个输出
  • 任何层都有多个输入或多个输出
  • 你需要进行图层共享
  • 您想要非线性拓扑(例如,剩余连接、多分支模型(

函数api设计得更灵活,即多个输入,因此它不会为您进行任何类型的自动推理,因此会出现错误。在这种情况下,必须显式传递输入层。对于您的用例,它不会自动推断形状,这可能看起来很奇怪,但当您考虑更广泛的用例场景时,这是有意义的。

所以第二种情况应该是:

model2 = tf.keras.layers.Input((10,3,2)) # specified input layer
model2 = tf.keras.layers.Conv2D(10,3,2,'valid',activation=tf.nn.relu)(model2)
model2 = tf.keras.layers.Conv2D(20,3,2,'valid',activation=tf.nn.relu)(model2)
model2 = tf.keras.layers.Flatten()(model2)
model2 = tf.keras.layers.Dense(200,activation=tf.nn.relu)(model2)

更新

如果您想创建两个单独的模型并将它们连接在一起,您应该使用函数API,然后由于它的限制,您必须使用输入层。所以你可以做一些类似的事情:

import tensorflow as tf
from tensorflow.keras.layers import Input, Flatten, Dense, concatenate, Conv2D
from tensorflow.keras.models import Model
input1 = Input((10,3,2))
model1 = Dense(200,activation=tf.nn.relu)(input1)
input2 = Input((10,3,2))
model2 = Dense(200,activation=tf.nn.relu)(input2)
merged = concatenate([model1, model2])
merged = Conv2D(10,3,2,'valid',activation=tf.nn.relu)(merged)
merged = Flatten()(merged)
merged = Dense(200,activation=tf.nn.relu)(merged)
model = Model(inputs=[input1, input2], outputs=merged)

上面我们有两个单独的输入,然后是两个密集层-你可以随心所欲地构建这些单独的线,然后将它们合并在一起,使它们通过卷积层,你需要使用tf.keras.layers.concatenate层,然后你可以从那里继续联合模型。将整个事情封装在Model对象中,然后可以访问训练和推理方法,如拟合/预测等。

keras中的链接通过层传播tensors来工作。因此,在第二个例子中,在开头,model2keras.layers.Layer的实例,而不是tf.Tensor,这就是为什么会出现错误。

CCD_ 7创建一个张量,然后可以使用该张量来链接层。因此,如果没有具体原因,只需添加一个:

model2 = tf.keras.layers.Input((10,3,2))
model2 = tf.keras.layers.Conv2D(10,3,2,'valid',activation=tf.nn.relu)(model2)

相关内容

  • 没有找到相关文章

最新更新