如何使用tf.layers.conv2d分享权重

时间:2018-04-25 19:41:44

标签: tensorflow share convolutional-neural-network

我使用tf.layers.conv2d图层构建了一个自动编码器,并希望分阶段进行训练。那就是首先训练外层,然后是中间层,然后是内层。我理解这可以使用tf.nn.conv2d,因为权重是使用tf.get_variable声明的,但我认为这也应该可以使用tf.layers.conv2d。

如果我输入一个与原始图不同的新变量范围来改变卷积层的输入(即在阶段1期间跳过内层),我无法重复使用权重。如果我没有输入新的变量范围,我无法冻结在此阶段我不想训练的权重。

基本上我在尝试使用AurélienGéron的培训方法https://github.com/ageron/handson-ml/blob/master/15_autoencoders.ipynb

除了我想使用cnn而不是密集层。怎么做?

2 个答案:

答案 0 :(得分:2)

无需手动创建变量。这也适用:

import tensorflow as tf

inputs_1 = tf.placeholder(tf.float32, (None, 512, 512, 3), name='inputs_1')
inputs_2 = tf.placeholder(tf.float32, (None, 512, 512, 3), name='inputs_2')

with tf.variable_scope('conv'):
    out_1 = tf.layers.conv2d(inputs_1, 32, [3, 3], name='conv_1')

with tf.variable_scope('conv', reuse=True):
    out_2 = tf.layers.conv2d(inputs_2, 32, [3, 3], name='conv_1')

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    print(tf.trainable_variables())

如果您给tf.layers.conv2d相同的名称,它将使用相同的权重(假设reuse=True,否则会有ValueError)。

答案 1 :(得分:0)

我建议稍微设置一下。我不是使用tf.layers.conv2d,而是使用对tf.get_variable()的调用来显式调整权重,然后使用这些权重调用tf.nn.conv2d()。这样,您不会对变量创建进行blackbox,并且可以轻松地引用它们。这也是了解网络中发生了什么的好方法,因为你手工编写了每组权重的形状!

示例(未经测试)代码:

inputs = tf.placeholder(tf.float32, (batch_size, 512, 512, 3), name='inputs')
weights = tf.get_variable(name='weights', shape=[5, 5, 3, 16], dtype=tf.float32)

with tf.variable_scope("convs"):
    hidden_layer_1 = tf.nn.conv2d(input=inputs, filter=weights, stride=[1, 1, 1, 1], padding="SAME")
with tf.variable_scope("convs", reuse=True):
    hidden_layer_2 = tf.nn.conv2d(input=hidden_layer_1, filter=weights,stride=[1, 1, 1, 1], padding="SAME"

这会创建卷积权重并将其应用于您的输入两次。我没有测试过这段代码,所以可能存在错误,但它是关于它应该如何看待的。这里引用variable sharing,此处引用tf.nn.conv2d

希望这有帮助!我会更彻底,但我不知道你的代码是什么样的。