如何解决是否可以在没有输入层的情况下在 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,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,activation=tf.nn.relu)
model2 = tf.keras.layers.Conv2D(20,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 顺序 api 被设计为更易于使用,因此不如函数式 api 灵活。这样做的好处是可以通过您传递给它的数据的任何形状自动推断输入“层”形状。缺点是这个更容易使用的模型被简化了,所以你不能做像使用多个输入这样的事情。
来自 keras 文档:
在以下情况下不适合使用顺序模型:
- 您的模型有多个输入或多个输出
- 您的任何层都有多个输入或多个输出
- 需要进行图层共享
- 您需要非线性拓扑(例如残差连接、 多分支模型)
函数式 api 设计得更灵活,即多输入,因此它不会为您进行任何类型的自动推理,因此会出现错误。在这种情况下,您必须显式传递输入层。对于您的用例,它不会自动推断形状似乎很奇怪,但是当您考虑更广泛的用例场景时,这是有道理的。
所以第二种情况应该是:
model2 = tf.keras.layers.Input((10,3,2)) # specified input layer
model2 = tf.keras.layers.Conv2D(10,2,'valid',activation=tf.nn.relu)(model2)
model2 = tf.keras.layers.Conv2D(20,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,2))
model1 = Dense(200,activation=tf.nn.relu)(input1)
input2 = Input((10,2))
model2 = Dense(200,activation=tf.nn.relu)(input2)
merged = concatenate([model1,model2])
merged = Conv2D(10,activation=tf.nn.relu)(merged)
merged = Flatten()(merged)
merged = Dense(200,activation=tf.nn.relu)(merged)
model = Model(inputs=[input1,input2],outputs=merged)
上面我们有两个单独的输入,然后是两个 Dense 层 - 您可以根据需要构建这些单独的线,然后将它们合并在一起以通过需要使用 tf.keras.layers.concatenate
层的卷积层,然后你可以从那里继续联合模型。将整个事物包装在模型对象中,然后您就可以访问训练和推理方法,例如拟合/预测等。
keras
中的链接通过在层中传播 tensors
来工作。因此,在您的第二个示例中,开头 model2
是 keras.layers.Layer
的实例,而不是 tf.Tensor
的实例,因此您会收到错误。
Input
创建一个张量,然后可用于链接层。所以如果没有具体原因,你就加一个:
model2 = tf.keras.layers.Input((10,2))
model2 = tf.keras.layers.Conv2D(10,activation=tf.nn.relu)(model2)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。