keras多输出模型
Keras多輸入多輸出模型構建
- 1. 多輸出模型構建
- 多輸出模型構建
- 自定義loss函數
- 批量訓練
- 調試
- 2. 多輸入多輸出模型(上)
- 多輸入多輸出模型
- (關鍵)定義這個具有兩個輸入和輸出的模型:
- 編譯模型時候分配損失函數權重
- 訓練模型
- 另外一種編譯、訓練方式(利用字典)
- 多輸入多輸出模型(下)--GoogleNet
- 模型結構
- Inception模塊
- 輔助輸出軸
- 前面的推斷過程
- 模型構建
- 多輸入多輸出模型示例-3
1. 多輸出模型構建
reference from : https://www.jianshu.com/p/6bcd63a0165c
多輸出模型構建
使用keras函數式API構建網絡:
# 輸入層 inputs = tf.keras.layers.Input(shape=(64,64,3))# 卷積層及全連接層等相關層 x = tf.keras.layers.Dense(256, activation=tf.nn.relu)(inputs)# 多輸出,定義兩個輸出,指定名字標識 fc_a=tf.keras.layers.Dense(name='fc_a',units=CLASS_NUM,activation=tf.nn.softmax)(x) fc_b=tf.keras.layers.Dense(name='fc_b',units=CLASS_NUM,activation=tf.nn.softmax)(x) # 單輸入多輸出 model = tf.keras.Model(inputs=inputs, outputs=[fc_a, fc_b])# 目標函數定義,需與輸出層名字對應 losses = {'fc_a': 'categorical_crossentropy','fc_b': 'categorical_crossentropy'}model.compile(optimizer=tf.train.AdamOptimizer(),loss=losses,metrics=['accuracy'])自定義loss函數
def loss_a(y_true, y_pred):return tf.keras.losses.categorical_crossentropy(y_true, y_pred)def loss_b(y_true, y_pred):return tf.keras.losses.meas_squared_error(y_true, y_pred)losses = {'fc_a': loss_a,'fc_b': loss_b}model.compile(optimizer=tf.train.AdamOptimizer(),loss=losses,metrics=['accuracy'])批量訓練
# data_generator返回的標簽形式要是與多輸出的數量對應的數組 def data_generator(sample_num, batch_size):while True:max_num = sample_num - (sample_num % batch_size)for i in range(0, max_num, batch_size):...yield (batch_x, [batch_a, batch_b])model.fit_generator(generator=data_generator(sample_num, batch_size),steps_per_epoch=sample_num//batch_size,epoches=EPOCHES,verbose=1)調試
在自定義的loss函數中,是以Sequence的方式來輸入的,如果想調試查看loss的計算過程中的輸出,直接print是無法打印值的,這是因為tensorflow的每次op都要以sess為基礎來啟動,如果想調試,可以用eager_execution模式:
import tensorflow.contrib.eager as tfe tfe.enable_eager_execution() np.set_printoptions(threshold=np.nan) # 輸出所有元素2. 多輸入多輸出模型(上)
reference from : https://blog.csdn.net/weixin_40920290/article/details/80917353
多輸入多輸出模型
主要輸入(main_input): 新聞標題本身,即一系列詞語.
輔助輸入(aux_input): 接受額外的數據,例如新聞標題的發布時間等.
該模型將通過 兩個損失函數 進行監督學習.
較早地在模型中使用主損失函數,是深度學習模型的一個良好正則方法.
下面用函數式API來實現它。
主要輸入:接受新聞標題本身,即一個整數序列(每個整數編碼一個詞)。這些整數在 1 到 10000之間(10000個詞的詞匯表),且序列長度為100個詞:
在這里我們添加輔助損失,使得即使在模型主損失很高的情況下,LSTM層和Embedding層都能被平穩地訓練:
此時,我們將輔助輸入數據與LSTM層的輸出連接起來,輸入到模型中:
再添加剩余的層:
(關鍵)定義這個具有兩個輸入和輸出的模型:
model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])編譯模型時候分配損失函數權重
編譯模型的時候,給 輔助損失 分配一個0.2的權重.
如果要為不同的輸出指定不同的 loss_weights 或 loss,可以使用列表或字典.
在這里,我們給 loss 參數傳遞單個損失函數,這個損失將用于所有的輸出。:
訓練模型
我們可以通過傳遞輸入數組和目標數組的列表來訓練模型:
model.fit([headline_data, additional_data], [labels, labels],epochs=50, batch_size=32)另外一種編譯、訓練方式(利用字典)
由于輸入和輸出均被命名了(在定義時傳遞了一個 name 參數),我們也可以通過以下方式編譯模型:
model.compile(optimizer='rmsprop',loss={'main_output': 'binary_crossentropy', 'aux_output': 'binary_crossentropy'},loss_weights={'main_output': 1., 'aux_output': 0.2})# 然后使用以下方式訓練: model.fit({'main_input': headline_data, 'aux_input': additional_data},{'main_output': labels, 'aux_output': labels},epochs=50, batch_size=32)多輸入多輸出模型(下)–GoogleNet
reference from : https://blog.csdn.net/weixin_40920290/article/details/80925228
模型結構
注意:
Inception模塊
def inception(x, filter_size, layer_number):"""由1x1,3x3,5x5以及Maxpool構成的Inception模塊Args:x(Tesnsor): 輸入張量filter_size: 卷積核列表,總共有6個卷積核。layer_number: Inception序號Returns:經過Inception模塊后的Tensor"""layer_number = str(layer_number)with K.name_scope('Inception_' + layer_number):# 1x1卷積with K.name_scope("conv_1x1"):conv_1x1 = Conv2D(filters=filter_size[0], kernel_size=(1, 1),strides=1, padding='same', activation='relu',kernel_regularizer=l2(L2_RATE),name='conv_1x1' + layer_number)(x)# 3x3 Bottleneck layer(瓶頸模塊)和 3x3 卷積with K.name_scope('conv_3x3'):conv_3x3 = Conv2D(filters=filter_size[1], kernel_size=(1, 1),strides=1, padding='same', activation='relu',kernel_regularizer=l2(L2_RATE),name='conv_3x3_bottleneck' + layer_number)(x)conv_3x3 = Conv2D(filters=filter_size[2], kernel_size=(3, 3),strides=1, padding='same', activation='relu',kernel_regularizer=l2(L2_RATE),name='conv_3x3' + layer_number)(conv_3x3)with K.name_scope('conv_5x5'):# 5x5 Bottleneck layer(瓶頸層)和 5x5 卷積conv_5x5 = Conv2D(filters=filter_size[3], kernel_size=(1, 1),strides=1, padding='same', activation='relu',kernel_regularizer=l2(L2_RATE),name='conv_5x5_bottleneck' + layer_number)(x)conv_5x5 = Conv2D(filters=filter_size[4], kernel_size=(5, 5),strides=1, padding='same', activation='relu',kernel_regularizer=l2(L2_RATE),name='conv_5x5' + layer_number)(conv_5x5)with K.name_scope('Max_Conv'):# Max pooling(最大池化層) 和 Bottleneck layer(瓶頸層)max_pool = MaxPooling2D(pool_size=3, strides=1, padding='same',name='maxpool'+layer_number)(x)max_pool = Conv2D(filters=filter_size[5], kernel_size=(1, 1),strides=1, padding='same', activation='relu',kernel_regularizer=l2(L2_RATE),name='maxpool_conv1x1' + layer_number)(max_pool)with K.name_scope('concatenate'):# 將所有張量拼接在一起x = concatenate([conv_1x1, conv_3x3, conv_5x5, max_pool], axis=-1)# high/width上相同,channels拼接在一起return x輔助輸出軸
def aux_classifier(x, filter_size, layer_number):"""輔助軸,輸出softmax分類結果Args:x: 輸入張量filter_size: 卷積核列表,長度為3layer_number: 序列Returns: 輔助軸分類結果"""layer_number = str(layer_number)with K.name_scope('aux_ckassifier'+layer_number):# 平均池化層x = AveragePooling2D(pool_size=3, strides=2, padding='same',name='AveragePooling2D'+layer_number)(x)# (0)1x1 卷積層x = Conv2D(filters=filter_size[0], kernel_size=1, strides=1,padding='valid', activation='relu',kernel_regularizer=l2(L2_RATE),name='aux_conv' + layer_number)(x)# 展平x = Flatten()(x)# (1)全連接層1x = Dense(units=filter_size[1], activation='relu',kernel_regularizer=l2(L2_RATE),name='aux_dense1_' + layer_number)(x)x = Dropout(0.7)(x)# (3)softmax輸出層x = Dense(units=NUM_CLASS, activation='softmax',kernel_regularizer=l2(L2_RATE),name='aux_output' + layer_number)(x)return x前面的推斷過程
def front(x, filter_size):# (0)conv2dx = Conv2D(filters=filter_size[0], kernel_size=5, strides=1,padding='same', activation='relu',kernel_regularizer=l2(L2_RATE))(x)x = MaxPooling2D(pool_size=3, strides=2, padding='same')(x)x = BatchNormalization(axis=-1)(x)# (1)conv2dx = Conv2D(filters=filter_size[1], kernel_size=1, strides=1,padding='same', activation='relu',kernel_regularizer=l2(L2_RATE))(x)# (2)conv2dx = Conv2D(filters=filter_size[2], kernel_size=3, strides=1,padding='same', activation='relu',kernel_regularizer=l2(L2_RATE))(x)x = BatchNormalization(axis=-1)(x)x = MaxPooling2D(pool_size=3,strides=1,padding='same')(x)return x模型構建
知識點
Note
- 模型的參數不完全一樣,因為輸入的是cifar-10數據集
- 訓練的時候沒有用生成器,也沒有圖像增強; 因為多輸入多輸出模型利用fit_generator比較麻煩,可以自己百度一下,在這里就不用了
- 利用TensorBoard查看計算圖以及訓練進程
- 并沒有去保存訓練模型等操作
- K.name_scope是可以用的,利用它組織好網絡結構,使用時只需要訓練的時候將TensorBoard回調對象傳回去
多輸入多輸出模型示例-3
reference from : https://blog.csdn.net/zzc15806/article/details/84067017
假設我們需要搭建如下的模型,輸入數據分別為100維和50維的向量,輸出為0或1:
from keras.layers import Conv1D, Dense, MaxPool1D, concatenate, Flatten from keras import Input, Model from keras.utils import plot_model import numpy as npdef multi_input_model():"""構建多輸入模型"""input1_= Input(shape=(100, 1), name='input1')input2_ = Input(shape=(50, 1), name='input2')x1 = Conv1D(16, kernel_size=3, strides=1, activation='relu', padding='same')(input1_)x1 = MaxPool1D(pool_size=10, strides=10)(x1)x2 = Conv1D(16, kernel_size=3, strides=1, activation='relu', padding='same')(input2_)x2 = MaxPool1D(pool_size=5, strides=5)(x2)x = concatenate([x1, x2])x = Flatten()(x)x = Dense(10, activation='relu')(x)output_ = Dense(1, activation='sigmoid', name='output')(x)model = Model(inputs=[input1_, input2_], outputs=[output_])model.summary()return modelif __name__ == '__main__':# 產生訓練數據x1 = np.random.rand(100, 100, 1)x2 = np.random.rand(100, 50, 1)# 產生標簽y = np.random.randint(0, 2, (100,))model = multi_input_model()# 保存模型圖plot_model(model, 'Multi_input_model.png')model.compile(optimizer='adam', loss='binary_crossentropy')model.fit([x1, x2], y, epochs=10, batch_size=10)總結
以上是生活随笔為你收集整理的keras多输出模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: keras 自定义评估函数和损失函数lo
- 下一篇: Nature | IL-27直接靶向脂肪