第14章TensorFlowOnSpark详解

第14章TensorFlowOnSpark详解

前面我们介绍了Spark MLlib的多种机器学习算法,如分类、回归、聚类、推荐等,Spark目前还缺乏对神经网络、深度学习的足够支持,但近几年市场对神经网络,尤其对深度学习热情高涨,成了当下很多企业的研究热点,缺失神经网络的支持,这或许也算是Spark MLlib尚欠不足之处吧。
不过好消息是TensorFlow这个深度学习框架,已经有了Spark接口,即TensorFlowOnSpark。TensorFlow是目前很热门的深度学习框架,是Google于2015年11月9日开源的第二代深度学习系统,也是AlphaGo的基础程序。
本章我们将介绍深度学习最好框架TensorFlow及TensorFlowOnSpark,具体包括:
TensorFlow简介
TensorFlow实现卷积神经网络
分布式TensorFlow
TensorFlowOnSpark架构
TensorFlowOnSpark实例

14.1TensorFlow简介

14.1.1TensorFlow的安装

安装TensorFlow,因本环境的python2.7采用anaconda来安装,故这里采用conda管理工具来安装TensorFlow,目前conda缺省安装版本为TensorFlow 1.1。

验证安装是否成功,可以通过导入tensorflow来检验。
启动ipython(或python)

14.1.2TensorFlow的发展

2015年11月9日谷歌开源了人工智能系统TensorFlow,同时成为2015年最受关注的开源项目之一。TensorFlow的开源大大降低了深度学习在各个行业中的应用难度。TensorFlow的近期里程碑事件主要有:
2016年04月:发布了分布式TensorFlow的0.8版本,把DeepMind模型迁移到TensorFlow;
2016年06月:TensorFlow v0.9发布,改进了移动设备的支持;
2016年11月:TensorFlow开源一周年;
2017年2月:TensorFlow v1.0发布,增加了Java、Go的API,以及专用的编译器和调试工具,同时TensorFlow 1.0引入了一个高级API,包含tf.layers,tf.metrics和tf.losses模块。还宣布增了一个新的tf.keras模块,它与另一个流行的高级神经网络库Keras完全兼容。
2017年4月:TensorFlow v1.1发布,为 Windows 添加 Java API 支,添加 tf.spectral 模块, Keras 2 API等;
2017年6月:TensorFlow v1.2发布,包括 API 的重要变化、contrib API的变化和Bug 修复及其他改变等。

14.1.3TensorFlow的特点

14.1.4TensorFlow编程模型

TensorFlow如何工作?我们通过一个简单的实例进行说明,为计算x+y,你需要创建下图(图14-1)这张数据流图:

图14-1计算x+y的数据流图

以下构成上数据流图(图14-1)的详细步骤:
1)定义x= [1,3,5],y =[2,4,7],这个图和tf.Tensor一起工作来代表数据的单位,你需要创建恒定的张量:

2)定义操作

3)张量和操作都有了,接下来就是创建图

注意:这一步不是必须的,在创建回话时,系统将自动创建一个默认图。
4)为了运行这图你将需要创建一个回话(tf.Session),一个tf.Session对象封装了操作对象执行的环境,为了做到这一点,我们需要定义在会话中将要用到哪一张图:

5)想要执行这个操作,要用到tf.Session.run()这个方法:

6)运行结果:
[ 3 7 12]

14.1.5TensorFlow常用函数

14.1.6TensorFlow的运行原理

TensorFlow有一个重要组件client,即客户端,此外,还有master、worker,这些有点类似Spark的结构。它通过Session的接口与master及多个worker相连,其中每一个worker可以与多个硬件设备(device)相连,比如CPU或GPU,并负责管理这些硬件。而master则负责管理所有worker按流程执行计算图。

14.2TensorFlow实现卷积神经网络

神经网络可为机器学习中最活跃的领域之一,尤其代表深度学习的卷积神经(Convolutional Neural Network,CNN)、循环神经网络(Recurrent Neural Network,RNN)更是炙手可热。

14.2.1卷积神经网络简介

卷积神经网络是人工神经网络的一种,已成为图像识别、视频处理、语音分析等领域的研究热点。它的权值共享网络结构使之更类似于生物神经网络,减少了权值的数量,降低了网络模型的复杂度,防止因参数太多导致过拟合。

14.2.3卷积神经网络的网络结构

接下来,我们利用训练集训练卷积神经网络模型,然后在测试集上验证该模型。
搭建的卷积神经网络使用的一些参数是:
卷积层1:kernel_size [5, 5], stride=1,32个卷积窗口
池化层1: pool_size [2, 2], stride = 2
卷积层2:kernel_size [5, 5], stride=1,64个卷积窗口
池化层2: pool_size [2, 2], stride = 2
全连接层: 1024个特征,使用dropout减少过拟合
输出层: 使用softmax进行分类

14.2.4.1 导入数据

首先启动ipython,进入交互计算环境,当然直接启动python也可,然后通过TensorFlow自带的函数读取图片数据。

如果无法直接通过input_data下载,可以先把MNIST数据下载,然后,修改
python/learn/datasets/mnist.py文件中read_data_sets函数中4个local_file的值
具体如下,注释原来的local_file,新增4行local_file

更加数据实际存放路径,修改read_data_sets中读取文件路径。

14.2.4.2 权重初始化

# 正态分布,标准差为0.1,默认最大为1,最小为-1,均值为0

14.2.4.3 构建卷积神经网络结构

14.2.4.4 训练评估模型

这里只迭代了2000次,运行结果;如果迭代20000次,在测试集上的精度可到99.2%左右
## -- End pasted text --
step 0, training accuracy 0.14
step 100, training accuracy 0.86
step 200, training accuracy 0.94
step 300, training accuracy 0.94
step 400, training accuracy 0.94
step 500, training accuracy 0.98
step 600, training accuracy 0.94
step 700, training accuracy 0.94
step 800, training accuracy 0.98
step 900, training accuracy 0.98
step 1000, training accuracy 1
step 1100, training accuracy 0.94
step 1200, training accuracy 0.98
step 1300, training accuracy 0.96
step 1400, training accuracy 0.92
step 1500, training accuracy 0.96
step 1600, training accuracy 0.96
step 1700, training accuracy 1
step 1800, training accuracy 1
step 1900, training accuracy 0.96

在测试集上,测试模型精度

14.3TensorFlow实现循环神经网络

14.3.1循环神经网络简介

在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,
每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能无力。

14.3.2LSTM循环神经网络简介

LSTM是一种特殊的RNNs,可以很好地解决长时依赖问题。

14.3.4TensorFlow实现循环神经网络

前面我们用卷积神经网络,对MNIST中的手写数进行设别,如果迭代20000次,精度可达到99.2左右,这个精度应该比较高;如果我们用循环神经网络来识别,是否可行?如果可以,效果如何?
为了适合使用RNN来识别,每张图片大小为28x28像素,我们把每张图片的每一行(元素个数为28)作为输入数据n_inputs,把每一行(一张图片共28行)看成是与时间序列有关的步数n_steps,这样图片的所有信息都用上了,而且适合使用RNN的应用场景。
启动ipython,进入ipython的交互式界面,导入需要的库,并启动交互式会话。

加载数据,具体实现细节可参考14.2.4.1小节,这里就不详细说明了。

1. 构建模型
设置训练模型的超参数,学习速率,批量大小等。

设置循环神经网络的参数,包括输入数长度,输入的步数,隐藏节点数,类别数等。

定义输入数据及权重等

定义权重及初始化偏移量

定义并初始化Input gate、Forget gate、Output gate、Memory cell等的输入数据、权重、偏移量,这里采用tensorflow中truncated_normal函数初始化相关参数值。

创建循环神经网络结构

2. 定义损失函数及优化器

3. 训练数据及评估模型

运行结果,以下是最后批次的运行结果。
Iter 8000, Minibatch Loss= 0.085752, Training Accuracy= 0.97656
Iter 8100, Minibatch Loss= 0.065435, Training Accuracy= 0.96875
Iter 8200, Minibatch Loss= 0.088926, Training Accuracy= 0.97656
Iter 8300, Minibatch Loss= 0.039572, Training Accuracy= 1.00000
Iter 8400, Minibatch Loss= 0.050593, Training Accuracy= 0.98438
Iter 8500, Minibatch Loss= 0.030424, Training Accuracy= 0.99219
Iter 8600, Minibatch Loss= 0.026174, Training Accuracy= 0.99219
Iter 8700, Minibatch Loss= 0.045043, Training Accuracy= 0.98438
Iter 8800, Minibatch Loss= 0.031143, Training Accuracy= 0.98438
Iter 8900, Minibatch Loss= 0.055115, Training Accuracy= 0.99219
Iter 9000, Minibatch Loss= 0.061676, Training Accuracy= 0.98438
Iter 9100, Minibatch Loss= 0.123581, Training Accuracy= 0.97656
Iter 9200, Minibatch Loss= 0.057620, Training Accuracy= 0.98438
Iter 9300, Minibatch Loss= 0.043013, Training Accuracy= 0.99219
Iter 9400, Minibatch Loss= 0.067405, Training Accuracy= 0.98438
Iter 9500, Minibatch Loss= 0.020679, Training Accuracy= 1.00000
Iter 9600, Minibatch Loss= 0.079038, Training Accuracy= 0.98438
Iter 9700, Minibatch Loss= 0.080076, Training Accuracy= 0.97656
Iter 9800, Minibatch Loss= 0.010582, Training Accuracy= 1.00000
Iter 9900, Minibatch Loss= 0.019426, Training Accuracy= 1.00000
Optimization Finished!

在测试集上验证模型

运行结果如下,这个结果虽然比CNN结果低些,但也是不错的一个结果。
Testing Accuracy: 0.976562

14.4分布式TensorFlow

2016年4月14日,Google发布了分布式TensorFlow,能够支持在几百台机器上并行训练。分布式的TensorFlow由高性能的gRPC库作为底层技术支持。

14.4.1客户端、主节点和工作节点间的关系

14.4.2分布式模式

常用的深度学习训练模型为数据并行化,即TensorFlow任务采用相同的训练模型在不同的小批量数据集上进行训练,然后在参数服务器上更新模型的共享参数。TensorFlow支持同步训练和异步训练两种模型训练方式。

14.4.3在Pyspark集群环境运行TensorFlow

这节将通过神经网络来模拟一个一元二次方程:y=x^2-0.5,
TensorFlowOnSpark的详细配置,请参考14.4节。已集群方式启动pyspark:

进入pyspark的交换界面

构造一个神经网络

输出结果:
1.62758
0.00996406
0.00634915
0.00483868
0.0043179
0.00399014
0.00368176
0.00337165
0.00309145
0.00284696
0.00267657
0.00255845
0.0024702
0.00240239
0.00235583
0.00232014
0.00229183
0.00226797
0.00224843

14.5TensorFlowOnSpark架构

TensorFlowOnSpark(TFoS),支持 TensorFlow 在 Spark 和 Hadoop 上的分布式运行。

14.6TensorFlowOnSpark安装

安装TensorFlowOnSpark,采用pip管理工具进行安装,缺省安装是1.0版本。

执行以上命令后,在用户当前目录下,将新增一个TensorFlowOnSpark目录。
然后,在.bashrc定义该路径。

可以通过pyspark环境来验证,以上2个安装是否成功。

导入这些库,如果没有异常,说明安装成功。接下来开始为训练数据做一些准备工作。
对scripts目录进行打包,便于把该包发布到各worker上

14.7TensorFlowOnSpark实例

使用TensorFlowOnSpark对MNIST数据进行预测,MNIST是一个手写数字数据库,它有60000个训练样本集和10000个测试样本集,train-images-idx3-ubyte.gz、train-labels-idx1-ubyte.gz等四个文件。这些图像数据都保存在二进制文件中。每个样本图像的宽高为28*28。
下载MNIST数据

14.7.1TensorFlowOnSpark单机模式实例

设置本机相关参数,在单机上启动一个master节点,两个worker节点。

启动以后,通过jps可以看到如下一些进程。一个master,两个worker,namenode是之前启动hadoop的进程。

相关服务起来后,接下来把MNIST数据上传到HDFS上,并把数据转换cvs格式。

运行完成后,通过hadoop fs命令可以在HDFS上看到如下信息:

数据加载转换成功后,开始训练数据。

运行完成后,可以看到如下内容:

如果运行过程中,过程被卡,可以调整mnist_dist.py文件中两处(在115,125行)logdir=logdir改为logdir=None。
训练完成后,接下来就是用测试集验证模型,并对结果进行预测。

运行完成以后,在HDFS上,就可看到predictions目录及相关内容。

打开其中一个文件,可以看到预测结果信息。
2017-06-18T05:51:42.397905 Label: 5, Prediction: 5
2017-06-18T05:51:42.397923 Label: 9, Prediction: 8
2017-06-18T05:51:42.397941 Label: 7, Prediction: 5
2017-06-18T05:51:42.397958 Label: 3, Prediction: 5
2017-06-18T05:51:42.397976 Label: 4, Prediction: 8
2017-06-18T05:51:42.397993 Label: 9, Prediction: 8
2017-06-18T05:51:42.398012 Label: 6, Prediction: 5

14.7.2TensorFlowOnSpark集群模式实例

设置本机相关参数,在以集群方式启动spark,一个master节点,slave1、slave2作为
两个worker节点,各节点资源配置信息。
训练模型

测试模型

查看运行结果

运行时各节点报错信息,可以查看spark/work/app-20170620085449-0003/1下的

14.8小结

为了弥补Spark机器学习中,缺乏神经网络、深度学习等的不足,这章我们介绍脱胎于AlphaGo的深度学习框架TensorFlow,以基础知识为主,在这个基础上介绍了使用TensorFlow的几个实例,最后介绍TensorFlow的分布式架构及与Spark整合的架构TensorFlowOnSpark。

发表评论