为什么我们说Keras中的功能API用于非顺序模型?

时间:2017-11-13 22:01:40

标签: python neural-network deep-learning keras

AFAIK,我们仍然需要使用functional API创建模型并向模型添加图层。为什么人们会说功能性AI用于创建非顺序神经网络?

2 个答案:

答案 0 :(得分:8)

  

为什么人们说它用于非顺序神经网络?

当您调用Sequential Model方法时,使用.add()逐步(按顺序)定义模型。然而,在Functional API(特别是Model类)上,您可以更自由,因为您可以定义接收不同输入的不同,然后实例化模型使用Model创建者使用任何这些图层(不一定是逐步或顺序)。

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

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

仅考虑这一点,然后选择哪种方式取决于您的个人风格和编码偏好。现在,在Sequential模型上使用Functional API有一个主要优势,即可以在不同模型中共享或重用层

编译和拟合模型时,将编译和训练其所有关联的图层。因此,共享此类图层的任何其他模型也将反映这些更改。这使您可以自由地执行许多操作,例如获取网络的子模型,重新定义它们,获取其相对输出,将它们合并到更复杂的模型中等,而无需再为每个子模型进行训练。

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

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进行预测模型作为一个整体。此时,执行以下操作是等效的:

#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 API,无论我是否要重复使用或回收图层,因为发现它更详细,但这取决于你自己决定。

答案 1 :(得分:2)

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

区别在于:

  • Sequential模型是一条直线。您不断添加图层,每个新图层都会获取上一图层的输出。您无法使用分支制作创意图表。
  • 功能API Model可以根据需要随意提供多种分支,输入和输出。

Sequential模型的示例:

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的示例:

现在我们开始创建非常精美的模型。

from keras.models import Model
from keras.layers import *

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

input1 = Input(inputShape1)

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

我们通过创建图层和“使用输入张量调用图层”来工作 当我们调用具有输入张量的图层时,我们得到一个输出张量 我们可以创建我们想要的任何路径。

#Example: two separate layers taking two separate inputs:
output1 = SomeLayer(...)(input1)
output2 = AnotherLayer(...)(input2)

我们可以使用不同的选项连接两个分支,例如add,multiply,concatenate等:

#joining the previous tensors output1 and output2
joined1_2 = Concatenate()([output1,output2])

我们可以重复使用不同输入的相同图层,获得不同的输出:

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)

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

model = Model([input1,input2,input3],[output1, output2])

重用和关联模型

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

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

input1 = Input(shape)
output1 = anExistingSequentialModel(input1)
output2 = anExistingFunctionalModel(input1)

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

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

seqModel = Sequential()
seqModel.add(anotherModel)