AFAIK,我们仍然需要使用functional API创建模型并向模型添加图层。为什么人们会说功能性AI用于创建非顺序神经网络?
答案 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,...)
在此之后,您将能够单独对encoder
和decoder
模型进行预测(例如,可视化您的编码),并使用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
模型是一条直线。您不断添加图层,每个新图层都会获取上一图层的输出。您无法使用分支制作创意图表。 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"
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)