您好,登錄后才能下訂單哦!
這篇文章主要講解了Keras將兩個模型連接到一起的實現方法,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
神經網絡玩得越久就越會嘗試一些網絡結構上的大改動。
先說意圖
有兩個模型:模型A和模型B。模型A的輸出可以連接B的輸入。將兩個小模型連接成一個大模型,A-B,既可以同時訓練又可以分離訓練。
流行的算法里經常有這么關系的兩個模型,對GAN來說,生成器和判別器就是這樣子;對VAE來說,編碼器和解碼器就是這樣子;對目標檢測網絡來說,backbone和整體也是可以拆分的。所以,應用范圍還是挺廣的。
實現方法
首先說明,我的實現方法不一定是最佳方法。也是實在沒有借鑒到比較好的方法,所以才自己手動寫了一個。
第一步,我們有現成的兩個模型A和B;我們想把A的輸出連到B的輸入,組成一個整體C。
第二步, 重構新模型C;我的方法是:讀出A和B各有哪些layer,然后一層一層重新搭成C。
可以看一個自編碼器的代碼(本人所編寫):
class AE: def __init__(self, dim, img_dim, batch_size): self.dim = dim self.img_dim = img_dim self.batch_size = batch_size self.encoder = self.encoder_construct() self.decoder = self.decoder_construct() def encoder_construct(self): x_in = Input(shape=(self.img_dim, self.img_dim, 3)) x = x_in x = Conv2D(self.dim // 16, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(x) x = BatchNormalization()(x) x = LeakyReLU(0.2)(x) x = Conv2D(self.dim // 8, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(x) x = BatchNormalization()(x) x = LeakyReLU(0.2)(x) x = Conv2D(self.dim // 4, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(x) x = BatchNormalization()(x) x = LeakyReLU(0.2)(x) x = Conv2D(self.dim // 2, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(x) x = BatchNormalization()(x) x = LeakyReLU(0.2)(x) x = Conv2D(self.dim, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(x) x = BatchNormalization()(x) x = LeakyReLU(0.2)(x) x = GlobalAveragePooling2D()(x) encoder = Model(x_in, x) return encoder def decoder_construct(self): map_size = K.int_shape(self.encoder.layers[-2].output)[1:-1] # print(type(map_size)) z_in = Input(shape=K.int_shape(self.encoder.output)[1:]) z = z_in z_dim = self.dim z = Dense(np.prod(map_size) * z_dim)(z) z = Reshape(map_size + (z_dim,))(z) z = Conv2DTranspose(z_dim // 2, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(z) z = BatchNormalization()(z) z = Activation('relu')(z) z = Conv2DTranspose(z_dim // 4, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(z) z = BatchNormalization()(z) z = Activation('relu')(z) z = Conv2DTranspose(z_dim // 8, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(z) z = BatchNormalization()(z) z = Activation('relu')(z) z = Conv2DTranspose(z_dim // 16, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(z) z = BatchNormalization()(z) z = Activation('relu')(z) z = Conv2DTranspose(3, kernel_size=(5, 5), strides=(2, 2), padding='SAME')(z) z = Activation('tanh')(z) decoder = Model(z_in, z) return decoder def build_ae(self): input_x = Input(shape=(self.img_dim, self.img_dim, 3)) x = input_x for i in range(1, len(self.encoder.layers)): x = self.encoder.layers[i](x) for j in range(1, len(self.decoder.layers)): x = self.decoder.layers[j](x) y = x auto_encoder = Model(input_x, y) return auto_encoder
模型A就是這里的encoder,模型B就是這里的decoder。所以,連接的精髓在build_ae()函數,直接用for循環讀出各層,然后一層一層重新構造新的模型,從而實現連接效果。因為keras也是基于圖的框架,這個操作并不會很費時,因為沒有實際地計算。
補充知識:keras得到每層的系數
使用keras搭建好一個模型,訓練好,怎么得到每層的系數呢:
weights = np.array(model.get_weights()) print(weights) print(weights[0].shape) print(weights[1].shape)
這樣系數就被存放到一個np中了。
看完上述內容,是不是對Keras將兩個模型連接到一起的實現方法有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。