文章目录
- 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