使用keras實(shí)現(xiàn)孿生網(wǎng)絡(luò)中的權(quán)值共享教程
首先聲明,這里的權(quán)值共享指的不是CNN原理中的共享權(quán)值,而是如何在構(gòu)建類似于Siamese Network這樣的多分支網(wǎng)絡(luò),且分支結(jié)構(gòu)相同時(shí),如何使用keras使分支的權(quán)重共享。
Functional API
為達(dá)到上述的目的,建議使用keras中的Functional API,當(dāng)然Sequential 類型的模型也可以使用,本篇博客將主要以Functional API為例講述。
keras的多分支權(quán)值共享功能實(shí)現(xiàn),官方文檔介紹
上面是官方的鏈接,本篇博客也是基于上述官方文檔,實(shí)現(xiàn)的此功能。(插一句,keras雖然有中文文檔,但中文文檔已停更,且中文文檔某些函數(shù)介紹不全,建議直接看英文官方文檔)
不共享參數(shù)的模型
以MatchNet網(wǎng)絡(luò)結(jié)構(gòu)為例子,為方便顯示,將卷積模塊個(gè)數(shù)減為2個(gè)。首先是展示不共享參數(shù)的模型,以便觀看完整的網(wǎng)絡(luò)結(jié)構(gòu)。
整體的網(wǎng)絡(luò)結(jié)構(gòu)如下所示:
代碼包含兩部分,第一部分定義了兩個(gè)函數(shù),F(xiàn)eatureNetwork()生成特征提取網(wǎng)絡(luò),ClassiFilerNet()生成決策網(wǎng)絡(luò)或稱度量網(wǎng)絡(luò)。網(wǎng)絡(luò)結(jié)構(gòu)的可視化在博客末尾。在ClassiFilerNet()函數(shù)中,可以看到調(diào)用了兩次FeatureNetwork()函數(shù),keras.models.Model也被使用的兩次,因此生成的input1和input2是兩個(gè)完全獨(dú)立的模型分支,參數(shù)是不共享的。
from keras.models import Sequential from keras.layers import merge, Conv2D, MaxPool2D, Activation, Dense, concatenate, Flatten from keras.layers import Input from keras.models import Model from keras.utils import np_utils import tensorflow as tf import keras from keras.datasets import mnist import numpy as np from keras.utils import np_utils from keras.callbacks import EarlyStopping, ModelCheckpoint, TensorBoard, ReduceLROnPlateau from keras.utils.vis_utils import plot_model # ---------------------函數(shù)功能區(qū)------------------------- def FeatureNetwork(): """生成特征提取網(wǎng)絡(luò)""" """這是根據(jù),MNIST數(shù)據(jù)調(diào)整的網(wǎng)絡(luò)結(jié)構(gòu),下面注釋掉的部分是,原始的Matchnet網(wǎng)絡(luò)中feature network結(jié)構(gòu)""" inp = Input(shape = (28, 28, 1), name='FeatureNet_ImageInput') models = Conv2D(filters=24, kernel_size=(3, 3), strides=1, padding='same')(inp) models = Activation('relu')(models) models = MaxPool2D(pool_size=(3, 3))(models) models = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(models) # models = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(models) models = Activation('relu')(models) models = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(models) models = Activation('relu')(models) models = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(models) models = Activation('relu')(models) models = Flatten()(models) models = Dense(512)(models) models = Activation('relu')(models) model = Model(inputs=inp, outputs=models) return model def ClassiFilerNet(): # add classifier Net """生成度量網(wǎng)絡(luò)和決策網(wǎng)絡(luò),其實(shí)maychnet是兩個(gè)網(wǎng)絡(luò)結(jié)構(gòu),一個(gè)是特征提取層(孿生),一個(gè)度量層+匹配層(統(tǒng)稱為決策層)""" input1 = FeatureNetwork() # 孿生網(wǎng)絡(luò)中的一個(gè)特征提取 input2 = FeatureNetwork() # 孿生網(wǎng)絡(luò)中的另一個(gè)特征提取 for layer in input2.layers: # 這個(gè)for循環(huán)一定要加,否則網(wǎng)絡(luò)重名會(huì)出錯(cuò)。 layer.name = layer.name + str("_2") inp1 = input1.input inp2 = input2.input merge_layers = concatenate([input1.output, input2.output]) # 進(jìn)行融合,使用的是默認(rèn)的sum,即簡單的相加 fc1 = Dense(1024, activation='relu')(merge_layers) fc2 = Dense(1024, activation='relu')(fc1) fc3 = Dense(2, activation='softmax')(fc2) class_models = Model(inputs=[inp1, inp2], outputs=[fc3]) return class_models # ---------------------主調(diào)區(qū)------------------------- matchnet = ClassiFilerNet() matchnet.summary() # 打印網(wǎng)絡(luò)結(jié)構(gòu) plot_model(matchnet, to_file='G:/csdn攻略/picture/model.png') # 網(wǎng)絡(luò)結(jié)構(gòu)輸出成png圖片
共享參數(shù)的模型
FeatureNetwork()的功能和上面的功能相同,為方便選擇,在ClassiFilerNet()函數(shù)中加入了判斷是否使用共享參數(shù)模型功能,令reuse=True,便使用的是共享參數(shù)的模型。
關(guān)鍵地方就在,只使用的一次Model,也就是說只創(chuàng)建了一次模型,雖然輸入了兩個(gè)輸入,但其實(shí)使用的是同一個(gè)模型,因此權(quán)重共享的。
from keras.models import Sequential from keras.layers import merge, Conv2D, MaxPool2D, Activation, Dense, concatenate, Flatten from keras.layers import Input from keras.models import Model from keras.utils import np_utils import tensorflow as tf import keras from keras.datasets import mnist import numpy as np from keras.utils import np_utils from keras.callbacks import EarlyStopping, ModelCheckpoint, TensorBoard, ReduceLROnPlateau from keras.utils.vis_utils import plot_model # ----------------函數(shù)功能區(qū)----------------------- def FeatureNetwork(): """生成特征提取網(wǎng)絡(luò)""" """這是根據(jù),MNIST數(shù)據(jù)調(diào)整的網(wǎng)絡(luò)結(jié)構(gòu),下面注釋掉的部分是,原始的Matchnet網(wǎng)絡(luò)中feature network結(jié)構(gòu)""" inp = Input(shape = (28, 28, 1), name='FeatureNet_ImageInput') models = Conv2D(filters=24, kernel_size=(3, 3), strides=1, padding='same')(inp) models = Activation('relu')(models) models = MaxPool2D(pool_size=(3, 3))(models) models = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(models) # models = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(models) models = Activation('relu')(models) models = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(models) models = Activation('relu')(models) models = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(models) models = Activation('relu')(models) # models = Conv2D(64, kernel_size=(3, 3), strides=2, padding='valid')(models) # models = Activation('relu')(models) # models = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(models) models = Flatten()(models) models = Dense(512)(models) models = Activation('relu')(models) model = Model(inputs=inp, outputs=models) return model def ClassiFilerNet(reuse=False): # add classifier Net """生成度量網(wǎng)絡(luò)和決策網(wǎng)絡(luò),其實(shí)maychnet是兩個(gè)網(wǎng)絡(luò)結(jié)構(gòu),一個(gè)是特征提取層(孿生),一個(gè)度量層+匹配層(統(tǒng)稱為決策層)""" if reuse: inp = Input(shape=(28, 28, 1), name='FeatureNet_ImageInput') models = Conv2D(filters=24, kernel_size=(3, 3), strides=1, padding='same')(inp) models = Activation('relu')(models) models = MaxPool2D(pool_size=(3, 3))(models) models = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding='same')(models) # models = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(models) models = Activation('relu')(models) models = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(models) models = Activation('relu')(models) models = Conv2D(filters=96, kernel_size=(3, 3), strides=1, padding='valid')(models) models = Activation('relu')(models) # models = Conv2D(64, kernel_size=(3, 3), strides=2, padding='valid')(models) # models = Activation('relu')(models) # models = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(models) models = Flatten()(models) models = Dense(512)(models) models = Activation('relu')(models) model = Model(inputs=inp, outputs=models) inp1 = Input(shape=(28, 28, 1)) # 創(chuàng)建輸入 inp2 = Input(shape=(28, 28, 1)) # 創(chuàng)建輸入2 model_1 = model(inp1) # 孿生網(wǎng)絡(luò)中的一個(gè)特征提取分支 model_2 = model(inp2) # 孿生網(wǎng)絡(luò)中的另一個(gè)特征提取分支 merge_layers = concatenate([model_1, model_2]) # 進(jìn)行融合,使用的是默認(rèn)的sum,即簡單的相加 else: input1 = FeatureNetwork() # 孿生網(wǎng)絡(luò)中的一個(gè)特征提取 input2 = FeatureNetwork() # 孿生網(wǎng)絡(luò)中的另一個(gè)特征提取 for layer in input2.layers: # 這個(gè)for循環(huán)一定要加,否則網(wǎng)絡(luò)重名會(huì)出錯(cuò)。 layer.name = layer.name + str("_2") inp1 = input1.input inp2 = input2.input merge_layers = concatenate([input1.output, input2.output]) # 進(jìn)行融合,使用的是默認(rèn)的sum,即簡單的相加 fc1 = Dense(1024, activation='relu')(merge_layers) fc2 = Dense(1024, activation='relu')(fc1) fc3 = Dense(2, activation='softmax')(fc2) class_models = Model(inputs=[inp1, inp2], outputs=[fc3]) return class_models
如何看是否真的是權(quán)值共享呢?直接對(duì)比特征提取部分的網(wǎng)絡(luò)參數(shù)個(gè)數(shù)!
不共享參數(shù)模型的參數(shù)數(shù)量:
共享參數(shù)模型的參數(shù)總量
共享參數(shù)模型中的特征提取部分的參數(shù)量為:
由于截圖限制,不共享參數(shù)模型的特征提取網(wǎng)絡(luò)參數(shù)數(shù)量不再展示。其實(shí)經(jīng)過計(jì)算,特征提取網(wǎng)絡(luò)部分的參數(shù)數(shù)量,不共享參數(shù)模型是共享參數(shù)的兩倍。兩個(gè)網(wǎng)絡(luò)總參數(shù)量的差值就是,共享模型中,特征提取部分的參數(shù)的量
網(wǎng)絡(luò)結(jié)構(gòu)可視化
不共享權(quán)重的網(wǎng)絡(luò)結(jié)構(gòu)
共享參數(shù)的網(wǎng)絡(luò)結(jié)構(gòu),其中model_1代表的就是特征提取部分。
以上這篇使用keras實(shí)現(xiàn)孿生網(wǎng)絡(luò)中的權(quán)值共享教程就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python多進(jìn)程池 multiprocessing Pool用法示例
這篇文章主要介紹了Python多進(jìn)程池 multiprocessing Pool用法,結(jié)合實(shí)例形式分析了多進(jìn)程池 multiprocessing Pool相關(guān)概念、原理及簡單使用技巧,需要的朋友可以參考下2018-09-09TensorFlow Session使用的兩種方法小結(jié)
今天小編就為大家分享一篇TensorFlow Session使用的兩種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07python 使用paramiko模塊進(jìn)行封裝,遠(yuǎn)程操作linux主機(jī)的示例代碼
這篇文章主要介紹了python 使用paramiko模塊進(jìn)行封裝,遠(yuǎn)程操作linux主機(jī)的示例代碼,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-12-12