神经网络玩得越久就越会尝试一些网络结构上的大改动。
先说意图
有两个模型:模型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实现将两个模型连接到一起就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
Keras,模型连接
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】