草庐IT

python - "ValueError: Trying to share variable $var, but specified dtype float32 and found dtype float64_ref"尝试使用 get_variable 时

coder 2023-08-21 原文

我正在尝试构建自定义变分自动编码器网络,其中我使用来自编码器层的权重转置来初始化解码器权重,我找不到 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/

有关python - "ValueError: Trying to share variable $var, but specified dtype float32 and found dtype float64_ref"尝试使用 get_variable 时的更多相关文章

随机推荐