文章目录

  • 1. 什么是并联神经网络
  • 2. tensorflow2 代码实现
  • 2.1 构造网络的图
  • 2.2 训练和测试
  • 3. 并联网络基础上做迁移学习


【以下有自己搜索和理解的内容,未必全对,供有需要的同学参考。】

1. 什么是并联神经网络

如下图所示,有时候需要搭建一个如下图的网络:“并联”两个子网络,将他们的输出层Concat到一起,然后在二者合并之后的网络上继续添加隐层。

两个神经网络模型怎么合成 神经网络并联_迁移学习

2. tensorflow2 代码实现

2.1 构造网络的图

import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model

####定义一个方便构造常规 Sequential() 网络的函数
def DNNGraph(x,n_input=28*28,n_hidden=100, n_layer=2,n_output=10,name='DNN_A'):
        he = tf.initializers.he_normal()
        elu = tf.nn.elu
        ##
        for i in range(n_layer):
            x=Dense(n_hidden, kernel_initializer=he, activation=elu, input_dim=n_input,use_bias=False,name=name+'_HiddenLayer-%d'%i)(x)
        x=Dense(n_output, kernel_initializer=he, activation=elu,use_bias=False,name=name+'_OutputLayer')(x)
        return(x)

#### 构造并联网络图
##需要并联的两个网络的输入
input_a=tf.keras.layers.Input(shape=[28*28])
input_b=tf.keras.layers.Input(shape=[28*28])
##构造两个需要并联的子网络结构
dnn_a=DNNGraph(input_a,n_input=28*28,n_hidden=100,n_layer=3,n_output=100,name="DNN_A")
dnn_b=DNNGraph(input_b,n_input=28*28,n_hidden=200,n_layer=3,n_output=200,name="DNN_B")
##concat操作
concat=tf.keras.layers.concatenate([dnn_a,dnn_b],axis=1,name="Concat_Layer")
##在concat基础上继续添加一些层
logit=Dense(10,activation=tf.keras.activations.softmax,name="Logit_Layer")(concat)
output=Dense(1,activation=tf.keras.activations.sigmoid,name="Output_Layer")(logit)
##这一步很关键:这一步相当于把输入和输出对应起来,形成系统认识的一个完整的图。
model=Model(inputs=[input_a,input_b],outputs=[output])
##网络的其他组件
optimizer=tf.keras.optimizers.Adam()
loss_fn=tf.keras.losses.mean_squared_error
model.compile(loss=loss_fn,
              optimizer=optimizer,
              metrics=['accuracy'],
              )

2.2 训练和测试

模型的训练和测试,和常规的Sequential模型一样,不过区别是,现在的输入是个list,里面包含每个分支网络的输入

#### 训练和测试:这里的x1,x2,对应前述的input_a和input_b
model.fit(x=[x1,x2],y=y,epochs=10,batch_size=500,verbose=2)
model.evaluate(x=[x1_test,x2_test],y=y_test,verbose=2)

3. 并联网络基础上做迁移学习

在一个训练好的并联网络上做迁移学习,例如只用训练好的一个分支 input_a对应的那个分支网络。这时候和普通迁移学习(TF2:50行代码的迁移学习实例 )区别是:需要从model.layers中提取出input_a对应的左边的那个子网络,需要知道该子网络中隐层在model.layers中对应的序号。这时候可以根据子网络的名称或者input_shape来判断。

上述代码中都是给网络做了命名,输出一下,可以观察出model.layers中分支网络的隐层在总模型中隐层的排列规律:比较简单的一个结论是——当两个分支网络层数一样或相差1的时候,二者的隐层在总网络中是交替排序的,分支网络层数差异较大时候,规律不是那么好看。可以用下述循环输出隐层的名称来观察。

for i in range(len(model.layers)):
    print(model.layers[i].name)

当DNN_A和DNN_B隐层数相同的时候,输出结果如下:
input_1
input_2
DNN_A_HiddenLayer-0
DNN_B_HiddenLayer-0
DNN_A_HiddenLayer-1
DNN_B_HiddenLayer-1
DNN_A_HiddenLayer-2
DNN_B_HiddenLayer-2
DNN_A_OutputLayer
DNN_B_OutputLayer
Concat_Layer
Logit_Layer
Output_Layer