专栏名称: 机器学习研究会
机器学习研究会是北京大学大数据与机器学习创新中心旗下的学生组织,旨在构建一个机器学习从事者交流的平台。除了及时分享领域资讯外,协会还会举办各种业界巨头/学术神牛讲座、学术大牛沙龙分享会、real data 创新竞赛等活动。
目录
相关文章推荐
爱可可-爱生活  ·  [CL]《Fooling LLM ... ·  昨天  
爱可可-爱生活  ·  [LG]《Convergence of ... ·  2 天前  
爱可可-爱生活  ·  “模型坍缩速度真的有我们想象的那么快吗?” ... ·  3 天前  
爱可可-爱生活  ·  “让翻译工作彻底自动化” - ... ·  3 天前  
爱可可-爱生活  ·  //@爱可可-爱生活:今日开奖,欢迎参与~- ... ·  3 天前  
51好读  ›  专栏  ›  机器学习研究会

如何将TensorFlow用作计算框架

机器学习研究会  · 公众号  · AI  · 2017-11-03 22:49

正文

Tensorflow可能是最受欢迎,增长最快的机器学习框架。在Github拥有超过70000个点赞,并得到Google的支持,不仅拥有比Linux更多的点赞,还拥有大量的资源。


如果那都不能激起你的兴趣,我不知道还会有什么可以引起你的兴趣。


如果你以前一直在关注机器学习101系列,你会注意到我们已经使用sklearn框架来实现我们的模型。然而,当我们开始勇于进入神经网络,深度学习和一些算法的内部运作时,我们将开始使用Tensorflow框架,该框架具有访问更多低级API的能力,为我们提供在模型上更细致的控制。


因此,我们将花费一些时间熟悉Tensorflow及其设计理念,以便我们在后续教程中可以开始使用它,而无需介绍。


在本教程中,我们将讨论:


  • 总体设计理念

  • 可视化

  • 涵盖常见用例的示例

  • 它与机器学习有什么关系?


在官方白皮书中,Tensorflow被描述为“用于表达机器学习算法的接口和用于执行这种算法的实现”。 它比其他框架的主要优点是在各种设备上执行代码非常容易。这与它在开源之前的发展动机有关。 Google最初开发了Tensorflow来弥合研究与生产之间的差距,希望从研究到生产都不需要对代码进行编辑。


Tensorflow是用于表达机器学习算法的接口,以及用于执行这种算法的实现。


为了实现这一点,Tensorflow在幕后实现一个计算图; 在你的代码中,你只是定义那个图:张量的流动。


那么,什么是张量?


就像一个向量可以看作是一个数组或列表,标量(普通数字1, 2,PI),那么矩阵可以看作数组向量,张量可以认为是矩阵数组。所以张量实际上是一个n维矩阵。事实上,正如我们在编码示例中所看到的那样,这种架构在使进行机器学习时非常有意义。


流动是什么呢?


流动是张量如何在网络中传递。当张量传递时,它们的值和形状由图运算更新。


做个比喻,你可以把图形想象成一个拥有一系列工作站的汽车工厂。一个站可以装上汽车的轮子,另一个安装变速箱。然后,流程描述一个汽车骨架必须采取的路线,以便成为一个全功能的汽车。这个比喻中传递的张量是汽车原型或骨架。




安装Tensorflow


你可以使用以下命令使用pip安装Tensorflow:



或者如果你有一个GPU:



请注意,如果要安装GPU版本,则需要安装CUDA和cuDNN。


撰写本文时,Tensorflow(v1.3)支持CUDA 8和CUDNN 6。


安装Tensorflow后,你可以使用以下方法验证所有操作是否正常:


有关详细信息,请参阅安装页面(https://www.tensorflow.org/install/?spm=5176.100239.blogcont230077.16.BGjh5J )。


Tensorflow的原子


我们已经讨论过Tensorflow是否是张量的流动,但是我们没有详细介绍。为了更好地证明架构的正确性,我们将详细阐述这个问题。


三种类型的张量


在Tensorflow中,有三种主要的张量类型:


  • tf.Variable


  • tf.constant


  • tf.placeholder 


看一看其中的每一个,讨论它们之间的差异,以及何时使用这些,是值得的。


tf.Variable


tf.Variable张量是最直接的基本张量,并且在很多方面类似于纯Python变量,因为它的值是很好的变量。


变量在整个会话控制期间保留其值,因此在定义可学习的参数(如神经网络中的权重)或其他任何将随代码运行而改变的参数时很有用。

你可以按如下方式定义一个变量:



在这里,我们创建一个具有初始状态[1,2,3]和名称a的张量变量。 请注意,Tensorflow无法继承Python变量名称,因此,如果要在图形上有一个名称(稍后将会有更多的名称),则需要指定一个名称。


还有几个选项,但这只是为了涵盖基础知识。与这里讨论的任何事情一样,你可以在文档页面上阅读更多信息。


tf.constant


tf.Constant与tf.Variable非常相似,有一个主要区别,它们是不可变的,就是值是恒定的。

tf.Variable张量的用法如下:



当你有一个不通过代码执行改变的值,例如表示数据的某些属性,或者在使用神经网络来存储学习速率时,就使用这个。


tf.placeholder


最后,我们解释tf.placeholder张量。 顾名思义,该张量类型用于定义您没有初始值的变量或图形节点(操作)。然后,你可以延迟设置值,直到实际使用sess.run进行计算。这在定义网络时可用作培训数据的代理。


运行操作时,需要传递占位符的实际数据。是这样做的:



请注意,我们先通过元素类型(这里是tf.int32)的非可选参数来定义占位符,然后使用矩阵维符号定义形状。 [1,2]表示具有1行和2列的矩阵。 如果你没有研究线性代数,这可能看起来很混乱:为什么表示宽度之前的高度?并且不是[1,2] a 1乘以2的矩阵本身的值1和2?


这些是有效的问题,但深入的答案超出了本文的范围。 然而,告诉你它的要点,奇怪的符号形式显然有一些很整齐的记忆特性的矩阵运算,[ 1,2 ]也可以被看作是一个由两个矩阵本身。Tensorflow使用像符号这样的列表,因为它支持n维矩阵,因此非常方便,我们将在后面看到。


你可以在这里找到支持Tensorflow数据类型的完整列表。


当我们用sess.run评估c的值时,我们使用feed_dict传入实际的数据。 请注意,我们使用Python变量名称,而不是给予Tensorflow图形的名称来定位占位符。 同样的方法也扩展到多个占位符,其中每个变量名映射到相同名称的字典键。


定义形状时的通配符


有时候,当你定义时,你不知道一些,或者一个占位符的整个形状。例如,你可以在训练时使用变量批量大小,这是通配符进入的地方。


通配符基本上允许你说“我不知道”给Tensorflow,并且让它从传入张量推断形状。


-1和None有什么区别?


老实说,我试图弄清楚这个的答案,但是我没有找到任何记录的差异,而在Tensorflow的源代码中我挖掘的小部分也没有产生任何结果。 但是,我遇到了一些例子,其中一个会引发错误,而另一个则不会。


在这两个中,None似乎对我来说使用更好,所以我一直使用,如果我收到与占位符大小相关的错误,我尝试将其更改为-1,但我觉得它们应该是等价的。


为什么不只是通配符?!


具有明确的形状可以帮助调试,因为很多错误将被捕获在“编译时间”,而不是在训练的时候,这使你更快地发现错误,并且它确保错误不会默默地爬行(至少它尝试了)。


所以为了避免以后的麻烦,你应该只使用通配符来描述一些变量,如输入大小,而不是一些静态的,如网络参数大小。


基本计算实例


了解了变量如何工作,我们现在可以看看如何创建更复杂的交互。


Tensorflow中的图形包含互连操作(ops)。OP本质上是一个函数,即任何需要输入并产生某些输出的函数。正如我们之前讨论过的,Tensorflow的默认数据类型是张量,所以操作可以说是进行张量操作。

看一个非常基本的例子,乘以两个标量,可以这样做:



请注意,当我们打印结果时,我们得到另一个Tensor,而不是实际结果。另外,请注意,变量具有shape(),这是因为标量是零维张量。最后,因为我们没有指定一个名字,所以我们得到名字'Variable_4:0'和'Variable_5:0',这意味着它们在图形0上是变量4和5。


要获得实际结果,我们必须在会话的上下文中计算值。 这可以这样做:



你也可以使用tf.InteractiveSession,如果你使用像IDLE或者jupyter笔记本这类的,这很有用。 此外,还可以通过声明sess = tf.Session()来开始一个会话控制,然后使用sess.close()关闭它,但是我不建议这样做,因为很容易忘记关闭会话会话控制, 使用此方法作为交互式会话可能对性能会有影响,因为Tensorflow真的喜欢占用尽可能多的资源(在这方面有点像Chrome)。


我们首先创建一个向Tensorflow发出信号的会话,我们要开始进行实际的计算。 在幕后,Tensorflow做了一些事情; 它选择一个设备来执行计算(默认情况下是你的第一个CPU),并初始化计算图。 虽然你可以使用多个图,但通常建议仅使用一个,因为不通过Python(我们建立的是慢的),两个图形之间的数据无法发送。即使你有多个断开连接的部件也是如此。


接下来我们初始化变量。 为什么在开始会话时不能这样做,我不知道,但它填充了图中变量的值,所以我们可以在我们的计算中使用它们。 这是这些小烦恼之一,你必须记住每次你想要计算的东西。


你可能记得,Tensorflow真的很懒,想尽可能少做。因此,你必须明确告诉Tensorflow来初始化变量。


Tensorflow是懒的


了解更多细节可能是有用的,因为了解如何以及为什么选择Tensorflow非常重要。


Tensorflow喜欢延长计算时间。 它是这样做的,因为Python很慢,所以它想要在Python之外运行计算。 通常,我们使用诸如numpy之类的库来实现这一点,但是在Python和优化的库之间传输数据(如numpy)是非常昂贵的。


Tensorflow通过首先使用Python定义一个图而不做任何计算,然后将所有数据发送到Python之外的图形,使用高效的GPU库(CUDA)可以运行。 这样,将数据传输所花的时间保持在最低限度。


因此,Tensorflow只需要计算实际需要的图形部分。当你运行操作来发现计算所依赖的所有依赖项时,它通过网络传播回来,并且仅计算它们。它忽略了网络的其余部分。

请思考以下代码:




转自:云栖社区


完整内容请点击“阅读原文”