首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我们说Keras中的functional用于非序列模型?

为什么我们说Keras中的functional用于非序列模型?
EN

Stack Overflow用户
提问于 2017-11-13 22:01:39
回答 2查看 4.3K关注 0票数 4

AFAIK,我们仍然需要创建一个模型并使用功能API向模型添加层。为什么人们说功能性人工智能被用来创建非序贯神经网络?

EN

回答 2

Stack Overflow用户

发布于 2017-11-13 23:41:44

为什么人们说它习惯于非序贯神经网络?

问题是,使用Sequential Model,在调用.add()方法时,您将逐步(顺序地)定义模型。然而,在Functional (特别是Model类)上,您有更多的自由度,因为您可以定义接收不同输入的不同层,然后使用任何这些层(不一定一步一步,也不一定是顺序方式)与Model创建者一起实例化模型。

换句话说,在调用model = Sequential()时,您就是,此时实例化您的模型对象(然后为其添加层和约束)。在Functional中,创建层,然后通过使用所需的输入和输出层调用model = Model(inputs=in, outputs=out)来实例化模型。正如您所看到的,这两种方法可以是等价的,例如,这两种方法是相同的:

代码语言:javascript
运行
复制
from keras.models import Sequential, Model
from keras.layers import Input, Dense, Activation
#---Using the Sequential model
model = Sequential() #Object is instantiated here
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))
#---Or using the Functional API
a = Input(shape=(784,))
b = Dense(32, activation='relu')(a)
model = Model(inputs=a, outputs=b) #Object is instantiated here

考虑到这一点,那么选择哪种方式更取决于你的个人风格和编码偏好。现在,与顺序模型相比,的一个主要优点是使用函数API,即可以在不同的模型()之间共享或重用层。

在编译和拟合模型时,它的所有相关层都将被编译和训练。因此,共享这些层的任何其他模型也将反映这些更改。这给了你做很多事情的自由,比如获得你的网络的子模型,重新定义它们,获得它的相对输出,将它们合并成更复杂的模型,等等,而不必为每一个子模型再进行训练。

为了更清楚地说明,这里有一个示例(基于 Keras自动编码博客文章),说明了在最后一段中讨论的内容:

代码语言:javascript
运行
复制
from keras.layers import Input, Dense
from keras.models import Model
#Create an autoencoder, along with its encoder and decoder model
input_img = Input(shape=(784,))
encoded = Dense(32, activation='relu')(input_img)
decoded = Dense(784, activation='sigmoid')(encoded)

#Here we define our autoencoder model: image -> encoding -> decoded image
autoencoder = Model(input_img, decoded)

#Now here is the advantage of the Funcional API
#We can reuse those layers to obtain an encoder model (image -> encoding)
#as well as a decoder model (encoding -> image)
#but compile all three by just compiling and fitting the Autoencoder model
encoder = Model(input_img, encoded) #see how the 'encoded' layer is output
# create a placeholder for an encoded (32-dimensional) input
encoded_input = Input(shape=(32,))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(encoded_input, decoder_layer(encoded_input))
#compile and fit with your data
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(X,Y,...)

在此之后,您将能够单独对encoderdecoder模型进行预测(例如,可视化您的编码),以及将autoencoder模型作为一个整体进行预测。在这一点上,做以下事情是等价的:

代码语言:javascript
运行
复制
#obtain reconstructed representation directly
autoencoder_imgs = autoencoder.predict(x_test)
#obtain reconstructed representation by joining encoder and decoder models
encoder_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)

希望这能有所帮助。就我个人而言,我总是尝试使用Functional,而不管我是否想重用或循环层,因为我发现它更冗长,但这取决于您的决定。

票数 12
EN

Stack Overflow用户

发布于 2017-11-14 12:51:27

嗯,“顺序”并不是真正正确的术语,但它是Keras开发人员选择的名称。当然,所有的模型都是按顺序工作的。

区别是:

  • Sequential模型是一条直线。您一直在添加层,每个新层都接受前一层的输出。你不能用树枝制作有创意的图表。
  • 函数式API Model完全可以根据需要拥有任意数量的分支、输入和输出。

Sequential模型的示例:

代码语言:javascript
运行
复制
from keras.models import Sequential 
from keras.layers import *

#you create a model
model = Sequential()

#and you add layers
model.add(SomeKerasLayer(...))
model.add(AnotherKerasLayer(...))

#as you can see, this model is a straight line, you only add layers "sequentially"

函数API Model示例

现在,我们开始创建非常漂亮的模型。

代码语言:javascript
运行
复制
from keras.models import Model
from keras.layers import *

我们首先定义输入张量。我们可以有任意数量的投入!(顺序模型仅限于一个输入,您使用input_shape在第一层中定义该输入)。

代码语言:javascript
运行
复制
input1 = Input(inputShape1)

#We can have more inputs if we want!
input2 = Input(inputShape2)
input3 = Input(inputShape3)

我们通过创建层和“用输入张量调用层”来工作。

当我们调用一个具有输入张量的层时,我们得到一个输出张量。

我们可以创造任何我们想要的道路。

代码语言:javascript
运行
复制
#Example: two separate layers taking two separate inputs:
output1 = SomeLayer(...)(input1)
output2 = AnotherLayer(...)(input2)

我们可以用不同的选项连接两个分支,例如添加、乘、连接等等:

代码语言:javascript
运行
复制
#joining the previous tensors output1 and output2
joined1_2 = Concatenate()([output1,output2])

我们可以用不同的输入重用相同的层,得到不同的输出:

代码语言:javascript
运行
复制
aLayer = AKerasLayer(...) #notice I'm creating this layer but not calling it yet

#calling the same layer with two different inputs
output1 = aLayer(joined1_2)
output2 = aLayer(input3)

最后,我们可以用我们想要的输入和输出来定义模型:

代码语言:javascript
运行
复制
model = Model([input1,input2,input3],[output1, output2])

重用关联模型

这两种模型,顺序API和functional,都可以像层一样使用。

您可以使用和输入张量调用模型,并获得输出张量,就像创建函数API模型时一样:

代码语言:javascript
运行
复制
input1 = Input(shape)
output1 = anExistingSequentialModel(input1)
output2 = anExistingFunctionalModel(input1)

newModel = Model(input1,[output1,output2])

您也可以在顺序模型中添加模型(注意分支,添加的模型最好有一个输入和一个输出,因为这是一个顺序输入)

代码语言:javascript
运行
复制
seqModel = Sequential()
seqModel.add(anotherModel)
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47274299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档