我正在尝试在中间层(例如 conv1_2 层)连接两个 VGG19 神经网络(记为网络 A 和 B)。输入图像先经过网络A的conv1_1层,将A的conv1_1层的输出乘以一个变换矩阵,然后将相乘结果作为网络B的conv1_2层的输入。我设法通过在 B 的 conv1_2 层中添加另一个 conv2D 操作来实现这一点,该操作将 A 的 conv1_1 层的输出作为其输入,同时将新的 Conv2D 操作的输出路由到 B 的 conv1_2 BiasAdd 操作。 Tensorboard 显示的图表显示了相同的模式。
问题是虽然反向传播可以在A的参数和变换矩阵上计算梯度,但前向传播只发生在网络B上(FP仍然使用B的顺序结构而不是我想要的“输入→A→变换矩阵→B” ). 无论A的conv1_1层参数和Transformation矩阵如何变化,B的损失都是一个常数!我特别困惑的是Tensorboard中的图表显示B的conv1_2层的Conv2D和BiasAdd操作之间没有联系之后我的修改,但是全网B的前向传播还是可以成功的。会话运行的图表是否与 Tensorboard 显示的图表不同? 附言我正在使用 tensorflow 1.4.1 和 python 3.5.2,VGG19 网络函数来自 slim 库。
这是从网络 A 连接到 B 的代码:
init_var_list=tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope="init_model")
full_var_list=tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope="full_model")
tensor_a_next=full_var_list[full_var_list.index(tensor_a)+2]
tensor_b_next=init_var_list[init_var_list.index(tensor_b)+2]
if len(tensor_a.shape.as_list())==4:
a_name=tensor_a.name.rstrip('/weights:0')
b_name=tensor_b.name.rstrip('/weights:0')
a_next_name=tensor_a_next.name.rstrip('/weights:0')
b_next_name=tensor_b_next.name.rstrip('/weights:0')
c=tf.get_default_graph().get_tensor_by_name(b_next_name+'/Conv2D:0')
d=tf.get_default_graph().get_operation_by_name(b_next_name+'/BiasAdd')
trans_f=tf.tensordot(full_model.end_point[a_name],Tran,axes=1)
c_=ge.graph_replace(c,{init_model.end_point[b_name]:trans_f})
ge.connect(ge.sgv(c_),ge.sgv(d).remap_inputs([0]))