keras學習筆記-----快速開始keras函數式API

Keras函數式API是定義複雜模型的方法,比如說多輸出模型,有向無環圖,或具有共享層的模型。當然在使用函數式API的時候,要對順序模型有一定的瞭解,我們可以通過一些例子來學習函數式API的使用。

一、全連接網絡

我們使用函數式API來實現一個全連接網絡。在定義網絡時,網絡層的示例是可調用的,它以張量爲參數,並且會返回一個張量,輸入和輸出都是張量,然後用來定義一個Model模型。下面我們通過這個例子,來看一下函數式API的使用。

from keras.layers import Input, Dense
from keras.models import Model

# 返回一個張量
inputs = Input(shape=(784,))

# 定義網絡層實例,輸入和輸出都是張量,可被調用
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)

# 創建模型
model = Model(inputs=inputs, outputs=predictions)
# 配置網絡
model.compile(optimizer='rmsprop',
             loss='categorical_crossentropy',
             metrics=['accuracy'])
# 訓練
model.fit(data, labels)

這樣,我們就定義好了一個簡單的模型,在keras中,利用函數式API,可以輕易地重用訓練好的模型,所有的模型可以被調用,就像網絡層一樣。通過傳遞一個張量來調用它,在調用模型時,不僅重用了模型的結構,也重用了模型的參數。這樣,我們可以快速創建可以處理序列輸入的模型。只需一行代碼就將圖像分類模型轉換爲視頻分類模型。

from keras.layers import TimeDistributed

# 創建一個20個時間步的序列,每個時間步是一個784的向量
input_sequences = Input(shape=(20, 784))

# 將之前定義的模型應用到這個輸入上,輸入爲維度爲10的20個向量的序列
processed_sequences = TimeDistributed(model)(input_sequences)

二、多輸入多輸出模型

對於多輸入多輸出模型,函數式API使處理大量交織的數據流變得容易。我們來預測Twitter上的一條新聞標題有多少轉發和點贊數。模型的主要輸入是新聞標題本身,即一系列詞語,我們增加了輔助輸入來接受額外的數據,例如新聞的發佈時間。該模型也通過來那個損失函數進行監督學習。模型結構圖如下:

from keras.layers import Input, Embedding, LSTM, Dense
from keras.models import Model

# 標題輸入,是一個含有100個整數的序列,值在1-10000之間,10000個詞的詞彙表
main_input = Input(shape=(100,), dtype='int32', name='main_input')

# Embedding層將輸入編碼爲一個稠密向量的序列,維度爲512
x = Embedding(output_dim=512, input_dim=10000, input_length=100)(main_input)

# LSTM層,把向量序列轉換爲單個向量,包含序列的上下文信息
lstm_out = LSTM(32)(x)

# 插入輔助損失,使LSTM和Embedding能平穩訓練
auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)

# 添加一個輔助輸入,並連接起來
auxiliary_input = Input(shape=(5,), name='aux_input')
x = keras.layers.concatenate([lstm_out, auxiliary_input])

# 堆疊多個全連接層
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)

# 邏輯迴歸
main_output = Dense(1, activation='sigmoid', name='main_output')(x)

# 定義模型
model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])

# 編譯模型,配置網絡
model.compile(optimizer='rmsprop', 
              loss='binary_crossentropy',
             loss_weights=[1., 0.2])

# 訓練模型
model.fit([headline_data, additional_data], [labels, labels], epochs=50, batch_size=32)

三、共享網絡層

共享網絡層是函數式API的另一個用途。假如我們想建立一個模型分辨兩條推文是否來自同一個人,我們可以將兩條推文編碼成兩個向量,連接向量,然後添加邏輯迴歸層。輸出兩條推文來自同一作者的概率。我們可以使用同一個LSTM來編碼兩條推文。

from keras.layers import Input, LSTM, Dense
from keras.models import Model
import keras

tweet_a = Input(shape(280, 256))
tweet_b = Input(shape(280, 256))

# 這一層可以輸入一個矩陣,並返回一個64維向量
shared_lstm = LSTM(64)

# 重用相同的圖層示例多次,權重也會重用
encoded_a = shared_lstm(tweet_a)
encoded_b = shared_lstm(tweet_b)

# 連接兩個向量
merged_vector = keras.layers.concatenate([encoded_a, encoded_b])

# 添加邏輯迴歸層
predictions = Dense(1, activation='sigmoid')(merged_vector)

# 定義模型
model = Model(inputs=[tweet_a, tweet_b], outputs=predictions)

# 編譯
model.compile(optimizer='rmsprop',
             loss='bianry_crossentropy',
             metrics=['accuracy'])

# 訓練
model.fit([data_a, data_b], labels, epoch=10)

我們還需要注意的問題是,模型的輸入和輸處形狀的問題,假如一個單輸出單輸出的模型。

a = Input(shape=(200, 256))
lstm = LSTM(32)
encoded_a = lstm(a)

assert lstm.output == encoded_a

但是,如果多輸入就會遇到問題。需要如下判斷

a = Input(shape=(280, 256))
b = Input(shape=(280, 256))

lstm = LSTM(32)
encoded_a = lstm(a)
encoded_b = lstm(b)

assert lstm.get_output_at(0) == encoded_a
assert lstm.get_output_at(1) == encoded_b

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章