深度学习与飞桨PaddlePaddle Fluid实战

978-7-115-51964-1
作者: 于祥
译者:
编辑: 陈冀康

图书目录:

详情

飞桨PaddlePaddle Fluid是百度推出的深度学习框架,不仅支撑了百度公司的很多业务和应用,而且随着其开源过程的推进,在很多行业得到普及、应用和关注。 本书基于最新的飞桨PaddlePaddle Fluid版本,以真实的应用案例介绍如何用飞桨PaddlePaddle解决主流的深度学习问题。全书共14章。本书首先介绍了什么是飞桨PaddlePaddle,然后介绍了其核心设计思想,进而紧紧结合案例介绍了飞桨PaddlePaddle在主流的图像任务领域、NLP领域的应用,最后还探讨了Paddle-Mobile与Anakin框架等高级主题。附录A和B给出了飞桨PaddlePaddle与TensorFlow、Caffe框架的接口中常用层的对比。 本书非常适合对人工智能感兴趣的学生、从事机器学习相关工作的读者阅读,尤其适合想要通过飞桨PaddlePaddle掌握深度学习应用技术的研究者和从业者参考。

图书摘要

版权信息

书名:深度学习与飞桨PaddlePaddle Fluid实战

ISBN:978-7-115-51964-1

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    于 祥

责任编辑 陈冀康

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


飞桨PaddlePaddle Fluid是百度推出的深度学习框架,不仅支撑了百度公司的很多业务和应用,而且随着其开源过程的推进,在很多行业得到普及、应用和关注。

本书基于最新的飞桨PaddlePaddle Fluid版本,以真实的应用案例介绍如何用飞桨PaddlePaddle解决主流的深度学习问题。全书共14章。本书首先介绍了什么是飞桨PaddlePaddle,然后介绍了其核心设计思想,进而紧紧结合案例介绍了飞桨PaddlePaddle在主流的图像任务领域、NLP领域的应用,最后还探讨了Paddle-Mobile与Anakin框架等高级主题。附录A和B给出了飞桨PaddlePaddle与TensorFlow、Caffe框架的接口中常用层的对比。

本书非常适合对人工智能感兴趣的学生、从事机器学习相关工作的读者阅读,尤其适合想要通过飞桨PaddlePaddle掌握深度学习应用技术的研究者和从业者参考。


PaddlePaddle是百度公司早在2013年就开始搭建的深度学习框架,推出后在公司内部获得了很多业务的支持和应用。为了能让公司外部的用户参与并使用该框架,百度于2016年9月正式将PaddlePaddle对外开源。

PaddlePaddle已在百度内部具有数年的历史,目前正夜以继日地支持百度的关键业务线。随着深度学习技术的发展,之前的框架设计不再适用于新的使用场景,因此百度重新开发了新一代深度学习框架,版本名称为Fluid,并于2017年正式对外发布。在2018年10月的百度世界大会上,PaddlePaddle Fluid 1.0版本正式发布,为用户提供更稳定的支持和更丰富的模型库,此后团队继续完善PaddlePaddle Fluid的建设。截至2019年7月4日,我们已经对外发布了Paddle Fluid 1.5版本。为了更好地支持国内开发者及企业使用,以及提升本土化服务,PaddlePaddle现在有了一个正式的中文名字——“飞桨”。

自2018年10月发布以来,PaddlePaddle Fluid获得广大开发者越来越多的关注,根据调研,国内至少70%的深度学习开发者都已经知晓飞桨PaddlePaddle框架。作者在社区、社群、高校教师、参赛选手等各个用户渠道不断地得到大家的反馈——需要一本关于PaddlePaddle Fluid的技术图书来帮助学习,而PaddlePaddle Fluid发布以来确实没有一本正式的技术图书供大家参考。所以在2018年年末,作者开始规划写一本既干货满满又易于理解和学习的PaddlePaddle参考书,就是您手中的这本《深度学习与飞桨PaddlePaddle Fluid实战》。

本书在内容上循序渐进,先介绍如何安装和使用PaddlePaddle,之后较深入地解读PaddlePaddle设计的核心思想。读者在大致了解了PaddlePaddle的使用方式之后,继续深入一些非常实用且流行的深度学习案例,首先逐行对代码进行解读和分析,然后再逐渐通过阅读注释的方式来理解程序的关键逻辑。编程是一门重实践的技能。对于读者来说,能快速掌握PaddlePaddle的使用方法,是阅读和学习本书的首要目标,而通过实际案例来学习编程是非常快速的学习方式。

要使用飞桨PaddlePaddle这样一个深度学习框架,深度学习的理论基础是必不可少的。只有具备了理论知识,你才能知道需要用框架来做什么,这就如同要有汽车的设计图才能制造汽车一样。深度学习的算法思路有别于传统算法,它的学习门槛较高。作为深度学习的研究者,作者也接触过许多深度学习的课程与学习资料。其中大多数教程的不足之处是理论与实践的脱节。有的读者明白原理,但是在实现代码时无从下手;有的读者想赶紧实现一个算法,但是搞不清楚理论细节,也导致在编写代码时无从下手;还有些读者花了很长时间学理论,数学细节学了忘、忘了学,最终放弃。这说明深度学习的理论和实践之间具有鸿沟,最终只有一小部分读者跨越了这个鸿沟,而大部分的读者选择了放弃。所以,在规划和设计本书的内容时,作者力求使每一章的理论和实践都深度契合。每章初始以实战项目为目标,先将目标进行任务拆解,让读者从头思考如果自己来完成这个任务,会怎样来做。然后告诉读者目前主流的方法当初在遇到这个问题时是如何应对的,之后又是如何发展完善的,以及最终如何成为业界主流的。

飞桨PaddlePaddle是源于产业实践的深度学习框架,擅长于应对实际生产中的种种挑战。本书是第一本飞桨PaddlePaddle Fluid技术图书,通过真实的应用案例介绍飞桨PaddlePaddle如何解决主流的深度学习问题。本书的代码基于最新发布的PaddlePaddle Fluid 1.5编写,相信本书出版后,飞桨PaddlePaddle还会持续发布版本更新。不过读者不用担心,当框架新版本升级时,算子会向前兼容旧版本的编码形式,因此本书中代码和更新后的版本框架不会出现不匹配问题。

本书共14章。每一章都有相应的理论解读与代码实现。

各章的主要内容如下。

第1章介绍飞桨PaddlePaddle平台的生态状况与优势,并讲述具有免费算力支持的在线AI编程平台AI Studio。

第2章从安装入手,帮读者轻松开始使用PaddlePaddle。

学习完第3章后,读者会对PaddlePaddle建立初步的感性认知。

第4章开始解读PaddlePaddle设计思想与核心技术,使读者在体会PaddlePaddle设计精妙的同时,在学习后续的实践章节时游刃有余。

第5~7章介绍主流的图像处理任务的基本原理与应用,先讲解6种经典的图像分类结构的实现方式,包含VGG16、GoogleNet、Alexnet、Resnet、MobileNet V2和ShuffleNet V2,然后讲述Fast R-CNN、Faster R-CNN、SSD、PyramidBox、ICNet、DeepLab v3+、Mask R-CNN等的实现方式。

考虑到NLP领域的读者较少会涉及深度学习开发,为了让这部分读者能够较快地掌握NLP的基础知识,第8~12章通过推荐系统、情感分析、语义角色标注、机器翻译等当下流行的案例,循序渐进地介绍NLP技术的PaddlePaddle实现。

第13和第14章首次公开介绍PaddlePaddle生态中的其他两个框架Paddle-Mobile与Anakin。在Paddle-Mobile的赋能下,手机百度频繁地在AI开发者大会上推出新的AI技术。在2019年百度AI开发者大会上,手机百度展示了强大的端侧图像推理能力。

为了方便其他框架的开发者体验飞桨PaddlePaddle,附录中列出了飞桨PaddlePaddle Fluid与TensorFlow、Caffe框架的接口中常用层的对照表,以帮助有深度学习开发经验的读者轻松地将其他框架的模型改写为飞桨PaddlePaddle代码。

本书非常适合以下读者和人群:

在阅读本书之前,读者最好达到以下要求:

虽然本书各章是根据循序渐进的顺序来设立的,但除了理论知识之外,各章之间的代码是相互独立的。如果您只对某个具体领域的知识和内容感兴趣,完全可以单独阅读该章,学习和掌握需要的内容。

读者可以通过扫描以下二维码,访问本书配套的AI Studio项目。

也可以通过Googol.ai访问作者的博客,或者访问异步社区(www.epubit.com)的本书页面,下载本书的配套代码。

作者和出版社花费了大量的精力来编写、审阅书稿,即使已经对全书内容及代码再三审校,也难免出现疏漏之处。如果您对本书有任何疑问或者想要继续学习PaddlePaddle,可以通过Googol.ai访问作者的个人博客。关于本书的疑问或者勘误,请发送邮件到Yimitrii@Gmail.com。

于祥,现任百度PaddlePaddle技术运营负责人。2015年开始研究神经网络技术,早期从事基于深度学习的身份认证技术研发,曾负责上海智慧城市项目和华润集团项目的算法支持。在校学习时曾获得ACM-ICPC与CCCC-GPLT银奖。

诚挚感谢百度AI技术生态部喻友平总经理,喻友平总经理夜以继日地辛勤工作,让飞桨变得世人皆知。他用心将飞桨PaddlePaddle用户培养成飞桨社区的中坚力量,推动飞桨建设更符合国人的需求。

感谢周奇老师在我遇到困难的时候会毫无隔阂地根据他的职业阅历给出建议。他对本书提出了一些关键的意见和建议,使本书质量得到保障。

感谢杜哲老师对我的指引,杜哲老师不仅使我在工作认知上得到了提升,还让我了解到我不曾看到的人生规律,使我对人生规划更加精准。他是一位非常专业的领导,更是一位“授人以渔”的老师。

衷心感谢田野老师耐心地帮助我认识到这个世界的真实的面貌以及事情表面背后难以察觉的因果关系。她是一位可遇不可求的职场前辈!

感谢百度深度学习技术平台部总监马艳军博士、于佃海总架构师为百度贡献了智能时代的操作系统,他们的辛勤付出使得飞桨在功能上和性能上都可以比肩业界主流标准,让飞桨这个开源开放的大框架如此强大。

感谢百度首席技术官王海峰老师带领飞桨走向今日的成就。

感谢李永会架构师为本书第13章提供的内容和资料。

感谢庄熠、靳伟、程思、高峰、江列霖、刘毅冰、何天健、许瑾、骆涛、殷晓婷、郭晟等百度同事提供的技术资料与指导。

感谢人民邮电出版社信息技术第一分社陈冀康副社长、谢晓芳编辑对本书出版的支持,使本书得以如期面市。

感谢所有关注飞桨的朋友,你们的关注与支持是飞桨前进的动力!


飞桨PaddlePaddle是百度自主研发的开源深度学习框架。飞桨PaddlePaddle是集深度学习核心框架、工具组件和服务平台于一体的技术领先、功能完备的开源深度学习平台,拥有活跃的开发者社区。

作为领先的核心框架,飞桨PaddlePaddle具备简单、易用、高效、安全的特点,能满足模型开发、训练、部署的全流程需求。

飞桨PaddlePaddle拥有丰富的工具组件。飞桨PaddlePaddle开放了PaddleHub、PARL、AutoDL Design、VisualDL等一系列深度学习工具组件。

飞桨PaddlePaddle具备专业的服务平台——AI Studio和EasyDL,可以满足不同层次的深度学习开发的需求。

图1-1展示了飞桨PaddlePaddle的生态结构。

图1-1

PaddlePaddle源于业界顶尖实践,拥有强大的超大规模并行深度学习处理能力,它具备4大工业级特点。

PaddlePaddle在速度上追求极致的体验,推出了全流程、全类型的高性能部署和集成方案,在计算性能与易用性上具备3大特性。

迁移学习(Transfer Learning)是深度学习的一个子研究领域,其目标在于利用数据、任务或模型之间的相似性,将在旧领域学习过的知识迁移和应用到新领域中。迁移学习吸引了很多研究者投身其中,因为它能够很好地解决深度学习中的以下几个问题。

PaddleHub是基于飞桨PaddlePaddle开发的预训练模型管理工具,目前的预训练模型覆盖了图像分类、目标检测、词法分析、Transformer、情感分析五大类别。PaddleHub通过命令行工具,可以方便快捷地完成模型的搜索、下载、安装、预测等功能。PaddleHub提供了基于PaddlePaddle 实现的 Finetune API,重点针对大规模预训练模型的 Finetune 任务做了高阶的抽象,让预训练模型能更好地服务于用户特定场景,如图1-2所示。通过大规模预训练模型结合Finetune API,可以在更短的时间完成模型的收敛,同时具备更好的泛化能力。通过命令行接口,用户可以便捷地获取PaddlePaddle 生态下的预训练模型。PaddleHub引入了“模型即软件”的理念,无须编写代码,命令行一键完成预训练模型预测;借助PaddleHub Finetune API,使用少量代码就可以完成迁移学习。

图1-2

作为AI技术发展的重要分支,除了应用于模拟器和游戏领域之外,强化学习在工业领域也取得了长足的进步。强化学习的主要思想是基于智能体(agent)和环境(environment)的交互学习,其中机器人通过动作影响环境,环境返回一个回馈和当前环境下的状态,整个交互过程是一个马尔可夫决策过程。在交互学习的过程中,没有人的示范,而是让机器自主去做一个动作,让机器拥有自我学习和自我思考的能力。强化学习能够解决有监督学习方法无法解决的很多问题。

PARL是一款基于飞桨PaddlePaddle打造的深度强化学习框架,继1.0版本开源了NeurIPS 2018假肢挑战赛冠军训练代码以及主流强化学习模型后,聚焦于并行的1.1版本也发布了。PARL 1.1通过一个简单的修饰符(@parl.remote_class)即可实现并行化,支持高质量的并行算法,包括IMPALA、GA3C、A2C,并提供了高性能的并行开发接口。以通过PARL实现的IMPALA算法的评估结果为例,在雅达利这个经典评测环境中,Pong游戏最快可在7分钟内达到20分(见图1-3),Breakout游戏可在25分钟达到400分(1个P40 GPU +32个CPU)。

图1-3

PARL具有高度灵活性和可扩展性,支持可定制的并行扩展,覆盖DQN、DDPG、PPO、IMPALA、A2C、GA3C 等主流强化学习算法。通过8块GPU拉动近20000个CPU节点的运算,将近5小时迭代一轮的PPO 算法加速到1分钟内,并且在NeurIPS 2018夺冠。

基于飞桨PaddlePaddle和PARL强化学习框架,百度进行了自动化网络结构设计的探索和尝试,并且开源了其中关于自动化网络结构设计的源代码和对应的预训练模型,将AutoDL这一前沿技术以更低的成本展示给业界和各位开发者,大幅降低了该类技术的门槛。

百度的研究员和工程师使用自动网络结构搜索的方法,目标是找到合适的“局部结构”,即首先搜索得到一些合适的局部结构作为零件,然后类似流行的Inception结构那样,按照一定的整体框架堆叠成一个较深的神经网络。整个搜索过程是基于增强学习思想设计出来的,因此很自然地包括了两个部分:第一个部分是生成器,对应增强学习中的智能体,用于采样(sample),生成网络结构;第二个部分是评估器,用于计算奖励(reward),即用新生成的网络结构去训练模型,把模型的准确率(accuracy)或者损失函数(loss function)返回给生成器,如图1-4所示。

图1-4

目前已发布用AutoDL Design方法生成的一系列神经网络,以及使用CIFAR10数据集在其上训练出来的6个模型,包括了网络结构以及对应的权重。开发者可以在这6个模型上进行推理(inference)以及模型融合。读者可以下载、安装和运行,尝试生成属于自己的、全新的神经网络结构。

AutoDL包含网络结构自动化设计、迁移小数据建模、适配边缘计算3个部分。使用开源的AutoDL Design网络结构自动化设计技术设计的图像分类网络,在CIFAR10 数据集中进行图像分类的正确率达到了98%,效果超过人类专家,居于业内领先位置。

VisualDL是一个面向深度学习任务设计的可视化工具。VisualDL原生支持Python的使用,只需要在模型中增加少量的代码,对VisualDL接口进行调用,便可以为训练过程提供丰富的可视化支持。除了Python SDK之外,VisualDL底层采用C++编写,其暴露的C++ SDK也可以集成到其他框架中,实现原生的性能和定制效果。用户也可以通过对C++ SDK进行封装,提供其他脚本语言的SDK。VisualDL目前支持标量、直方图、图像、音频、文本、高维图这6种可视化组件。

VisualDL帮助开发者方便地观测训练整体趋势、数据样本质量、数据中间结果、参数分布和变化趋势、模型的结构,快速地处理深度学习任务,完美地可视化深度学习过程。

深度学习的应用主要包括两个部分:一是通过深度学习框架训练出模型,二是利用训练出来的模型进行预测。开发者基于不同的深度学习框架能够得到不同的训练模型,如果想要基于一种框架进行预测,就必须要解决不同框架的模型之间的匹配问题。基于这种考虑,为了帮助用户快速从其他框架迁移,飞桨PaddlePaddle开源了模型转换工具X2Paddle。

X2Paddle可以将TensorFlow、Caffe 的模型转换为飞桨PaddlePaddle的核心框架Paddle Fluid可加载的格式。同时X2Paddle还支持ONNX格式的模型转换,这也相当于支持了众多可以转换为ONNX格式的框架,比如PyTorch、MXNet、CNTK等。

飞桨PaddlePaddle为百亿数据规模推荐业务提供了分布式训练及预测支持。

图1-5

图1-6

图1-7

从用法上来说,PaddlePaddle相对较规整,TensorFlow使用相对较灵活。

因为第1条和第4条,Paddle定义训练前除了feeding函数外,还需要准备好reader和event_handler;TensorFlow训练定义只需要准备好feeding函数就可以启动训练。

AI Studio 是百度推出的一站式开发平台,它是一个囊括了AI教程、代码环境、算法算力、数据集,并提供免费的在线云计算的一体化编程环境,如图1-8所示。用户不必纠结于复杂的环境配置和烦琐的扩展包搜寻,只要打开浏览器并在地址栏中输入aistudio.baidu.com,就可以在 AI Studio 中开始深度学习项目之旅。

图1-8

AI Studio开发者可以实现自定义的AI建模能力而无须考虑硬件成本、运维成本、人力成本。相比于在其他云平台付费购买计算资源和存储空间,AI Studio提供全套免费服务(计算资源免费、空间资源免费、项目托管免费,连视频教程也免费)。AI Studio平台集合了AI教程、深度学习样例工程、各领域的经典数据集、云端的运算及存储资源,以及比赛平台和社区,从而解决学习者在AI学习过程中的一系列难题,例如教程水平不一、教程和样例代码难以衔接、高质量的数据集不易获得,以及本地难以使用大体量数据集进行模型训练等。

百度AI Studio平台已经为用户预置了Python语言环境,并且内置了PaddlePaddle最新版本,无须再进行PaddlePaddle安装便可立即在线使用PaddlePaddle框架。同时,用户可以在其中自行加载Scikit-Learn等机器学习库。

在AI Studio中创建项目的界面如图1-9所示。

图1-9

1.创建项目

回到项目大厅页,点击居中的“创建项目”按钮,如图1-10所示。

图1-10

将会出现“创建项目”对话框,如图1-11所示。

图1-11

该对话框中各选项的作用如下。

2.添加数据集

如果项目涉及数据集,可以考虑直接使用系统预置的数据集,点击“添加数据集”按钮,然后出现图1-12所示的浮窗。

图1-12

每个项目最多可以引入两个数据集,以便于模型比较在不同数据集下的准确率和召回率。若无合适的数据集,用户也可以自行上传创建新数据集,点击“添加”按钮后自动返回图1-11所示的“创建项目”对话框。

最后,在“创建项目”对话框中,点击“创建”按钮并在弹出对话框中选择“查看”按钮进入项目详情页,如图1-13所示。

图1-13

然后在项目详情页对项目进行编辑,可以对数据集进行变更。

在项目详情页中,用户可以浏览自己刚创建的项目,并且编辑项目名称及数据集等信息,如图1-14所示。

图1-14

页面上部的两个标签页说明如下。

点击右方“运行项目”按钮进行项目环境初始化。在弹出的对话框中,点击“进入”按钮跳转到项目代码在线编辑Notebook环境,如图1-15所示。

图1-15

Notebook的使用说明详见1.8节。

如果不熟悉相关操作,则可以直接复制百度AI学习项目或者其他开发者共享的项目,加快学习速度,如图1-16所示。

图1-16

前面提到,VisualDL是一个面向深度学习任务设计的可视化工具,支持标量数据、参数分布、模型结构、图像可视化等功能。AI Studio单机项目已经集成VisualDL工具,可以在Notebook中编写VisualDL代码。

第一步,在训练代码中增加Logger来记录不同种类的数据。注意这里的logdir = "./log",即需要把log目录放到/home/aistudio/log。

logdir = "./log"
logwriter = LogWriter(logdir, sync_cycle=10)

with logwriter.mode("train") as writer:
    loss_scalar = writer.scalar("loss")

第二步,使用PaddlePaddle API创建训练模型。

def vgg16_bn_drop(input):
    pass

第三步,开始训练并且同时用VisualDL来采集相关数据。

        loss_scalar.add_record(step, loss)

第四步,在Web浏览器中输入URL访问。URL生成规则是将项目地址中的notebooks及之后部分替换为visualdl

#notebooks项目的URL
url_notebook = 'http://aistudio.baidu.com/user/30799/33852/notebooks/33852.ipynb?   
redirects=1'
#替换后的URL
url_visualdl = 'http://aistudio.baidu.com/user/30799/33852/visualdl'

当前Notebook编辑界面由如下几个部分组成,如图1-17所示。

图1-17

以下对每个区域的操作分别说明。

操作区如图1-18所示。

图1-18

1.新建块

点击 可以分别插入代码块和文字块。

图1-19

图1-20

选中某个块,然后点击 ,则可以使其在代码/文字之间进行切换。

2.操作块

点击 中的“运行”,对于代码块,则自动执行该块内容,同时激活下一个块。如果连续点击“运行”,则顺次执行。

块执行时,左侧的In[ ]会变成In[*],以示当前该块正在执行中。

如果发现代码不尽如人意,可以点击“中断”,中断所有代码块的执行,通常需要耗时数十秒才能完全停止。

如果需要重置整个项目环境,清除中间变量,则可以点击“重启”按钮。

1.命令/编辑模式

Notebook内容编辑区由基本的块(cell)组成。绿色代表块内容为可编辑状态——编辑模式(比如输入代码),蓝色代表块为可操作状态——命令模式(比如删除块,必须回到蓝色),与Linux编辑器Vi/Vim类似。编辑模式和命令模式之间可以用Esc键和Enter键来切换。

Notebook的编辑模式如图1-21所示。

图1-21

Notebook的命令模式如图1-22所示。

图1-22

2.鼠标操作

鼠标操作方式如图1-23所示。

图1-23

3.快捷键操作

表1-1列出了常用快捷键操作。

表1-1 Notebook两种模式下的常用快捷键操作

模式

内容

快捷键(Windows)

快捷键(Mac)

命令模式(通过Esc键切换)

运行块

Shift+Enter

Shift+Enter

命令模式

在下方插入块

B

B

命令模式

在上方插入块

A

A

命令模式

删除块

d+d

d+d

命令模式

切换到编辑模式

Enter

Enter

编辑模式(通过Enter键切换)

运行块

Shift+Enter

Shift+Enter

编辑模式

缩进

Clrl+]

Command+]

编辑模式

取消缩进

Ctrl+ [

Command+ [

编辑模式

注释

Ctrl+/

Command+/

编辑模式

函数内省

Tab

Tab

4.代码块In提示符

In提示符参见表1-2。

表1-2 In提示符

提示符

含义

In[ ]

程序未运行

In[num]

程序运行后

In[*]

程序正在运行

5.Linux命令

运行Linux命令的方式是在Linux命令前加一个“!”,这样就可以在块里运行命令了,如图1-24所示。

图1-24

通过Tab键查看提示信息或者补全命令,如图1-25所示。

图1-25

在一个库、方法或变量前加上“?”,就可以获得它的一个快速语法说明,如图1-26所示。

图1-26

Magic关键字是可以运行的特殊命令,参见表1-3。Magic 命令的前面带有一个或两个百分号(%或%%),分别代表行Magic命令和块Magic命令。行Magic命令仅应用于编写Magic命令时所在的行,而块Magic命令应用于整个块。

表1-3 Magic关键字

Magic关键字

含义

%timeit

测试单行语句的执行时间

%%timeit

测试整个块中代码的执行时间

%matplotlib inline

显示Matplotlib包生成的图形

%run

调用外部Python脚本

%pdb

调试程序

%pwd

查看当前工作目录

%ls

查看目录文件列表

%reset

清除全部变量

%who

查看所有全局变量的名称,若给定类型参数,只返回该类型的变量列表

%whos

显示所有的全局变量名称、类型、值/信息

%xmode Plain

设置为当异常发生时只展示简单的异常信息

%xmode Verbose

设置为当异常发生时展示详细的异常信息

%debug

bug调试,输入quit退出调试

%bug

调试,输入quit退出调试

%env

列出全部环境变量

示例1:使用%%timeit测试整个块的运行时间,如图1-27所示。

图1-27

示例2:块可集成matplotlib,从而进行绘图,但注意绘图前需要输入%matplotlib inline并运行,否则即使运行终端可用的绘图代码段,cell也只会返回一个文件说明,如图1-28所示。

图1-28

示例3:查看所有支持的Magic关键字,如图1-29所示。

图1-29

示例4:查看当前环境中的Python版本和Paddle版本,如图1-30所示。

图1-30

6.文字块说明

除文本外,文字块还可嵌入公式、表格、图片、音乐、视频、网页等。

相关Markdown用法可以参考其官网。

插入图片的方法如下。

(1)点击“编辑”菜单中的“插入图片”,如图1-31所示。

图1-31

(2)上传图片,如图1-32所示。

图1-32

(3)图片插入成功,如图1-33所示。

图1-33

侧边栏如图1-34所示。

图1-34

1.文件夹

按照树状结构展示/home/aistudio路径下的文件夹和文件,如图1-35所示。可以在该目录下进行如下操作。

图1-35 

2.数据集

在数据集栏中,可以复制数据集文件的路径,并置于代码中,如图1-36所示。

图1-36

若复制数据集路径成功,则出现提示,如图1-37所示。

图1-37

顶部工具栏有大量的功能,由于名称的含义一目了然,因此不一一介绍,具体参见图1-38。

图1-38

集群项目的任务执行由GPU集群支撑,具有实时高速的并行计算和浮点计算能力,有效减轻了深度学习训练中的计算压力,提高了处理效率。

用户可以先在单机项目中,利用在线的Notebook功能,完成代码的编写与调试,之后在集群项目中运行,从而提高模型训练速度。

点击主页上的“创建项目”按钮,进入“创建项目”对话框,如图1-39和图1-40所示。

图1-39

图1-40

对于“配置资源”选择“远程集群”,等待几秒后进入集群项目详情页。

在集群项目详情页中,用户可以浏览自己创建的项目内容,编辑项目名称及数据集等信息,查看集群历史任务信息等,如图1-41所示。

图1-41

代码编辑界面主要分为左侧(文件管理及数据集区域)和右侧(文件预览编辑和提交任务区域)两个部分,如图1-42所示。

图1-42

左侧的文件管理和数据集区域如图1-43所示。

图1-43

用户可以手动创建文件/文件夹,对文件/文件夹进行重命名或删除。用户可以选择指定文件,并设置为主文件,以用作整个项目的入口。用户也可以手动上传文件(上限为20MB,更大文件请通过数据集上传)。用户可以双击文件,在右侧将新建一个标签页。用户可以进一步查看或编辑该文件的内容(目前仅支持.py文件和.txt文件,同时预览文件的上限为1MB)。用户可以查看数据集文件,并复制该文件的相对路径,最后拼合模板内置绝对路径,即可使用文件。

右侧的文件预览编辑和提交任务区域如图1-44所示。

图1-44

当多个文件被打开时,用户可以将它们逐一关闭,最后一个文件不可关闭。选中文件对应的标签页即可对文件内容进行预览和编辑,但当前仅支持.py和.txt格式的文件。点击“保存”按钮,会将所有文件的改动信息都保存,若用户不提交任务,直接退出,则自动保存为一个“未提交”版本。提交任务前,建议写一个备注名称,方便未来进行不同版本代码/参数的效果比较。

PaddlePaddle基于集群的分布式训练任务与单机训练任务的调用方法不同。基于pserver- trainer架构的分布式训练任务分为两种角色——parameter server(pserver)和trainer。

在Fluid中,用户只需要进行单机训练所需要的网络配置,DistributeTranspiler模块会自动地根据当前训练节点的角色将用户配置的单机网络配置改写成pserver和trainer需要运行的网络配置。

t = fluid.DistributeTranspiler()
t.transpile(
    trainer_id = trainer_id,
    pservers = pserver_endpoints,
    trainers = trainers)
if PADDLE_TRAINING_ROLE == "TRAINER":
    #获取pserver程序并执行它
    trainer_prog = t.get_trainer_program()
    ...

elif PADDLE_TRAINER_ROLE == "PSERVER":
    #获取trainer程序并执行它
    pserver_prog = t.get_pserver_program(current_endpoint)
    ...

目前集群项目中提供的默认环境PADDLE_TRAINERS=1。(PADDLE_TRAINERS是分布式训练任务中trainer节点的数量。)

非PaddlePaddle代码请放到if PADDLE_TRAINING_ROLE == "TRAINER"分支下执行,例如数据集解压任务。

集群项目中添加的数据集统一放到绝对路径./datasets中。

#数据集文件会自动复制到./datasets目录下
CLUSTER_DATASET_DIR = '/root/paddlejob/workspace/train_data/datasets/'

集群项目数据集文件路径的获取方式如下。在页面左侧数据集中点击图1-45中虚线框标注的图标,复制数据集文件路径,得到文件的相对路径,例如点击后复制到剪切板的路径为data65/train-labels-idx1-ubyte.gz

#数据集文件相对路径
file_path = 'data65/train-labels-idx1-ubyte.gz'

图1-45

真正使用的时候需要将两者拼合,即train_datasets = datasets_prefix + file_path。

集群项目输出文件路径为./output

#需要下载的文件可以输出到'/root/paddlejob/workspace/output'目录
CLUSTER_OUTPUT_DIR = '/root/paddlejob/workspace/output'

点击图1-14中的“运行项目”按钮后进入任务编辑页面,如图1-46所示。

图1-46

历史任务页面如图1-47所示。

图1-47

任务操作有如下几种。

集群项目空间安装包及版本号参见表1-4。

表1-4 集群项目空间安装包及版本号

安装包

版本号

backports.functools-lru-cache

1.5

cycler

0.10.0

graphviz

0.10.1

kiwisolver

1.0.1

matplotlib

2.2.3

nltk

3.4

numpy

1.15.4

opencv-python

3.4.4.19

paddlepaddle-gpu

1.3.1

Pillow

5.3.0

pip

18.1

protobuf

3.1.0

pyparsing

2.3.0

rarfile

3.0

recordio

0.1.5

requests

2.9.2

scipy

1.1.0

setuptools

40.6.2

six

1.12.0

subprocess32

3.5.3

wheel

0.32.3

在线部署与预测为开发者提供训练模型向应用化API转换的功能。开发者在AI Studio平台通过单机项目Notebook页面完成模型训练后,通过创建一个在线服务,应用模型生成在线API,使用该API可以直接检验模型效果或将模型实际应用到开发者的私有项目中,如图1-48所示。目前,该功能暂时仅对单机项目开放。

图1-48

在训练任务过程中,通过调用paddle.fluid.io.save_inference_model 实现模型的保存,保存后的目录需要可以被在线服务使用。我们以房价预测的线性回归任务为例,具体代码如下。

import paddle
import paddle.fluid as fluid
import numpy
import math
import sys
from __future__ import print_function
BATCH_SIZE = 20
train_reader = paddle.batch(
   paddle.reader.shuffle(
      paddle.dataset.uci_housing.train(), buf_size=500),
      batch_size=BATCH_SIZE)
test_reader = paddle.batch(
   paddle.reader.shuffle(
      paddle.dataset.uci_housing.test(), buf_size=500),
      batch_size=BATCH_SIZE)
params_dirname = "model2"
x = fluid.layers.data(name='x', shape=[13], dtype='float32')
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
y_predict = fluid.layers.fc(input=x, size=1, act=None)
main_program = fluid.default_main_program()
startup_program = fluid.default_startup_program()
cost = fluid.layers.square_error_cost(input=y_predict, label=y)
avg_loss = fluid.layers.mean(cost)
sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.001)
sgd_optimizer.minimize(avg_loss)
test_program = main_program.clone(for_test=True)
use_cuda = False
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
exe = fluid.Executor(place)
num_epochs = 100
def train_test(executor, program, reader, feeder, fetch_list):
   accumulated = 1 * [0]
   count = 0
   for data_test in reader():
      outs = executor.run(program=program,
                       feed=feeder.feed(data_test),
                       fetch_list=fetch_list)
      accumulated = [x_c[0] + x_c[1][0] for x_c in zip(accumulated, outs)]
      count += 1
   return [x_d / count for x_d in accumulated]
params_dirname = "fit_a_line.inference.model"
feeder = fluid.DataFeeder(place=place, feed_list=[x, y])
naive_exe = fluid.Executor(place)
naive_exe.run(startup_program)
step = 0
exe_test = fluid.Executor(place)
for pass_id in range(num_epochs):
   for data_train in train_reader():
      avg_loss_value, = exe.run(main_program,
                            feed=feeder.feed(data_train),
                           fetch_list=[avg_loss])
      if step % 10 == 0: 
         print (step, avg_loss_value[0])
      if step % 100 == 0:
         test_metics = train_test(executor=exe_test,
                              program=test_program,
                              reader=test_reader,
                              fetch_list=[avg_loss.name],
                              feeder=feeder)
         print (step, test_metics[0])
         if test_metics[0] < 10.0:
            break
      step += 1
      if math.isnan(float(avg_loss_value[0])):
         sys.exit("got NaN loss, training failed.")
   if params_dirname is not None:
      fluid.io.save_inference_model(params_dirname, ['x'],
                              [y_predict], exe)

使用已有模型,可以通过!wget在Notebook中将模型文件传输到环境目录下。以房价预测的线性回归模型为例,通过!wget https://ai.baidu.com/file/4E1D1FCC670E4 A5E8441634201658107- O fit_a_line.inference.model传输文件,解压后直接被在线服务使用,如图1-49所示。

图1-49

完成模型训练后,在单机项目页面中点击“创建预测服务”按钮,如图1-50所示,创建一个在线服务。

图1-50

1.选择模型文件

选择模型文件,如图1-51所示。

图1-51

已选中的文件将出现在右边的框中,如图1-52所示。

图1-52

设置主程序,主程序为paddle.fluid.io.save_inference_model中参数main_program配置的程序。在房价预测的示例中,我们使用默认参数调用save_inference_model,因此将__model__文件设置为主程序,如图1-53所示。

图1-53

2.确认输入/输出

填写模型的输入/输出参数。以房价预测的线性回归模型为例,添加的参数如图1-54所示。

图1-54

3.制作参数转换器

参数转换器帮助用户将参数转换为合法输入并完成数据预处理。

输入参数转换器的使用方法如下。

def reader_infer(data_args):
       """
       reader_infer 输入参数转换器方法
       :param data_args: 接口传入的数据
       :return [[]], feeder
       """
       #构造内容
       pass

输出参数转换器的使用方法如下。

def output(results, data_args):
       """
       output 输出参数转换器方法
       :param results 模型预测结果
       :param data_args: 接口传入的数据
              :return array 需要被json_encode处理的数据格式
              """
       #构造内容
       pass

以房价预测为例,输入参数转换器的代码如下所示。

import os
import sys
sys.path.append("..")
from PIL import Image
import numpy as np
import paddle.fluid as fluid
from home.utility import base64_to_image
def reader_infer(data_args):
   """
   reader_infer 输入参数转换器方法
   :param data_args: 接口传入的数据
   :return [[]], feeder
   """
   def reader():
      """
      reader
      :return:
      """
      x = fluid.layers.data(name='x', shape=[13], dtype='float32')
      # y = fluid.layers.data(name='y', shape=[1], dtype='float32')
      feeder = fluid.DataFeeder(place=fluid.CPUPlace(), feed_list=[x])
      CRIM = float(data_args["CRIM"])
      ZN = float(data_args["ZN"])
      INDUS =  float(data_args["INDUS"])
      CHAS = float(data_args["CHAS"])
      NOX = float(data_args["NOX"])
      RM = float(data_args["RM"])
      AGE = float(data_args["AGE"])
      DIS = float(data_args["DIS"])
      RAD =  float(data_args["RAD"])
      TAX = float(data_args["TAX"])
      PTRATIO = float(data_args["PTRATIO"])
      B =  float(data_args["B"])
      LSTAT = float(data_args["LSTAT"])
      return [[[CRIM, ZN, INDUS, CHAS, NOX, RM, AGE, DIS, RAD, TAX, PTRATIO, B, LSTAT]]], 
          feeder
   return reader

输出参数转换器的代码如下所示。

def output(results, data_args):
   """
   output 输出参数转换器方法
   :param results 模型预测结果
   :param data_args: 接口传入的数据
   :return array 需要被json_encode处理的数据格式
   """
  lines = []
  for dt in results:
     y = dt.tolist()
     lines.append({"predict": y})
  return lines

用户的API参数直接传递给模型,如图1-55所示。

图1-55

4.沙盒部署

用户最多可以同时部署5个沙盒服务,用来对比模型优化结果。

录入名称,点击“生成沙盒”按钮或者点击“暂存”按钮将沙盒保存到草稿箱,如图1-56所示。

图1-56

对沙盒列表中的沙盒服务进行测试,验证是否配置正确。步骤如下。

(1)点击“测试”打开测试页面,如图1-57所示。

图1-57

(2)填写json格式请求参数,如图1-58所示。

图1-58

(3)点击“发送请求”按钮检验返回结果,如图1-59所示。

图1-59

点击“正式部署”部署线上API,如图1-60和图1-61所示。

图1-60

图1-61

对于一个项目,可以创建5个沙盒服务,并把其中1个沙盒服务部署为线上服务。沙盒服务如果连续超过24小时无调用,将自动调整为暂停状态。线上服务如果连续超过14天无调用,将自动调整为暂停状态。

依据API key、服务地址(见图1-62)和用户自定义参数,实现对服务的调用。

图1-62

1.请求方式

2.调用示例

以房价预测项目为例,CURL调用示例如下。

curl -H "Content-Type: application/json" -X POST -d '{"CRIM":0.01887747, "ZN":-0.11363636, "INDUS":0.25525005, "CHAS":-0.06916996,  "NOX":0.29898136, "RM": -0.04476612, "AGE":  
0.14340987, "DIS":-0.14797285,  "RAD":0.62828665, "TAX":0.49191383, "PTRATIO":0.18558153,  
"B":0.05473289, "LSTAT":0.16851371}' "https://aistudio.baidu.com/serving/online/xxx?apiKey=   
xxxxxxxxxx"

Python调用示例如图1-63所示。

图1-63

NumPy(Numerical Python)是 Python 中的一个线性代数库,它为Python提供高性能的向量、矩阵和高维数据结构的科学计算。NumPy通过C和Fortran实现,因此在用向量和矩阵建立方程并实现数值计算时有非常好的性能。对于每一个数据科学或机器学习Python包而言,NumPy都是一个非常重要的库,SciPy(Scientific Python)、matplotlib、Scikit-learn等都在一定程度上依赖NumPy。PaddlePaddle在通过pip安装时会自动安装对应版本的NumPy。

在对数组进行数学运算和逻辑运算时,NumPy 是非常有用的。在用Python对n维数组和矩阵进行运算时,NumPy 提供了大量有用特征。在使用 PaddlePaddle时,NumPy不仅是一个库,它还是实现深度学习数据表示的基础之一。因此,了解它的工作原理、关注向量化和广播(broadcasting)是非常必要的。

这一节介绍数据科学初学者需要了解的NumPy基础知识,包括如何创建NumPy数组、如何使用NumPy中的广播机制、如何获取值以及如何操作数组。更重要的是,大家可以通过本节了解到NumPy处理Python列表数据的优势:更简洁、更快速地读写项,并且更方便、更高效。

1.安装NumPy

在安装PaddlePaddle时,PaddlePaddle的安装程序会自动在当下环境集成适合该PaddlePaddle版本的NumPy包。PaddlePaddle的安装方法在第2章中介绍。如果要单独安装NumPy,那么可以使用以下命令从终端上安装 NumPy。

pip install numpy

如果已经安装了Anaconda,那么可以使用以下命令通过终端或命令提示符安装 NumPy。

conda install numpy

2.使用Python列表创建NumPy数组

NumPy数组是包含相同类型值的网格。NumPy数组有两种形式——向量和矩阵。在计算机科学中,向量是一维数组,矩阵是多维数组。在某些情况下,矩阵也可以只有一行或一列。

在使用NumPy之前先赋予包别名。

import numpy as np

先创建一个Python列表“first_list”。

first_list = [1, 2, 3, 4, 5]

通过这个列表,可以简单地创建一个名为one_dimensional_list_list的NumPy数组,显示结果。

one_dimensional_list = np.array(first_list)
one_dimensional_list  #这里将回显刚刚由first_list数组生成的结果

刚才将一个Python列表转换成了一维NumPy数组。要得到二维数组,就要创建一个以列表为元素的列表,如下所示。

second_list = [[1,2,3], [5,4,1], [3,6,7]]
two_dimensional_list = np.array(second_list)
two_dimensional_list  #这里将回显刚刚由second_list数组生成的结果
array ([[1, 2, 3],
        [5, 4, 1],
        [3, 6, 7]])

3.使用内置函数arange()创建NumPy数组

NumPy可以用arange()创建一个数组,这与Python的内置函数range()相似。

first_list = np.arange(10)

或者

first_list = np.arange(0,10)

这就产生了0~9的10个数字。

first_list
array ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

要注意的是, np.arange() 函数中有3个参数。第一个参数表示起始位置,第二个参数表示终止位置,第三个参数表示步长。例如,要得到 0~10 中的偶数,只需要将步长设置为 2 就可以了,如下所示。

first_list = np.arange(0,11,2)
first_list
array ([ 0,  2,  4,  6,  8, 10])

还可以创建有 7 个 0 的一维数组。

my_zeros = np.zeros(7)
my_zeros
array ([0., 0., 0., 0., 0., 0., 0.])

也可以创建有 5 个 1 的一维数组。

my_ones = np.ones(5)
my_ones
array ([1., 1., 1., 1., 1.])

同样,可以生成内容都为0的7行5列二维数组。

two_dimensional_zeros = np.zeros((7,5))
two_dimensional_zeros
array ([[0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.]])

函数empty可创建一个初始元素为随机数的数组,操作方法和zeros如出一辙。具体随机量取决于内存状态。默认状态下,所创建数组的数据类型(dtype)一般是 float64。

4.使用内置函数linspace()创建NumPy数组

linspace() 函数返回在指定范围内具有指定间隔的数字。也就是说,如果要得到区间[0,12]中间隔相等的4个数,可以使用以下命令。

isometry_arr = np.linspace(0, 12, 4)
isometry_arr

该命令将结果生成一维向量。

array ([ 0.,  4.,  8., 12.])

与arange()函数不同,linspace() 的第三个参数是要创建的数据点的数量。

5.在NumPy中创建一个单位矩阵

单位矩阵也叫恒等矩阵、纯量矩阵。在处理线性变换时,单位矩阵是非常有用的,它表示无缩放、旋转或平移的变换。一般对于图像而言,单位矩阵是一个二维方阵,也就是说,在这个矩阵中列数与行数相等。单位矩阵的特点是它的对角线上的元素都是1,其他的元素都是0。创建单位矩阵一般只有一个参数。下述命令说明了如何创建6×6的单位矩阵。

identity_matrix = np.eye(6)

6.用NumPy创建一个由随机数组成的数组

一般比较常用的random系函数有rand()、randn()或randint(),它们都具备生成随机数的功能。

使用 random.rand(),可以以给定的形状创建一个数组,并在数组中加入在[0,1]内均匀分布的随机样本。

如果要创建由4个对象组成的一维数组,并使得这4个对象均匀分布在[0,1]中,可以这样做。

my_rand = np.random.rand(4)
my_rand
array([0.54530499, 0.4791477 , 0.17816267, 0.98061916])

如果要创建一个 3 行 4 列的二维数组,则可以使用以下代码。

my_rand = np.random.rand(3, 4)
my_rand
array([[3.64058527e-01, 9.05102725e-01, 3.25318028e-01, 4.86173815e-01],
      [6.85567784e-01, 7.30340885e-02, 1.36020526e-01, 3.13770036e-04],
      [2.76068271e-02, 5.37804406e-01, 6.09760670e-01, 9.03652017e-01]])

使用 randn(),可以创建一个期望为0、方差为1的标准正态分布(高斯分布)的随机样本。例如,从中生成 30 个服从标准正态分布的随机数。

my_randn = np.random.randn(30)
my_randn

array([ 0.46344253, -1.1180354 , -0.76683867,  0.60764125,  0.75040916,
       0.52247857,  1.05988275, -0.40201072, -0.21179046, -0.17263014,
       1.3185744 ,  0.59589626,  1.24200835, -0.80713838,  2.07958112,
       1.37557692,  1.35925843, -0.05960489,  1.26046288,  0.88368104,
       0.30442813,  2.57724599, -0.94821606,  0.37336274, -1.1968936 ,
       1.10085423,  0.3339304 ,  0.63401235,  0.6585172 ,  0.72375082])

要将其表示为3行5列的二维数组,使用以下代码即可。

np.random.randn(3,5)

使用randint()函数生成整数数组。randint() 函数最多可以有3个参数,分别是最小值(包含,默认为0)、最大值(不包含,必填)以及数组的大小(默认为1)。

np.random.randint(5, 20, 7) 
array([10, 12, 19, 12,  8, 13, 14])

7.将一维数组转换成二维数组

首先,创建一个有20个随机整数的一维数组。

arr = np.random.rand(20)

然后,使用 reshape() 函数将其转换为二维数组。

arr = arr.reshape(4,5)
array([[0.85161986, 0.06722657, 0.22270304, 0.60935757, 0.20345998],
      [0.67193271, 0.27533643, 0.30484289, 0.78642633, 0.7400095 ],
      [0.63484647, 0.48679984, 0.93656238, 0.81573558, 0.22958044],
      [0.57825764, 0.79502777, 0.77810231, 0.37802153, 0.6360811 ]])

注意,在使reshape() 进行转换时,要保证行列数相乘后与元素数量相等。

假设存在大量数组,而你需要弄清楚数组的形状,只需要使用 shape 函数即可。

arr.shape()
 (4, 5)

8.定位NumPy数组中的最大值和最小值

使用max()和min()函数,分别可以得到数组中的最大值和最小值。

arr_2 = np.random.randint(0, 20, 10) #在0到20中随机生成10个数字
array([ 8,  9, 13, 13,  1, 14,  8,  0, 17, 18])
arr_2.max() #返回最大的数字,即18
arr_2.min() #返回最小的数字,即0

使用argmax()和argmin()函数,分别可以定位数组中最大值和最小值的下标。

arr_2.argmax() #返回最大的数字的下标,即9
arr_2.argmin() #返回最小的数字的下标,即7

9.从NumPy数组中索引/选择多个元素(组)

在NumPy数组中进行索引与在Python中类似,只需要在方括号中指定下标即可。

my_array = np.arange(0,13)
my_array[8]  
8

要获得数组中的一系列值,可以使用切片符“:”,这和Python中的使用方法一样。

my_array[2:6] 
array([2, 3, 4, 5])
my_array[:5]
array([0, 1, 2, 3, 4])
my_array[5:]
array([ 5,  6,  7,  8,  9, 10, 11, 12])

同样也可以通过使用 [ ][ ] 或 [,] 在二维数组中选择元素。

现在使用 [ ][ ] 从下面的二维数组中抓取出值「60」。

two_d_arr = np.array([[10,20,30], [40,50,60], [70,80,90]])
two_d_arr[1][2] #抓取第二行第三列

使用 [,] 从上面的二维数组中抓取出值「20」。

two_d_arr[0,1] #抓取第二行第三列

也可以用切片符抓取二维数组的子部分。使用下面的操作从数组中抓取一些元素。

two_d_arr[:1, :2] #将返回 [[10, 20]]
two_d_arr[:2, 1:] #将返回 ([[20, 30], [50, 60]])
two_d_arr[:2, :2] #将返回 ([[10, 20], [40, 50]])

还可以索引一整行或一整列。只需要使用索引数字即可抓取任意一行。

two_d_arr[0]    #将返回第一行 ([10, 20, 30])

还可以使用 &、|、<、> 和 == 运算符对数组执行条件选择和逻辑选择,从而对比数组中的值和给定值。

new_arr = np.arange(5,15)
new_arr > 10 
False, False, False, False, False, False,  True,  True,  True, True]

组合使用条件运算符和逻辑运算符,可以得到值大于 3 且小于 10 的元素。

new_arr[(new_arr>3) & (new_arr<10)]
array([5, 6, 7, 8, 9])

10.广播机制

广播机制是 NumPy 非常重要的一个特点,它允许 NumPy 扩展矩阵间的运算。例如,它会隐式地把一个数组的异常维度调整到与另一个算子相匹配的维度以实现维度兼容。例如,将一个维度为 [3,2] 的矩阵与另一个维度为 [3,1] 的矩阵相加是合法的,NumPy 会自动将第二个矩阵扩展到等同的维度。

为了定义两个形状是否是可兼容的,NumPy从最后开始往前逐个比较它们的维度大小。在这个过程中,如果两者的对应维度相同,或者其中一个(或者二者都)等于 1,则继续进行比较,直到最前面的维度。若不满足这两个条件,程序就会报错。

最简单的广播机制是快速改变 NumPy 数组中的值,例如,将索引为 0~5 的元素的初始值改为 20。

my_array = np.arange(0,13)
my_array[0:5] = 20
array([20, 20, 20, 20, 20,  5,  6,  7,  8,  9, 10, 11, 12])

当两个矩阵维度不匹配时,使用以下代码。

a = np.array([1.0,2.0,3.0,4.0, 5.0, 6.0]).reshape(3,2)
b = np.array([3.0])
a * b
array([[ 3.,  6.],
      [ 9., 12.],
      [15., 18.]])

11.对NumPy数组执行数学运算

对NumPy数组执行数学运算的语法就和你想象的一样。

arr = np.arange(1,11)
arr * arr              
arr - arr              
arr + arr              
arr / arr

还可以通过NumPy 广播机制批量对数组执行标量运算。

arr + 50

NumPy 还允许在数组上执行通用函数,如平方根函数、指数函数和三角函数等。

np.sqrt(arr)    
np.exp(arr)     
np.sin(arr)     
np.cos(arr)     
np.log(arr)     
np.sum(arr)     
np.std(arr)

12.对NumPy数组执行点积(内积)运算

我们一般使用np.dot()执行点积运算,如同NumPy官网指出的,如果ab都是一维数组,它的作用是计算内积(不进行复共轭)。执行点积运算的前提是左边矩阵的列数(每行的元素)必须等于右边矩阵的行数,否则就会报错。对于秩为1的数组,对应位置的元素先相乘,然后再相加;对于秩不为1的二维数组,执行矩阵乘法运算。下面的例子展示了二维矩阵的点积运算。

I = np.eye(3)
I
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
D = np.arange(1,10).reshape(3,3)
D
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
M = np.dot(D,I)
M
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]])


相关图书

ChatGPT原理与应用开发
ChatGPT原理与应用开发
深度学习的数学——使用Python语言
深度学习的数学——使用Python语言
深度学习:从基础到实践(上、下册)
深度学习:从基础到实践(上、下册)
动手学深度学习(PyTorch版)
动手学深度学习(PyTorch版)
深度学习与医学图像处理
深度学习与医学图像处理
深度强化学习实战:用OpenAI Gym构建智能体
深度强化学习实战:用OpenAI Gym构建智能体

相关文章

相关课程