我正在尝试构建自定义变分自动编码器网络,其中我使用来自编码器层的权重转置来初始化解码器权重,我找不到 tf.contrib.layers 的原生内容.fully_connected 所以我使用了 tf.assign,这是我的层代码:
def inference_network(inputs, hidden_units, n_outputs):
"""Layer definition for the encoder layer."""
net = inputs
with tf.variable_scope('inference_network', reuse=tf.AUTO_REUSE):
for layer_idx, hidden_dim in enumerate(hidden_units):
net = layers.fully_connected(
net,
num_outputs=hidden_dim,
weights_regularizer=layers.l2_regularizer(training_params.weight_decay),
scope='inf_layer_{}'.format(layer_idx))
add_layer_summary(net)
z_mean = layers.fully_connected(net, num_outputs=n_outputs, activation_fn=None)
z_log_sigma = layers.fully_connected(
net, num_outputs=n_outputs, activation_fn=None)
return z_mean, z_log_sigma
def generation_network(inputs, decoder_units, n_x):
"""Define the decoder network."""
net = inputs # inputs here is the latent representation.
with tf.variable_scope("generation_network", reuse=tf.AUTO_REUSE):
assert(len(decoder_units) >= 2)
# First layer does not have a regularizer
net = layers.fully_connected(
net,
decoder_units[0],
scope="gen_layer_0",
)
for idx, decoder_unit in enumerate([decoder_units[1], n_x], 1):
net = layers.fully_connected(
net,
decoder_unit,
scope="gen_layer_{}".format(idx),
weights_regularizer=layers.l2_regularizer(training_params.weight_decay)
)
# Assign the transpose of weights to the respective layers
tf.assign(tf.get_variable("generation_network/gen_layer_1/weights"),
tf.transpose(tf.get_variable("inference_network/inf_layer_1/weights")))
tf.assign(tf.get_variable("generation_network/gen_layer_1/bias"),
tf.get_variable("generation_network/inf_layer_0/bias"))
tf.assign(tf.get_variable("generation_network/gen_layer_2/weights"),
tf.transpose(tf.get_variable("inference_network/inf_layer_0/weights")))
return net # x_recon
它使用这个 tf.slim arg_scope 包装:
def _autoencoder_arg_scope(activation_fn):
"""Create an argument scope for the network based on its parameters."""
with slim.arg_scope([layers.fully_connected],
weights_initializer=layers.xavier_initializer(),
biases_initializer=tf.initializers.constant(0.0),
activation_fn=activation_fn) as arg_sc:
return arg_sc
但是我收到错误:ValueError:尝试共享变量 VarAutoEnc/generation_network/gen_layer_1/weights,但指定了 dtype float32 并找到了 dtype float64_ref。
我已将其缩小到 get_variable 调用,但我不知道它为什么会失败。
如果有一种方法可以从另一个完全连接的层初始化 tf.contrib.layers.fully_connected 而无需 tf.assign 操作,那么该解决方案很好和我一起。
最佳答案
我无法重现您的错误。这是一个与您的代码相同的简约可运行示例:
import tensorflow as tf
with tf.contrib.slim.arg_scope([tf.contrib.layers.fully_connected],
weights_initializer=tf.contrib.layers.xavier_initializer(),
biases_initializer=tf.initializers.constant(0.0)):
i = tf.placeholder(tf.float32, [1, 30])
with tf.variable_scope("inference_network", reuse=tf.AUTO_REUSE):
tf.contrib.layers.fully_connected(i, 30, scope="gen_layer_0")
with tf.variable_scope("generation_network", reuse=tf.AUTO_REUSE):
tf.contrib.layers.fully_connected(i, 30, scope="gen_layer_0",
weights_regularizer=tf.contrib.layers.l2_regularizer(0.01))
with tf.variable_scope("", reuse=tf.AUTO_REUSE):
tf.assign(tf.get_variable("generation_network/gen_layer_0/weights"),
tf.transpose(tf.get_variable("inference_network/gen_layer_0/weights")))
代码运行时没有 ValueError。如果运行此程序时出现 ValueError,那么它可能是一个错误,已在后来的 tensorflow 版本中修复(我在 1.9 上测试过)。否则,错误是您未在问题中显示的代码的一部分。
顺便说一句,assign 将返回一个 op,一旦返回的 op 在 session 中运行,该 op 将执行分配。因此,您需要返回 generation_network 函数中所有 assign 调用的输出。您可以使用 tf.group 将所有分配操作捆绑在一起。
关于python - "ValueError: Trying to share variable $var, but specified dtype float32 and found dtype float64_ref"尝试使用 get_variable 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50588274/