在 TensorFlow 中,tf.identity 有啥用?

Posted

技术标签:

【中文标题】在 TensorFlow 中,tf.identity 有啥用?【英文标题】:In TensorFlow, what is tf.identity used for?在 TensorFlow 中,tf.identity 有什么用? 【发布时间】:2016-04-24 23:16:15 【问题描述】:

我在一些地方看到过tf.identity,例如官方 CIFAR-10 教程和 *** 上的批量标准化实现,但我不明白为什么有必要。

它是做什么用的?谁能给出一两个用例?

一个建议的答案是它可以用于 CPU 和 GPU 之间的传输。这对我来说不是很清楚。问题的扩展,基于this:loss = tower_loss(scope) 在 GPU 块下,这向我表明tower_loss 中定义的所有运算符都映射到 GPU。然后,在tower_loss 的末尾,我们在返回之前看到total_loss = tf.identity(total_loss)。为什么?在这里不使用tf.identity会有什么缺陷?

【问题讨论】:

一个很好的用法 here 用于 tf.identity 和梯度计算 超链接已损坏.. 用于制作张量的副本 【参考方案1】:

我看到了这种检查断言的技巧:

assertion = tf.assert_equal(tf.shape(image)[-1], 3, message="image must have 3 color channels")
with tf.control_dependencies([assertion]):
    image = tf.identity(image)

它也只是用来给一个名字:

image = tf.identity(image, name='my_image')

【讨论】:

【参考方案2】:

当我们的输入数据以字节为单位序列化时,我们想要从该数据集中提取特征。我们可以以键值格式执行此操作,然后为其获取占位符。当有多个特征并且必须以不同的格式读取每个特征时,它的好处会更加明显。

  #read the entire file in this placeholder      
  serialized_tf_example = tf.placeholder(tf.string, name='tf_example')

  #Create a pattern in which data is to be extracted from input files
  feature_configs = 'image': tf.FixedLenFeature(shape=[256], dtype=tf.float32),/
                     'text': tf.FixedLenFeature(shape=[128], dtype=tf.string),/
                     'label': tf.FixedLenFeature(shape=[128], dtype=tf.string),

  #parse the example in key: tensor dictionary
  tf_example = tf.parse_example(serialized_tf_example, feature_configs)

  #Create seperate placeholders operation and tensor for each feature
  image = tf.identity(tf_example['image'], name='image')
  text  = tf.identity(tf_example['text'], name='text')
  label = tf.identity(tf_example['text'], name='label')

【讨论】:

这个答案只是为了展示 tf.identity() 的另一个用例。【参考方案3】:

在分布式训练中,我们应该使用tf.identity,否则worker会一直等待着主worker初始化:

vec = tf.identity(tf.nn.embedding_lookup(embedding_tbl, id)) * mask
with tf.variable_scope("BiRNN", reuse=None):
    out, _ = tf.nn.bidirectional_dynamic_rnn(fw, bw, vec, sequence_length=id_sz, dtype=tf.float32)

具体来说,在没有身份的情况下,首席工作者会不恰当地将某些变量视为局部变量,而其他工作者会等待无法结束的初始化操作

【讨论】:

【参考方案4】:

除了上述之外,我只是在需要为没有名称参数的操作分配名称时使用它,就像在 RNN 中初始化状态时一样:

rnn_cell = tf.contrib.rnn.MultiRNNCell([cells])
# no name arg
initial_state = rnn_cell.zero_state(batch_size,tf.float32)
# give it a name with tf.identity()
initial_state = tf.identity(input=initial_state,name="initial_state")

【讨论】:

只找这个【参考方案5】:

我在 Tensorboard 中发现了 tf.identity 的另一个应用。 如果使用 tf.shuffle_batch,它会一次返回多个张量,因此在可视化图形时会看到混乱的画面,无法将张量创建管道与实际输入张量分开:messy

但是使用 tf.identity 可以创建不影响计算流程的重复节点:nice

【讨论】:

如果输出是张量列表,我可以直接使用identity还是先使用stack,然后使用identity?什么是最好的方法。 假设您有一个带有 2 个参数的图形:图像和标签。您已经实现了两种提供值的方法:使用占位符和使用tf.shuffle_batch。您想很好地可视化您的图表。让我们拆分训练子图和批量生成子图。使用占位符很容易。但是批处理不是:如果您将操作 tf.shuffle_batch 放入范围 batch_generation 并将其他操作放入范围 modelmodel 内没有 INPUT 节点。我建议将 tf.identity 直接应用于 tf.shuffle_batch 生成的每个向量,并将它们移动到model scope 嗨 grihabor,您介意分享您的代码 sn-p 吗?【参考方案6】:

我遇到了其他答案未完全涵盖的另一个用例。

def conv_layer(input_tensor, kernel_shape, output_dim, layer_name, decay=None, act=tf.nn.relu):
    """Reusable code for making a simple convolutional layer.
    """
    # Adding a name scope ensures logical grouping of the layers in the graph.
    with tf.name_scope(layer_name):
        # This Variable will hold the state of the weights for the layer
        with tf.name_scope('weights'):
            weights = weight_variable(kernel_shape, decay)
            variable_summaries(weights, layer_name + '/weights')
        with tf.name_scope('biases'):
            biases = bias_variable([output_dim])
            variable_summaries(biases, layer_name + '/biases')
        with tf.name_scope('convolution'):
            preactivate = tf.nn.conv2d(input_tensor, weights, strides=[1, 1, 1, 1], padding='SAME')
            biased = tf.nn.bias_add(preactivate, biases)
            tf.histogram_summary(layer_name + '/pre_activations', biased)
        activations = act(biased, 'activation')
        tf.histogram_summary(layer_name + '/activations', activations)
        return activations

大多数时候,在构建卷积层时,您只需要返回激活值,以便将它们输入下一层。但是,有时(例如在构建自动编码器时)您需要预激活值。

在这种情况下,一个优雅的解决方案是将tf.identity 作为激活函数传递,有效地不激活层。

【讨论】:

如果输出是张量列表,我可以直接使用identity还是先使用stack,然后使用identity?最好的方法是什么。【参考方案7】:

经过一番磕磕绊绊后,我想我注意到了一个适合我所见过的所有示例的单个用例。如果还有其他用例,请举例说明。

用例:

假设您想在每次评估特定变量时运行一个运算符。例如,假设您想在每次评估变量 y 时向 x 添加一个。这似乎可行:

x = tf.Variable(0.0)
x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = x
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())

它没有:它会打印 0、0、0、0、0。相反,我们似乎需要在 control_dependencies 块内的图形中添加一个新节点。所以我们使用这个技巧:

x = tf.Variable(0.0)
x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = tf.identity(x)
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())

这有效:它打印 1、2、3、4、5。

如果在 CIFAR-10 教程中我们删除了 tf.identity,那么 loss_averages_op 将永远不会运行。

【讨论】:

如果这对其他人来说并不明显,docs 明确指出“控制依赖上下文仅适用于在上下文中构造的操作。仅在上下文不添加控制依赖。”所以我们需要tf.identity 在控制依赖上下文中做一个额外的操作。 y=x 不会创建新的操作,它与 x 共享相同的内存对象,因此不能在 control_dependency 中使用。另一方面, tf.identity 确实创建了一个新操作。更重要的是,y = x + 0 也创建了一个新的 op,所以你可以把身份想成 y = x+0【参考方案8】:

tf.identity 在您想在设备之间显式传输张量(例如,从 GPU 到 CPU)时很有用。 op在图中添加send/recv节点,当输入和输出的设备不同时进行复制。

默认行为是,当操作发生在不同的设备上时,会隐式添加发送/接收节点,但您可以想象某些情况(尤其是在多线程/分布式设置中),获取值可能有用在session.run 的一次执行中多次使用变量。 tf.identity 允许对何时应从源设备读取值进行更多控制。可能更适合此操作的名称是 read

另外,请注意在tf.Variablelink的实现中,在构造函数中添加了标识操作,这确保了对变量的所有访问只从源复制数据一次。如果变量位于 GPU 上但由多个 CPU 操作(或相反)读取,则多个副本可能会很昂贵。用户可以在需要时通过多次调用tf.identity 来更改行为。

编辑:编辑问题后更新答案。

此外,tf.identity 可以用作虚拟节点来更新对张量的引用。这对各种控制流操作很有用。在 CIFAR 案例中,我们希望强制 ExponentialMovingAverageOp 在检索损失值之前更新相关变量。这可以实现为:

with tf.control_dependencies([loss_averages_op]):
  total_loss = tf.identity(total_loss)

在这里,tf.identity 除了在评估 loss_averages_op 之后标记要运行的 total_loss 张量之外没有任何用处。

【讨论】:

如果可能的话,你能评论我上面的更新吗?具体来说,如果我们省略 total_loss = tf.identity(total_loss) 行,tensorflow.googlesource.com/tensorflow/+/master/tensorflow/… 会出现什么问题? 嘿干得好,在我写完一个小时后把我的答案包括在你的答案中?

以上是关于在 TensorFlow 中,tf.identity 有啥用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 tensorflow 2.5 中运行 tensorflow 分析

TensorFlow Hub 模块可以在 TensorFlow 2.0 中使用吗?

显式 tensorflow 会话在 Tensorflow/nmt 中给出获取错误

tensorflow环境下安装Python包

tensorflow 传入值-老鱼学tensorflow

Tensorflow 2.2.0-rc4 AttributeError:模块'tensorflow.compat.v1'在Spyder中没有属性'contrib'?