【问题标题】:How do I efficiently track the history of a tensorflow tensor?如何有效地跟踪张量流张量的历史?
【发布时间】:2019-07-09 21:02:39
【问题描述】:

这种使用TensorArray 的模式是跟踪张量历史的有效方式吗?内部循环中的所有内容都是在 GPU 上完成的,而没有向 CPU 传输任何内容吗?我该如何验证?

import tensorflow as tf


with tf.device('/device:GPU:0'):
    @tf.function
    def f(x, y):
        return y, x + y

    x_array = tf.TensorArray(tf.float32, 0, dynamic_size=True,
                             clear_after_read=False)
    y_array = tf.TensorArray(tf.float32, 0, dynamic_size=True,
                             clear_after_read=False)

    x = tf.Variable([1.0])
    y = tf.Variable([1.0])
    x_array.write(0, x)
    y_array.write(0, y)

    for i in tf.range(10):
        x = x_array.read(i)
        y = y_array.read(i)
        new_x, new_y = f(x, y)
        x_array.write(i + 1, new_x)
        y_array.write(i + 1, new_y)

    print(x_array.stack())
    print(y_array.stack())

这是我真正想要做的,但它甚至没有运行:

import tensorflow as tf


with tf.device('/device:GPU:0'):
    @tf.function
    def f(x, y):
        return y, x + y

    @tf.function
    def g(n):
        for i in tf.range(n):
            x = x_array.read(i)
            y = y_array.read(i)
            new_x, new_y = f(x, y)
            x_array.write(i + 1, new_x)
            y_array.write(i + 1, new_y)

    x_array = tf.TensorArray(tf.float32, 0, dynamic_size=True,
                             clear_after_read=False)
    y_array = tf.TensorArray(tf.float32, 0, dynamic_size=True,
                             clear_after_read=False)

    x = tf.Variable([1.0])
    y = tf.Variable([1.0])
    x_array.write(0, x)
    y_array.write(0, y)

    g(tf.constant(10))

    print(x_array.stack())
    print(y_array.stack())

【问题讨论】:

    标签: python-3.x tensorflow tensorflow2.0


    【解决方案1】:

    以下是修复第二个 sn-p 的方法:

    import tensorflow as tf
    
    with tf.device('/device:GPU:0'):
        @tf.function
        def f(x, y):
            return y, x + y
    
        @tf.function
        def g(x, y, n):
            x_array = tf.TensorArray(tf.float32, n + 1, dynamic_size=False,
                                     clear_after_read=True)
            y_array = tf.TensorArray(tf.float32, n + 1, dynamic_size=False,
                                     clear_after_read=True)
            x_array = x_array.write(0, x)
            y_array = y_array.write(0, y)
            for i in range(n):
                x, y = f(x, y)
                x_array = x_array.write(i + 1, x)
                y_array = y_array.write(i + 1, y)
            return x_array.stack(), y_array.stack()
    
    
        x = tf.Variable([1.0])
        y = tf.Variable([1.0])
    
        x_hist, y_hist = g(x, y, tf.constant(10))
    
        print(x_hist)
        # tf.Tensor(
        # [[ 1.]
        #  [ 1.]
        #  [ 2.]
        #  [ 3.]
        #  [ 5.]
        #  [ 8.]
        #  [13.]
        #  [21.]
        #  [34.]
        #  [55.]
        #  [89.]], shape=(11, 1), dtype=float32)
        print(y_hist)
        # tf.Tensor(
        # [[  1.]
        #  [  2.]
        #  [  3.]
        #  [  5.]
        #  [  8.]
        #  [ 13.]
        #  [ 21.]
        #  [ 34.]
        #  [ 55.]
        #  [ 89.]
        #  [144.]], shape=(11, 1), dtype=float32)
    

    有一些问题。 tf.function 应该将其输入作为参数,而不是来自全局范围。您可以在函数中创建张量数组,并且可以将它们设置为固定大小并在读取后清除,因为之后您将不再使用它们。但重要的是您将每个write 操作的结果分配给数组变量,因为这将使其成为“写入后的张量数组”。您不需要在循环中使用tf.range。并且“历史”数组可以通过写入每次迭代的结果来更有效地填充,而不是从数组中再次读取。

    关于 GPU,由于所有内容都在 tf.device 上下文中,因此所有内容都将在 GPU 上分配并运行,如果某些内容无法在 GPU 上运行,则会出现错误,因此只要一切正常,就应该没问题。

    【讨论】:

    • 谢谢!但是现在你传入xy,我很担心,因为我实际上有一百个这样的变量和TensorArrays。我希望将它们放入字典或对象中。这样做的惯用 TensorFlow 方式是什么?我会将它们放入 keras 层吗?
    • @NeilG 我不了解您的实际用例,所以我无法确定,但我认为拥有数百个独立变量并不常见,而是拥有数百个(或更多)的价值。但无论如何,我想您可以将对象中的所有这些作为属性。但是,我不确定tf.function 是否支持迭代张量集合,因为我在尝试使用它时遇到了错误......
    • 感谢您的浏览。我遇到了同样的问题,但更多的调查表明我应该使用AbstractRNNCell 来实现一个状态随每次迭代而变化的对象。 github.com/tensorflow/tensorflow/blob/master/RELEASE.md
    • @NeilG Ahh 我想我现在明白了,谢谢你的反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2017-12-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多