我使用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而不是密集层。怎么做?
答案 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。
希望这有帮助!我会更彻底,但我不知道你的代码是什么样的。