鍵.png)
使用這些基本 REST API 最佳實踐構(gòu)建出色的 API
from keras.layers import Dense
model = Sequential([Dense(2, input_dim=1), Dense(1)])
圖層也可以分段添加:
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, input_dim=1))
model.add(Dense(1))
順序模型API非常適合在大多數(shù)情況下開發(fā)深度學(xué)習(xí)模型,但它也有一些限制。例如,定義可能具有多個不同輸入源,產(chǎn)生多個輸出目標(biāo)的模型或重用圖層的模型并非易事。
Keras功能API為定義模型提供了更靈活的方法。它特別允許您定義多個輸入或輸出模型以及共享圖層的模型。不僅如此,它還允許您定義臨時非循環(huán)網(wǎng)絡(luò)圖。通過創(chuàng)建層實例并將它們直接成對相互連接,然后定義一個模型來指定模型,以指定這些層作為模型的輸入和輸出來定義模型。讓我們依次看一下Keras功能API的三個獨特方面:
與順序模型不同,您必須創(chuàng)建并定義一個獨立的輸入層,以指定輸入數(shù)據(jù)的形狀。輸入層采用形狀參數(shù),該參數(shù)是一個元組,指示輸入數(shù)據(jù)的維數(shù)。如果輸入數(shù)據(jù)是一維的(例如多層感知器),則形狀必須明確地留出訓(xùn)練網(wǎng)絡(luò)時拆分數(shù)據(jù)時使用的最小批量大小的形狀的空間。因此,當(dāng)輸入為一維(2,)
時,形狀元組始終以最后一個懸掛尺寸定義,例如:
from keras.layers import Input
visible = Input(shape=(2,))
模型中的圖層成對連接。這是通過在定義每個新層時指定輸入來自何處來完成的。使用括號表示法,以便在創(chuàng)建圖層之后,指定當(dāng)前圖層輸入的來源圖層。讓我們用一個簡短的例子來闡明這一點。我們可以如上所述創(chuàng)建輸入層,然后創(chuàng)建一個隱藏層作為Dense,僅從輸入層接收輸入。
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)
注意在創(chuàng)建將輸入層輸出作為密集層連接起來的密集層之后的(可見)層。正是這種逐層連接的方式賦予了功能性API靈活性。例如,您可以看到開始定義圖層的臨時圖形將非常容易。
創(chuàng)建所有模型層并將它們連接在一起之后,必須定義模型。與Sequential API一樣,模型是您可以匯總,擬合,評估并用于進行預(yù)測的東西。Keras提供了一個Model類,您可以使用該類從創(chuàng)建的圖層中創(chuàng)建模型。它只需要指定輸入和輸出層。例如:
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)
model = Model(inputs=visible, outputs=hidden)
現(xiàn)在,我們已經(jīng)了解了Keras功能API的所有關(guān)鍵部分,下面我們來定義一組不同的模型,并進行一些實踐。每個示例都是可執(zhí)行的,并打印結(jié)構(gòu)并創(chuàng)建圖的圖。我建議您針對自己的模型執(zhí)行此操作,以明確定義的內(nèi)容。我希望這些示例在將來您希望使用功能性API定義自己的模型時為您提供模板。
使用功能性API入門時,最好先了解如何定義一些標(biāo)準(zhǔn)的神經(jīng)網(wǎng)絡(luò)模型。在本節(jié)中,我們將研究定義一個簡單的多層感知器,卷積神經(jīng)網(wǎng)絡(luò)和遞歸神經(jīng)網(wǎng)絡(luò)。這些示例將為以后理解更詳細的示例提供基礎(chǔ)。
在本節(jié)中,我們定義了用于二進制分類的多層感知器模型。該模型具有10個輸入,3個具有10、20和10個神經(jīng)元的隱藏層以及一個具有1個輸出的輸出層。整流的線性激活函數(shù)用于每個隱藏層,而S形激活函數(shù)用于輸出層,以進行二進制分類。
# Multilayer Perceptron
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(10,))
hidden1 = Dense(10, activation='relu')(visible)
hidden2 = Dense(20, activation='relu')(hidden1)
hidden3 = Dense(10, activation='relu')(hidden2)
output = Dense(1, activation='sigmoid')(hidden3)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multilayer_perceptron_graph.png')
輸出如下:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 10) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 110
_________________________________________________________________
dense_2 (Dense) (None, 20) 220
_________________________________________________________________
dense_3 (Dense) (None, 10) 210
_________________________________________________________________
dense_4 (Dense) (None, 1) 11
=================================================================
Total params: 551
Trainable params: 551
Non-trainable params: 0
_________________________________________________________________
網(wǎng)絡(luò)結(jié)構(gòu)圖如下:
在本節(jié)中,我們將定義用于圖像分類的卷積神經(jīng)網(wǎng)絡(luò)。該模型接收黑白64×64圖像作為輸入,然后具有兩個卷積和池化層作為特征提取器的序列,然后是一個全連接層以解釋特征,并具有一個S型激活的輸出層以進行兩類預(yù)測 。
# Convolutional Neural Network
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
visible = Input(shape=(64,64,1))
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(16, kernel_size=4, activation='relu')(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat = Flatten()(pool2)
hidden1 = Dense(10, activation='relu')(flat)
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='convolutional_neural_network.png')
輸出如下:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 64, 64, 1) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 61, 61, 32) 544
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 30, 30, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 27, 27, 16) 8208
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 16) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 2704) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 27050
_________________________________________________________________
dense_2 (Dense) (None, 1) 11
=================================================================
Total params: 35,813
Trainable params: 35,813
Non-trainable params: 0
_________________________________________________________________
網(wǎng)絡(luò)結(jié)構(gòu)圖如下:
在本節(jié)中,我們將為序列分類定義一個長短期記憶遞歸神經(jīng)網(wǎng)絡(luò)。該模型期望一個功能的100個時間步長作為輸入。該模型具有單個LSTM隱藏層以從序列中提取特征,然后是一個完全連接的層以解釋LSTM輸出,然后是一個用于進行二進制預(yù)測的輸出層。
# Recurrent Neural Network
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
visible = Input(shape=(100,1))
hidden1 = LSTM(10)(visible)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='recurrent_neural_network.png')
輸出如下:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 100, 1) 0
_________________________________________________________________
lstm_1 (LSTM) (None, 10) 480
_________________________________________________________________
dense_1 (Dense) (None, 10) 110
_________________________________________________________________
dense_2 (Dense) (None, 1) 11
=================================================================
Total params: 601
Trainable params: 601
Non-trainable params: 0
_________________________________________________________________
模型結(jié)構(gòu)圖如下:
多層可以共享一層的輸出。例如,可能有來自輸入的多個不同的特征提取層,或者可能有多個層用于解釋來自特征提取層的輸出。讓我們看兩個例子。
在本節(jié)中,我們定義了具有不同大小內(nèi)核的多個卷積層,以解釋圖像輸入。該模型將拍攝尺寸為64×64像素的黑白圖像。有兩個共享此輸入的CNN特征提取子模型。第一個的內(nèi)核大小為4,第二個的內(nèi)核大小為8。這些特征提取子模型的輸出被展平為向量,并連接為一個長向量,并傳遞到完全連接的層以進行解釋,最后輸出層完成 二進制分類。
# Shared Input Layer
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
# input layer
visible = Input(shape=(64,64,1))
# first feature extractor
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
flat1 = Flatten()(pool1)
# second feature extractor
conv2 = Conv2D(16, kernel_size=8, activation='relu')(visible)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat2 = Flatten()(pool2)
# merge feature extractors
merge = concatenate([flat1, flat2])
# interpretation layer
hidden1 = Dense(10, activation='relu')(merge)
# prediction output
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='shared_input_layer.png')
輸出如下:
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 64, 64, 1) 0
____________________________________________________________________________________________________
conv2d_1 (Conv2D) (None, 61, 61, 32) 544 input_1[0][0]
____________________________________________________________________________________________________
conv2d_2 (Conv2D) (None, 57, 57, 16) 1040 input_1[0][0]
____________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D) (None, 30, 30, 32) 0 conv2d_1[0][0]
____________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D) (None, 28, 28, 16) 0 conv2d_2[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten) (None, 28800) 0 max_pooling2d_1[0][0]
____________________________________________________________________________________________________
flatten_2 (Flatten) (None, 12544) 0 max_pooling2d_2[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate) (None, 41344) 0 flatten_1[0][0]
flatten_2[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 10) 413450 concatenate_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 1) 11 dense_1[0][0]
====================================================================================================
Total params: 415,045
Trainable params: 415,045
Non-trainable params: 0
____________________________________________________________________________________________________
網(wǎng)絡(luò)結(jié)構(gòu)圖如下:
在本節(jié)中,我們將使用兩個并行子模型來解釋用于序列分類的LSTM特征提取器的輸出。模型的輸入是1個特征的100個時間步長。具有10個存儲單元的LSTM層將解釋此序列。第一個解釋模型是淺的單個完全連接層,第二個解釋是深的3層模型。兩種解釋模型的輸出都連接到一個長向量中,該向量傳遞到用于進行二進制預(yù)測的輸出層。
# Shared Feature Extraction Layer
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.layers.merge import concatenate
# define input
visible = Input(shape=(100,1))
# feature extraction
extract1 = LSTM(10)(visible)
# first interpretation model
interp1 = Dense(10, activation='relu')(extract1)
# second interpretation model
interp11 = Dense(10, activation='relu')(extract1)
interp12 = Dense(20, activation='relu')(interp11)
interp13 = Dense(10, activation='relu')(interp12)
# merge interpretation
merge = concatenate([interp1, interp13])
# output
output = Dense(1, activation='sigmoid')(merge)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='shared_feature_extractor.png')
輸出如下:
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 100, 1) 0
____________________________________________________________________________________________________
lstm_1 (LSTM) (None, 10) 480 input_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 10) 110 lstm_1[0][0]
____________________________________________________________________________________________________
dense_3 (Dense) (None, 20) 220 dense_2[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 10) 110 lstm_1[0][0]
____________________________________________________________________________________________________
dense_4 (Dense) (None, 10) 210 dense_3[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate) (None, 20) 0 dense_1[0][0]
dense_4[0][0]
____________________________________________________________________________________________________
dense_5 (Dense) (None, 1) 21 concatenate_1[0][0]
====================================================================================================
Total params: 1,151
Trainable params: 1,151
Non-trainable params: 0
____________________________________________________________________________________________________
網(wǎng)絡(luò)結(jié)構(gòu)圖如下:
功能性API也可以用于開發(fā)具有多個輸入(可能具有不同的模式)的更復(fù)雜的模型。它還可以用于開發(fā)產(chǎn)生多個輸出的模型。我們將在本節(jié)中查看每個示例。
我們將開發(fā)一個圖像分類模型,該模型將兩個版本的圖像作為輸入,每個版本的大小不同。特別是黑白64×64版本和彩色32×32版本。分別對每個CNN模型進行特征提取,然后將兩個模型的結(jié)果連接起來以進行解釋和最終預(yù)測。請注意,在創(chuàng)建Model()
實例時,我們將兩個輸入層定義為一個數(shù)組。特別:
model = Model(inputs=[visible1, visible2], outputs=output)
實例如下:
# Multiple Inputs
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
# first input model
visible1 = Input(shape=(64,64,1))
conv11 = Conv2D(32, kernel_size=4, activation='relu')(visible1)
pool11 = MaxPooling2D(pool_size=(2, 2))(conv11)
conv12 = Conv2D(16, kernel_size=4, activation='relu')(pool11)
pool12 = MaxPooling2D(pool_size=(2, 2))(conv12)
flat1 = Flatten()(pool12)
# second input model
visible2 = Input(shape=(32,32,3))
conv21 = Conv2D(32, kernel_size=4, activation='relu')(visible2)
pool21 = MaxPooling2D(pool_size=(2, 2))(conv21)
conv22 = Conv2D(16, kernel_size=4, activation='relu')(pool21)
pool22 = MaxPooling2D(pool_size=(2, 2))(conv22)
flat2 = Flatten()(pool22)
# merge input models
merge = concatenate([flat1, flat2])
# interpretation model
hidden1 = Dense(10, activation='relu')(merge)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=[visible1, visible2], outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multiple_inputs.png')
輸出如下:
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 64, 64, 1) 0
____________________________________________________________________________________________________
input_2 (InputLayer) (None, 32, 32, 3) 0
____________________________________________________________________________________________________
conv2d_1 (Conv2D) (None, 61, 61, 32) 544 input_1[0][0]
____________________________________________________________________________________________________
conv2d_3 (Conv2D) (None, 29, 29, 32) 1568 input_2[0][0]
____________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D) (None, 30, 30, 32) 0 conv2d_1[0][0]
____________________________________________________________________________________________________
max_pooling2d_3 (MaxPooling2D) (None, 14, 14, 32) 0 conv2d_3[0][0]
____________________________________________________________________________________________________
conv2d_2 (Conv2D) (None, 27, 27, 16) 8208 max_pooling2d_1[0][0]
____________________________________________________________________________________________________
conv2d_4 (Conv2D) (None, 11, 11, 16) 8208 max_pooling2d_3[0][0]
____________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D) (None, 13, 13, 16) 0 conv2d_2[0][0]
____________________________________________________________________________________________________
max_pooling2d_4 (MaxPooling2D) (None, 5, 5, 16) 0 conv2d_4[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten) (None, 2704) 0 max_pooling2d_2[0][0]
____________________________________________________________________________________________________
flatten_2 (Flatten) (None, 400) 0 max_pooling2d_4[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate) (None, 3104) 0 flatten_1[0][0]
flatten_2[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 10) 31050 concatenate_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 10) 110 dense_1[0][0]
____________________________________________________________________________________________________
dense_3 (Dense) (None, 1) 11 dense_2[0][0]
====================================================================================================
Total params: 49,699
Trainable params: 49,699
Non-trainable params: 0
____________________________________________________________________________________________________
網(wǎng)絡(luò)結(jié)構(gòu)圖如下:
在本節(jié)中,我們將開發(fā)一個進行兩種不同類型預(yù)測的模型。給定一個特征的100個時間步長的輸入序列,該模型將對序列進行分類并輸出具有相同長度的新序列。LSTM層解釋輸入序列,并為每個時間步返回隱藏狀態(tài)。第一個輸出模型創(chuàng)建堆疊的LSTM,解釋特征,并進行二進制預(yù)測。第二個輸出模型使用相同的輸出層為每個輸入時間步長進行實值預(yù)測。
# Multiple Outputs
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.layers.wrappers import TimeDistributed
# input layer
visible = Input(shape=(100,1))
# feature extraction
extract = LSTM(10, return_sequences=True)(visible)
# classification output
class11 = LSTM(10)(extract)
class12 = Dense(10, activation='relu')(class11)
output1 = Dense(1, activation='sigmoid')(class12)
# sequence output
output2 = TimeDistributed(Dense(1, activation='linear'))(extract)
# output
model = Model(inputs=visible, outputs=[output1, output2])
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multiple_outputs.png')
輸出如下:
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 100, 1) 0
____________________________________________________________________________________________________
lstm_1 (LSTM) (None, 100, 10) 480 input_1[0][0]
____________________________________________________________________________________________________
lstm_2 (LSTM) (None, 10) 840 lstm_1[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 10) 110 lstm_2[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 1) 11 dense_1[0][0]
____________________________________________________________________________________________________
time_distributed_1 (TimeDistribu (None, 100, 1) 11 lstm_1[0][0]
====================================================================================================
Total params: 1,452
Trainable params: 1,452
Non-trainable params: 0
____________________________________________________________________________________________________
網(wǎng)絡(luò)結(jié)構(gòu)圖如下:
在本節(jié)中,我想向您提供一些技巧,以便在定義自己的模型時充分利用功能性API。
hidden1
,hidden2
)使用相同的變量名。它將有助于正確地將事物連接在一起。Dense(1,name =’hidden1')
。文章轉(zhuǎn)自微信公眾號@開發(fā)者阿橙