AFAIK,我们仍然需要创建一个模型并使用功能API向模型添加层。为什么人们说功能性人工智能被用来创建非序贯神经网络?
发布于 2017-11-13 23:41:44
为什么人们说它习惯于非序贯神经网络?
问题是,使用Sequential Model
,在调用.add()
方法时,您将逐步(顺序地)定义模型。然而,在Functional (特别是Model
类)上,您有更多的自由度,因为您可以定义接收不同输入的不同层,然后使用任何这些层(不一定一步一步,也不一定是顺序方式)与Model
创建者一起实例化模型。
换句话说,在调用model = Sequential()
时,您就是,此时实例化您的模型对象(然后为其添加层和约束)。在Functional中,创建层,然后通过使用所需的输入和输出层调用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
考虑到这一点,那么选择哪种方式更取决于你的个人风格和编码偏好。现在,与顺序模型相比,的一个主要优点是使用函数API,即可以在不同的模型()之间共享或重用层。
在编译和拟合模型时,它的所有相关层都将被编译和训练。因此,共享这些层的任何其他模型也将反映这些更改。这给了你做很多事情的自由,比如获得你的网络的子模型,重新定义它们,获得它的相对输出,将它们合并成更复杂的模型,等等,而不必为每一个子模型再进行训练。
为了更清楚地说明,这里有一个示例(基于这 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,而不管我是否想重用或循环层,因为我发现它更冗长,但这取决于您的决定。
发布于 2017-11-14 12:51:27
嗯,“顺序”并不是真正正确的术语,但它是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"
函数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)
我们可以用不同的选项连接两个分支,例如添加、乘、连接等等:
#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和functional,都可以像层一样使用。
您可以使用和输入张量调用模型,并获得输出张量,就像创建函数API模型时一样:
input1 = Input(shape)
output1 = anExistingSequentialModel(input1)
output2 = anExistingFunctionalModel(input1)
newModel = Model(input1,[output1,output2])
您也可以在顺序模型中添加模型(注意分支,添加的模型最好有一个输入和一个输出,因为这是一个顺序输入)
seqModel = Sequential()
seqModel.add(anotherModel)
https://stackoverflow.com/questions/47274299
复制相似问题