简体   繁体   English

是否可以在没有输入层的 Keras 功能 API 中创建 model ?

[英]Is it possible to create a model in Keras Functional API without an input layer?

I would like to create a model consisting of 2 convolutional, one flatten, and one dense layer in Keras.我想创建一个 model,它由 Keras 中的 2 个卷积层、一个展平层和一个密集层组成。 This would be a model with shared weights, so without any predefined input layer.这将是一个具有共享权重的 model,因此没有任何预定义的输入层。

It is possible to do using the sequential way:可以使用顺序方式进行:

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))

However, using the Functional API, produces a TypeError:但是,使用功能 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)

Error:错误:

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

Is it impossible to do this way, or am I missing something?这样做是不可能的,还是我错过了什么?

The keras sequential api is designed to be easier to use, and as a result is less flexible than the functional api. keras 顺序 api 设计为更易于使用,因此不如功能性 api 灵活。 The benefit of this is that an input 'layer' shape can be inferred automatically by whatever shape of the data you pass to it.这样做的好处是可以通过传递给它的任何数据形状自动推断输入“层”形状。 The downside is that this easier to use model is simplified, and so you can't do things like using multiple inputs.缺点是这个更容易使用 model 被简化了,所以你不能做像使用多个输入这样的事情。

From the keras docs:来自keras文档:

A Sequential model is not appropriate when:顺序 model 在以下情况下不适用:

  • Your model has multiple inputs or multiple outputs您的 model 有多个输入或多个输出
  • Any of your layers has multiple inputs or multiple outputs您的任何层都有多个输入或多个输出
  • You need to do layer sharing您需要进行图层共享
  • You want non-linear topology (eg a residual connection, a multi-branch model)您想要非线性拓扑(例如残差连接、多分支模型)

The functional api is designed to be more flexible ie multiple inputs, and so it doesn't make any sort of automatic inference for you, hence the error.功能 api 被设计为更灵活,即多输入,因此它不会为您进行任何类型的自动推理,因此会出现错误。 You must explicitly pass an input layer in this case.在这种情况下,您必须显式传递一个输入层。 For your use case, it might seem odd that it doesn't automatically infer the shape, however when you consider the wider use-case scenario it makes sense.对于您的用例,它不会自动推断形状可能看起来很奇怪,但是当您考虑更广泛的用例场景时,它是有意义的。

So the second scenario should be:所以第二种情况应该是:

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)

Update更新

If you want to create two separate models and join them together, you should use the functional API, and then due to it's constraints you must therefore use input layers.如果要创建两个单独的模型并将它们连接在一起,则应使用功能 API,然后由于其限制,因此您必须使用输入层。 So you could do something like:因此,您可以执行以下操作:

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)

Above we have two separate inputs and then two Dense layers - you can build these separate lines however you want, and then to merge them together to pass them through a convolutional layer you need to use a tf.keras.layers.concatenate layer, and then you can continue the joint model from there.上面我们有两个单独的输入,然后是两个 Dense 层 - 您可以根据需要构建这些单独的线,然后将它们合并在一起以通过卷积层,您需要使用tf.keras.layers.concatenate层,以及然后你可以从那里继续联合 model。 Wrapping the whole thing inside a Model object then allows you access training and inference methods like fit/predict etc.将整个东西包装在 Model object 中,然后允许您访问训练和推理方法,如拟合/预测等。

The linking in keras works by propagating tensors through the layers. keras中的链接通过在层中传播tensors来工作。 So in your second example, at the beginning model2 is an instance of a keras.layers.Layer and not a tf.Tensor that why you get the error.因此,在您的第二个示例中,一开始model2keras.layers.Layer的实例,而不是tf.Tensor的实例,这就是您收到错误的原因。

Input creates a tensor which can then be used to link the layers. Input创建一个张量,然后可以使用它来链接图层。 So if there is not a specific reason, you just add one:因此,如果没有特定原因,您只需添加一个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM