PaddlePaddle深度学习实战
上QQ阅读APP看书,第一时间看更新

1.3 Python库的操作

Python作为机器学习和深度学习最主流的编程语言,在机器学习和深度学习工程具体实现中提供了哪些主要库函数呢?具体代码实现时会用到哪些操作呢?这里介绍两个在深度学习中最为常用的库函数——numpy和matplotlib。

注意 由于目前PaddlePaddle仅支持Python 2(推荐2.7),本书中所用的Python语法、函数等均为Python 2.X版本。

1.3.1 numpy操作

numpy(Numerical Python Extension)是一个第三方的Python包,用于科学计算。这个库的前身是1995年就开始开发的一个用于数组运算的库。经过了长时间的发展,基本上成了绝大部分Python科学计算的基础包,当然也包括所有提供Python接口的深度学习框架。

1.基本模块

(1)array模块

array,也就是数组,是numpy中最基础的数据结构。最关键的属性是维度和元素类型,在numpy中,可以非常方便地创建各种不同类型的多维数组,并且执行一些基本操作。在深度学习中,如果神经元之间的连接关系涉及的参数是数组,便可利用array模块进行设定,来看代码清单1-1所示:

代码清单1-1 array的基本操作

注意到在导入numpy的时候,代码中将np作为numpy的别名。这是一种习惯性的用法,后面的章节中本书也默认这么使用。例如在机器学习中常用到的矩阵的转置操作,可以通过matrix构建矩阵,transpose函数来实现转置,如代码清单1-2所示:

代码清单1-2 numpy中实现矩阵转置

对于一维的array,所有Python列表(list)支持的下标操作方法array也都支持,所以在此没有特别列出。

代码清单1-3 numpy基础数学运算

(2)random模块

numpy中的随机模块包含了随机数产生和统计分布相关的基本函数。Python本身也有随机模块random,不过numpy的random功能更丰富,随机模块一般会用于深度学习中的一些随机数的生成,seed的生成以及初始值的设定,具体的用法请看代码清单1-4:

代码清单1-4 random模块相关操作

随机模块同时可以很方便地做一些快速模拟去验证一些结论,在神经网络中也能够做一些快速的网络构造。比如来考虑一个非常违反直觉的概率题例子:一个选手去参加一个TV秀,有三扇门,其中一扇门后有奖品,这扇门只有主持人知道;选手先随机选一扇门,但并不打开,主持人看到后,会打开其余两扇门中没有奖品的一扇门,然后,主持人问选手,是否要改变一开始的选择?

这个问题的答案是应该改变一开始的选择。在第一次选择的时候,选错的概率是2/3,选对的概率是1/3。第一次选择之后,主持人相当于帮忙剔除了一个错误答案,所以如果一开始选的是错的,这时候换掉就选对了;而如果一开始就选对,则这时候换掉就错了。根据以上,一开始选错的概率就是换掉之后选对的概率(2/3),这个概率大于一开始就选对的概率(1/3),所以应该换。虽然道理上是这样,但还是有些绕,要是通过推理就是搞不明白怎么办,没关系,用随机模拟就可以轻松得到答案。

注意 这一部分请读者作为练习自行完成。

2.广播机制

对于array,默认执行对位运算。涉及多个array的对位运算需要array的维度一致,如果一个array的维度和另一个array的子维度一致,则在没有对齐的维度上分别执行对位运算,这种机制叫作广播(Broadcasting),具体通过代码清单1-5理解:

代码清单1-5 广播机制的理解

3.向量化

读者在数学基础部分(见1.2.1节)已经初步了解到,向量化在深度学习中的应用十分广泛,它是提升计算效率的主要手段之一,对于在机器学习中缩短每次训练的时间是很有意义的。当可用工作时间不变的情况下,更短的单次训练时间可以让程序员有更多的测试机会,进而更早更好地调整神经网络结构和参数。接下来通过一个矩阵相乘的例子来呈现向量化对于代码计算速度的提升效果。代码清单1-6、1-7、1-8展示了向量化对于计算速度的提升效果。在代码清单1-6中首先导入了numpy和time库,它们分别被用于数学计算和统计运行时间。然后准备数据,这里初始化两个1000000维的随机向量v1和v2, v作为计算结果初始化为零。

代码清单1-6 导入库和数据初始化

在代码清单1-7中,设置变量tic和toc分别为计算开始时间和结束时间。在非向量化版本中,两个向量相乘的计算过程使用for循环实现。

代码清单1-7 矩阵相乘(非向量化版本)

在代码清单1-8中,同样使用变量tic和toc记录计算开始和结束时间。向量化版本使用numpy库的numpy.dot()计算矩阵相乘。

代码清单1-8 矩阵相乘(向量化版本)

为了保证计算结果相同,我们输出了二者的计算结果,确保计算无误。最后的输出结果为:“非向量化计算时间578.0208ms,向量化计算时间1.1038ms”。可以观察到效率提升效果十分显著。非向量化版本的计算时间约为向量化版本计算时间的500倍。可见向量化对于计算速度的提升是很明显的,尤其是在长时间的深度学习训练中,向量化可以帮助开发者节省更多时间。

1.3.2 matplotlib操作

matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型2D图表和一些基本的3D图表。matplotlib最早是为了可视化癫痫病人的脑皮层电图相关的信号而研发的,因为在函数的设计上参考了MATLAB,所以叫作matplotlib。matplotlib的原作者John D. Hunter博士是一名神经生物学家,2012年不幸因癌症去世,感谢他创建了这样一个伟大的库。matplotlib首次发表于2007年,在开源社区的推动下,在基于Python的各个科学计算领域都得到了广泛应用。

注意 安装Matplotlib的方式和numpy很像,可以直接通过UNIX/Linux的软件管理工具,比如Ubuntu 16.04 LTS下,输入:

>> sudo apt-get install python-matplotlib

或者通过pip安装:

>> pip install matplotlib

Windows下也可以通过pip安装,或是到官网下载(http://matplotlib.org/)。

1.图表展示

matplotlib非常强大,不过在深度学习中常用的其实只有很基础的一些功能。这里以机器学习中的梯度下降法来展示其图表功能。首先假设现在需要求解目标函数func(x) =x*x的极小值,如代码清单1-9所示,由于func是一个凸函数,因此它唯一的极小值同时也是它的最小值,其一阶导函数为dfunc(x)=2*x

代码清单1-9 创建目标函数及目标函数求导函数

接下来编写梯度下降法功能函数GD(),如代码清单1-10所示:

代码清单1-10 梯度下降法功能函数实现

在map_plot()函数中,具体用matplotlib实现了展示梯度下降法搜索最优解的过程,如代码清单1-11所示:

代码清单1-11 利用matplotlib实现图像绘制

这个例子中展示了如何利用梯度下降法寻找x2的极小值,起始检索点为x=-5,学习率为0.5,最终绘制的图像如图1-7所示,图中红线为检索过程,红点为每次更新的x值所在的点。利用matplotlib还能完成其他多种多样的图像的绘制,具体实现请参考matplotlib官方文档(网址:http://matplotlib.org/)。

图1-7 matplotlib绘制图像

2.图像显示

matplotlib也支持图像的存取和显示,并且和OpenCV一类的接口比起来,对于一般的二维矩阵的可视化要方便很多,这一点在机器学习中体现得极为方便,如代码清单1-12所示:

代码清单1-12 利用matlibplot实现图像的显示

这段代码中第一个例子是读取一个本地图片并显示,如图1-8所示,第二个例子将读取的原图灰度化,经过灰度像素变换的图直接绘制了两个形状一样,但是值的范围不一样的图案。显示的时候imshow会自动进行归一化,把最亮的值显示为纯白,最暗的值显示为纯黑。这是一种非常方便的设定,尤其是查看深度学习中某个卷积层的响应图时,得到图1-9所示。

图1-8 matplotlib显示图片

图1-9 matplotlib显示图像处理后的结果

注意 这里只讲到了最基本和常用的图表及最简单的例子,更多有趣精美的例子可以在Matplotlib的官网找到:Thumbnail gallery - Matplotlib 1.5.3 documentation(http://matplotlib.org/gallery.html)。