一. TensorFlow介绍与安装
深度学习火的一塌糊涂,我们都知道TensorFlow是Google开源的一款人工智能学习库。我们来一起解读下tenrflow到底啥意思:Tensor的意思是张量,代表N维数组;Flow的意思是流,代表基于数据流图的计算。把N维数字从流图的一端流动到另一端的过程,就是人工智能神经网络进行分析和处理的过程。
1.1 TensorFlow介绍
TensorFlow的基本规则很简单,总体来说分两步:
首先,定义一个满足计算任务的图,图中有很多节点,接下来TensorFlow用优化后的C 代码进行高效的计算。我们来看一个简单的例子:
上图表示定义的一个简单方程计算任务,通过调用TensorFlow库便可以对该任务进行计算。我们知道,任何一门编程语言都可以进行计算如此简单的方程任务,那么我们为什么要用TensorFlow呢?
对于这个简单的方程计算,我们当然可以不用TensorFlow计算,这里我们作为一个例子来一起学习下为什么要用TensorFlow来计算。一个重要的因素就是,TensorFlow支持将一个图计算任务,拆分成多个块(如下图):
然后通过多个CPU或GPU进行并行交叉运算,另外TensorFlow还支持分布式计算。因此我们在巨大的数据量的情况下训练庞大的神经网络的时候,就不会有那么大的压力。
在当前的深度学习库中,有很多开源的学习库,如下表:
我们为什么选择TensorFlow库呢?
我们详细看下TensorFlow有什么优势:
- 多平台运行,Windows,Linux,macOS,IOS和Android等
- 提供简单的Python API (TELearn²) 兼容SciKit-Learn机器学习库
- 提供简单API (TF-slim)去建立训练和评价神经网络模型
- 包含很多机器学习方法的高性能的C 优化代码
- 强大的可视化(TensorBoard)可以查看计算过程,比如学习曲线
- TensorFlow还可以在谷歌云上进行计算图
当然,TensorFlow的优势不只上面所列,还有很多,我们一起学习和发掘。
1.2 TensorFlow安装
安装TensorFlow在Python中和安装其他库类似,可以用pip进行安装,也可以直接在Pycharm或Anaconda中进行安装。当然,机器支持GPU的话,建议安装GPU版本。so easy, 这里不再详述。
二. TensorFlow之牛刀小试
上节讲到,对于TensorFlow的操作分为两个步骤,首先是创建图,然后计算。在这里我们一起学习创建图和运行的几种方法,管理图和节点的生命周期。
2.1 创建图
以上节描述的图为例,如何创建呢?如下代码,即创建了该方程计算图:
这里需要注意的一点就是,虽然代码看起来好像做了一些计算,特别是最后一行,上面的代码中仅仅是在默认图中添加了一些节点而已,并没有去计算函数的值,甚至连变量初始化都没有做。那么如何计算上面的图呢?
2.2 运行图的常见方法
- 为了计算上图方程,TensorFlow中需要开启一个session,并用这个session去初始化变量并且做最终计算。如下代码:
上面的方法有一个缺点,就是需要重复代码sess.run()来对变量进行初始化,并且需要手动关闭session,这样显得有些繁琐。
- 这里我们介绍一种略微方便的一种方法,如下:
在这个with语句中,这个sess被设置为默认的session,也就是说语句x.initializer.run()相当于tf.get_default_session().run(x.initializer),并且f.eval()相当于调用tf.get_default_session().run(f),这种运行图的方法比较易读,并且自动关闭session,不需要我们手动关闭。关于图的管理,下面会介绍。
- 上面介绍的两种运行图的方法都需要手动初始化每一个变量,但是对于大型的神经网络计算图来说,这无疑是自找麻烦,这里介绍一种自动初始化变量的方法:
在这个方法中,我们通过调用函数tf.global_variables_initializer(),代替了手动逐一初始化。但是这里需要注意的是,这个函数实际上并没有立即对变量进行初始化,而是在运行的时候才进行初始化。
- 其实在python或者在jupyter 中,一般更喜欢这样运行图:
这种创建session的方法设置自己是默认的session,并且需要手动关闭session。但是这样减少了with语句的应用,使得看起来更为简洁。
从上面的方法可以看出,一个TensorFlow的程序明显的分为两部分,第一部分是创建一个计算图也称为创建阶段,第二部分是计算该图,也称为执行阶段。创建阶段一般是创建一个机器学习需要训练的模型,而执行阶段一般是执行训练过程。下节我们将会看到一实例。
2.3 图的管理
对于我们创建的任何一个节点,都会放到默认的图中(系统会默认创建一个),在大多数情况下,这样没问题且能满足我们的应用需求的,如下:
但是,有时候我们可能需要同时管理多个独立的图,这时可以通过新建一个图并临时把该图作为一个默认图(因为我们添加的节点默认情况下是在默认图中),如下,在with语句中,x2所在的图还是默认图,但是with语句之外x2所在的图已经不是默认图了。也就是说graph只有在with语句中才是默认图,一旦出了with语句,默认图自动变为系统创建的默认图。
很多时候,我们在测试的时候,会重复运行一段代码,那么我们会结束一个包含很多节点的图,如果不reset默认图的话,那么默认图会有很多冗余的节点,暂用资源,一般reset默认图有两种方法,比如在jupyter中,其中一个方法就是重启jupyter kernel,但是常用的另一种方法是通过运行代码tf.reset_default_graph()来结束默认图。
2.4 节点的生命周期
当我们需要计算一个节点的时候,TensorFlow会自动判断该节点所依靠的其他节点,并先计算所以靠的其他节点值。如下:
当我们需要计算y的值的时候,TensorFlow会自动检测到y的值依靠x,而x依靠w,并且会先计算w的值,再计算x的值,最后计算y的值。而当计算z值的时候会重复上面的步骤,并不会去调用计算y的时候计算出来的x的值。也就是说会计算两次w和x的值。
其实在不同的图之间运行,TensorFlow会释放掉所有的节点值(除了某些特殊值和变量值会被保留)。一个变量值的声明周期从它的initializer开始,到session结束。
我们知道上面的计算y和z的值需要两次计算w和x节点,但是,如果想更高效率的计算y和z的值的话,则需要将两个计算放到一个图中,如下:
其实在单线程中,多个session之间不共享任何信息,即使不同session计算同一个图(每一个session都有自己的变量copy)。在分布式的TensorFlow中变量信息存放在服务器中,而不是在session中,所以多session可以共享变量。
三. 线性回归TF实战
这里,我们将TensorFlow和用NumPy以及Scikit-Learn做一个比较,进而更加详细的了解TensorFlow。
3.1 TensorFlow线性回归
TensorFlow支持多输入多输出的操作,比方说相加和相差运算是两个输入一个输出,常数和变量是没有输入。这里的输入和输出都是多维数组,也称tensor。就像numpy中的数组,tensor有一个类型和尺寸。
之前的例子中,我们tensor只包含了单一数值,接下来,我们将用TensorFlow来实战一下线性回归这里我们用机器学习三人行系列(公众号回复“机器学习”进行查看)中的房价数据做回归,先上代码在讲解如下:
从上面代码中,我们可以看到,首先获取了房价的数据集,然后在每条数据的前面加1(大家考虑下为什么加1,欢迎文末留言讨论),接着创建了两个常量节点来承载数据和label,之后就是计算线性回归的系数。其实θ的计算是根据下面的公式计算出来的:
上面代码和直接用numpy直接计算θ的主要区别是在于如果我们的电脑上支持GPU计算的话,那么其将自动调用GPU资源运行。
3.2 NumPy线性回归
NumPy的方法,我们直接求取上面的公式如下:
从这结果里面,我们可以看到用TensorFlow和NumPy的方法得到的值是很相近的。
3.3 Scikit-Learn线性回归
关于Scikit-Learn线性回归的线性回归,这里不多说,详情查看机器学习系列文章。如下:
可以看到,三种方法得到的结果十分相近。
四. 本期小结
本期我们从TensorFlow的简介特性入手,熟悉了TensorFlow的相关流程,以及如何创建图,运行图的几种常见的方法,最后,我们通过TensorFlow的线性回归与NumPy的线性回归和Scikit-Learn之间的线性回归进行比较,来学习了TensorFlow在线性回归方面的应用。