【问题标题】:tensorflow: creating variables in fn of tf.map_fn returns value errortensorflow:在 tf.map_fn 的 fn 中创建变量返回值错误
【发布时间】:2017-08-21 05:25:22
【问题描述】:

我对 map_fn 中的变量初始化有疑问。

我试图在张量中的每个单独元素上分别应用一些高速公路层,所以我认为 map_fn 可能是最好的方法。

segment_list = tf.reshape(raw_segment_embedding,[batch_size*seqlen,embed_dim])
segment_embedding = tf.map_fn(lambda x: stack_highways(x, hparams), segment_list)

现在问题是我的 fn,即 stack_highways,创建变量,并且由于某种原因 tensorflow 无法初始化这些变量并给出此错误。

W = tf.Variable(tf.truncated_normal(W_shape, stddev=0.1), name='weight')

ValueError: Initializer for variable body/model/parallel_0/body/map/while/highway_layer0/weight/ is from inside a control-flow construct, such as a loop or conditional. When creating a variable inside a loop or conditional, use a lambda as the initializer. 

我现在很无能,基于错误我认为这与范围无关,但我不知道如何使用 lambda 作为初始化程序(我什至不知道这到底是什么意思)。 以下是stack_highways的实现,任何建议将不胜感激..

def weight_bias(W_shape, b_shape, bias_init=0.1):
  """Fully connected highway layer adopted from 
     https://github.com/fomorians/highway-fcn/blob/master/main.py
  """
  W = tf.Variable(tf.truncated_normal(W_shape, stddev=0.1), name='weight')
  b = tf.Variable(tf.constant(bias_init, shape=b_shape), name='bias')
  return W, b




def highway_layer(x, size, activation, carry_bias=-1.0):
  """Fully connected highway layer adopted from 
     https://github.com/fomorians/highway-fcn/blob/master/main.py
  """
  W, b = weight_bias([size, size], [size])
  with tf.name_scope('transform_gate'):
    W_T, b_T = weight_bias([size, size], bias_init=carry_bias)


    H = activation(tf.matmul(x, W) + b, name='activation')
    T = tf.sigmoid(tf.matmul(x, W_T) + b_T, name='transform_gate')
    C = tf.sub(1.0, T, name="carry_gate")


    y = tf.add(tf.mul(H, T), tf.mul(x, C), name='y') # y = (H * T) + (x * C)
    return y




def stack_highways(x, hparams):
  """Create highway networks, this would not create
  a padding layer in the bottom and the top, it would 
  just be layers of highways.


  Args:
    x: a raw_segment_embedding
    hparams: run hyperparameters


  Returns:
    y: a segment_embedding
  """
  highway_size = hparams.highway_size
  activation = hparams.highway_activation #tf.nn.relu
  carry_bias_init = hparams.highway_carry_bias
  prev_y = None
  y = None
  for i in range(highway_size):
    with tf.name_scope("highway_layer{}".format(i)) as scope:
      if i == 0: # first, input layer
        prev_y = highway_layer(x, highway_size, activation, carry_bias=carry_bias_init)
      elif i == highways - 1: # last, output layer
        y = highway_layer(prev_y, highway_size, activation, carry_bias=carry_bias_init)
      else: # hidden layers
        prev_y = highway_layer(prev_y, highway_size, activation, carry_bias=carry_bias_init)
  return y

最诚挚的问候, 科尔曼

【问题讨论】:

    标签: python-3.x lambda tensorflow


    【解决方案1】:

    TensorFlow 提供了两种主要的变量初始化方式:

    1. “lambda”初始化程序:返回初始化值的可调用程序。 TF 提供了很多包装精美的ones
    2. 按张量值初始化:这是您当前使用的。

    错误消息指出,当使用来自while_loopmap_fn 在内部调用)中的变量时,您需要使用第一种类型的初始化程序。 (总的来说,lambda 初始化器对我来说似乎更健壮。)

    另外过去,tf.get_variable seems to be preferred over tf.Variable when used from within control flow

    所以,我怀疑您可以通过将 weight_bias 函数修复为以下内容来解决您的问题:

    def weight_bias(W_shape, b_shape, bias_init=0.1):
      """Fully connected highway layer adopted from 
         https://github.com/fomorians/highway-fcn/blob/master/main.py
      """
      W = tf.get_variable("weight", shape=W_shape,
              initializer=tf.truncated_normal_initializer(stddev=0.1))
      b = tf.get_variable("bias", shape=b_shape,
              initializer=tf.constant_inititializer(bias_init))
      return W, b
    

    希望有帮助!

    【讨论】:

    • 感谢您的回答,直到今天我才知道初始化程序和 get_variable 的用法。
    • @suharshs 当我使用以下命令时,这在 tf-gpu=1.5.0 中不起作用:gru_fw = tf.contrib.cudnn_rnn.CudnnGRU( 1, num_units, kernel_initializer=tf.random_normal_initializer(stddev=0.1)) 在条件构造下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多