多輸出模型
社交模型的構(gòu)建
這里我們先來看個例子,通過一個網(wǎng)絡(luò)來試圖預(yù)測數(shù)據(jù)的不同性質(zhì),一個網(wǎng)絡(luò)中:
這個就是一個典型的一個輸入,多個輸出的模型,具體的coding如下。
多頭輸出模型案例from keras import layers
from keras import Input
from keras.models import Model
# 最常用的前50000詞語
vocabulary_size = 50000
# 收入為10個等級
num_income_groups = 10
# shape = (None,) 表示輸入的長度是可變的
# 輸入的格式類型是:整數(shù)序列
# name='posts' 對輸入進行命名
posts_input = Input(shape=(None,),dtype='int32',name='posts')
# # 將輸入嵌入維度為256的向量
embedded_posts = layers.Embedding(256,vocabulary_size)(posts_input)
x = layers.Conv1D(128,5,activation='relu')(embedded_posts)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(256,5,activation = 'relu')(x)
x = layers.Conv1D(256,5,activation='relu')(x)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(256,5,activation='relu')(x)
x = layers.Conv1D(256,5,activation='relu')(x)
# 求全局的MAX池化,這里全局指的是整個steps
x = layers.GlobalMaxPooling1D()(x)
x = layers.Dense(128,activation='relu')(x)
# 對于每一個輸出層進行命名
age_prediction = layers.Dense(1,name='age')(x)
income_prediction = layers.Dense(num_income_groups,
activation='softmax',
name = 'income')(x)
gender_prediction = layers.Dense(1,
activation='sigmoid',
name = 'gender')(x)
# 創(chuàng)建模型,模型的輸出是三個數(shù)據(jù)構(gòu)成一個列表
model = Model(posts_input,
[age_prediction,
income_prediction,
gender_prediction])
社交模型編譯 - 損失函數(shù)處理
這里我們需要對于不同的輸入指定不同的損失函數(shù):
對于在keras中我們可以這樣處理:
在編譯函數(shù)compile
中,使用列表或者使用字典將不同的輸出指定不同的損失,然后將得到的損失值相加得到一個全局損失值,然后在訓(xùn)練過程中將相加的那個損失進行最小化.
具體的coding如下
# 使用列表的形式,要與模型建立的是輸出要對應(yīng)
model.compile(optimizer='rmsprop',
loss = ['mse',
'categorical_crossentropy',
'binary_crossentropy'])
# 使用字典的形式
# 這里也是需要輸出層具有名稱時
model.compile(optimizer='rmsprop',
loss= {'age':'mse',
'income': 'categorical_crossentropy',
'gender': 'binary_crossentropy'
})
損失值權(quán)重的分配
上面的相加是比較粗暴的直接相加,這里需要考慮兩個問題:
# 使用列表的形式,要與模型建立的是輸出要對應(yīng)
model.compile(optimizer='rmsprop',
loss = ['mse',
'categorical_crossentropy',
'binary_crossentropy'],
loss_weights=[0.25,1.0,10.])
# 使用字典的形式
# 這里也是需要輸出層具有名稱時
model.compile(optimizer='rmsprop',
loss= {'age':'mse',
'income': 'categorical_crossentropy',
'gender': 'binary_crossentropy'
},
loss_weights={
'age':0.25,
'imcome':1.,
'gender':10.
}
)
多輸出模型的訓(xùn)練
對于多輸出模型,要將標簽數(shù)據(jù)對應(yīng)與模型中的目標數(shù)據(jù).我們可以使用Numpy數(shù)據(jù)組成的列表或者字典.
# 訓(xùn)練函數(shù)中,多輸出模型的列表數(shù)據(jù)
model.fit(posts,
[age_targets,income_targets,gender_targets],
epochs=10,
batch_size=64)
# 訓(xùn)練函數(shù)中,多輸出模型的字典數(shù)據(jù)
# 這里也是需要輸出層具有名稱時
model.fit(posts,
{'age':age_targets,
'income':income_targets,
'gender':gender_targets},
epochs=10,
batch_size=64)
多輸入多輸出模型
本例子參考Keras 文檔的關(guān)于試圖預(yù)測Twitter上的一條新聞有多少轉(zhuǎn)發(fā)和點贊數(shù),來說明多輸入多輸出模型,利用函數(shù)API里處理大量交織的數(shù)據(jù)流.
輸入的數(shù)據(jù):
輸出的數(shù)據(jù):
輔助輸出
較早地在模型中使用主損失函數(shù),是深度學(xué)習(xí)模型的一個良好正則方法
插入輔助損失,使得即使在模型主損失很高的情況下,LSTM 層和 Embedding 層都能被平穩(wěn)地訓(xùn)練
主輸出
具體的模型結(jié)構(gòu)如下圖:
多輸入多輸出模型具體的coding如下:
from keras.layers import Input,Embedding,LSTM,Dense
from keras.models import Model
# 最常用的前10000詞語
vocabulary_size = 10000
# shape = (100,) 表示輸入是一個含有100個整數(shù)序列,
# 每個整數(shù)在1到10000之間的
# 輸入的格式類型是:整數(shù)序列
# name='main_input' 對輸入進行命名
main_input = Input(shape=(100,),
dtype='int32',
name='main_input')
# Embedding 層將輸入序列編碼為一個稠密向量的序列,
# 每個向量維度為 512。
# 使用最常用的前10000詞語
# 輸入的長度100,同上面main_input
x = Embedding(output_dim=512,
input_dim=10000,
input_length=100)(main_input)
# LSTM 層把向量序列轉(zhuǎn)換成單個向量,
# 它包含整個序列的上下文信息
lstm_out = LSTM(32)(x)
# 這里直接來一個輔助輸出
# 作用是:
# 1.使得即使在模型主損失很高的情況下,
#LSTM 層和 Embedding 層都能被平穩(wěn)地訓(xùn)練
# 2. 較早地在模型中使用主損失函數(shù),是一個良好正則方法
auxiliary_output = Dense(1,
activation='sigmoid',
name='aux_output')(lstm_out)
# 引入輔助輸入數(shù)據(jù)
auxiliary_input = Input(shape=(5,),name = 'aux_input')
# 結(jié)合輔助數(shù)據(jù)
x = keras.layers.concatenate([lstm_out,auxiliary_input])
# 堆疊多個全連接網(wǎng)絡(luò)層
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
# 最后添加主要的邏輯回歸層
main_output = Dense(1, a
ctivation='sigmoid',
name='main_output')(x)
# 定義一個多輸入多輸出模型
model = Model(inputs=[main_input,auxiliary_input],
outputs=[main_output,auxiliary_output]
)
# 這里做了一個簡寫,因為這里的兩個損失函數(shù)選的是一樣,
# 這里對于輔助損失值分配一個0.2的權(quán)重
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
loss_weights=[1.,0.2])
# 另外一種列表的寫法
model.compile(optimizer='rmsprop',
loss=['binary_crossentropy',
'binary_crossentropy'],
loss_weights=[1.,0.2])
# 傳入的數(shù)據(jù)也是兩個,和兩個標簽數(shù)據(jù)
model.fit([headline_data,additional_data],
[labels,labels],
epochs=50,
batch_size=32)
# 使用字典的寫法
model.compile(optimizer='rmsprop',
losss = {'main_output':'binary_crossentropy',
'aux_output':'binary_crossentropy'},
loss_weight=[1.,0.2]
)
# 要跟前面的name對應(yīng)
model.fit(
{'main_input':headline_data,
'aux_input': additional_data},
{'main_output':labels,
'aux_output':labels},
epochs=50,
batch_size=32
)