《TensorFlow自然语言处理》—2.3 使用作用域重用变量
2.3 使用作用域重用变量
到目前为止,我们已经了解了TensorFlow的体系结构,以及实现基本TensorFlow客户端所需的基本知识。然而,TensorFlow还有更多内容。正如我们已经看到的,TensorFlow的行为与典型的Python脚本完全不同。例如,你无法实时调试TensorFlow代码(但可以用Python IDE执行简单的Python脚本),因为在TensorFlow中计算不会实时发生(除非你使用的是Eager执行方法,它最近出现在TensorFlow1.7中:https://research.googleblog.com/2017/10/eager-execution-imperative-def?ine-by.html)。换句话说,TensorFlow首先定义完整的计算图,再在设备上执行所有计算,最后得到结果。因此,调试TensorFlow客户端可能会非常烦琐和痛苦,这强化了在实现TensorFlow客户端时注意细节的重要性。因此,建议遵循为TensorFlow引入的正确编码规范。一种这样的规范被称为“作用域”,并允许更容易的变量重用。
重用TensorFlow变量是TensorFlow客户端中经常出现的情况。要理解答案的价值,我们必须首先理解这个问题。此外,错误的代码可以帮助我们更好理解这个问题。
假设我们想要一个执行某种计算的函数:给定w,需要计算x * w + y ** 2。让我们编写一个TensorFlow客户端,它具有执行此操作的函数:
假设你想要在某一步计算它,然后,你可以调用session.run(very_simple_computation(2))
(当然,在调用tf.global_variables_initializer().run()之后),之后你会得到结果,并对编写实际有效的代码感觉良好。但是,情况可能相反,因为多次运行此函数会出现问题。每次调用此方法时,都会创建两个TensorFlow变量。还记得我们讨论过TensorFlow与Python不同吗这就是一个这样的例子。多次调用此方法时,图中的x和y变量不会被替换。相反,将保留旧变量,并在图中创建新变量,直到内存不足为止。但是,结果是正确的。要查看此操作,请在for循环中运行session.run(very_simple_computation(2)),如果打印图中变量的名称,将看到两个以上变量。
这是运行10次时的输出:
每次运行该函数时,都会创建一对变量。让我们明确一点:如果你运行这个函数100次,你的图中将有198个过时变量(99个x变量和99个y变量)。
这是作用域可以解决的问题。作用域允许你重用变量,而不是每次调用函数时都创建一个变量。现在为我们的小例子添加可重用性,我们将代码更改为以下内容:
在这个例子中,如果执行session.run([z1,z2,a1,a2,zz1,zz2]),应该看到z1、z2、a1、a2、zz1、zz2的值依次为9.0、90.0、9.0、90.0、9.0、90.0。现在,如果打印变量,你应该只看到四个不同的变量:scopeA/x,scopeA/y,scopeB/x和scopeB/y。我们现在可以在循环中多次运行它,而不必担心创建冗余变量和内存不足。
现在,你可能想知道为什么不能在代码的开头创建四个全局变量,并在之后的方法中使用它们。因为这会破坏代码的封装,这样一来,代码将明确依赖于该代码块之外的内容。
总之,作用域允许可重用性,同时保留代码的封装性。此外,作用域使代码更直观,并减少出错的可能性,因为我们可以通过域和名称显式获取变量,而不是使用被TensorFlow变量赋值的Python变量。
- 点赞
- 收藏
- 关注作者
评论(0)