描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787301305812
(1)一切以代码说话:本书的一切原理都有相应的代码实现。一时不能理解的原理,可以通过实践慢慢体会,能够让程序员以较低的成本迅速入门。
(2)从现象到本质:世界上除了这两种主流框架之外,还有微软的cntk、亚马逊的mxnet、百度的paddlepaddle等。其实本质上它们都趋同的,有了本书学习的基础,寄希读者可以更高维度地思考框架背后的设计理念,有所取舍,而不沦为其奴仆。
(3)5-4-6 速成法:深度学习用到的数学知识很多,概念也很多,学习曲线很陡。但是,笔者还是从中抓住了一条主线——计算图模型。基于计算图模型,总结出了5-4-6 速成法,通过5 步,使用4 种基本元素,组合6 种基本网络结构,就能够写出功能非常强大的深度学习程序。
(4)超越深度学习:本书还讲解了深度学习的两个重要应用:如何自动调参和深度学习引发的强化学习。可以看到,编程变得越来越简单,但是系统变得越来越复杂。我们一方面要时刻关注它们的进展,另一方面手工写神经网络的基本功还不能丢。
(5)赠送资源丰富:本书配套的源代码 100分钟配套学习视频 相关技术延伸阅读。
《TensorFlow PyTorch深度学习从算法到实战》详尽介绍深度学习相关的基本原理与使用TensorFlow、PyTorch两大主流框架的开发基础知识和基本技术,并且展示了在图像识别与文本生成实际问题中的应用方法。同时考虑到程序员擅长JavaScript 的人员比熟悉Python 的人员更多的情况,特别增加了对于TensorFlow.js 的介绍。初学者面对深度学习望而却步的主要原因是认为入门门槛太高,需要较多的算法基础训练。针对此问题,本书原创了5-4-6 学习模型提纲挈领地降低学习曲线,并通过将知识点和难点分散到代码中的方式让读者以熟悉的方式迅速入门,并且为进一步学习打下坚实的基础。同时,本书也介绍了AutoML和深度强化学习等新技术,帮助读者开阔眼界。
《TensorFlow PyTorch深度学习从算法到实战》内容翔实,讲解深入浅出,通俗易懂,配有大量的程序案例可供实操学习,既适合职场中经验丰富的开发人员学习,又可供计算机等相关专业的在校学生和其他科技人员参考,还可供算法理论相关的研究人员参考。
绪论程序员为什么要学习机器学习
0.1工业革命级的技术红利
0.2中美两国为机器学习作背书
0.3从编程思维向数据思维的进化
第1章30分钟环境搭建速成
1.1使用Anaconda搭建开发环境
1.2使用Python自带的开发环境
1.3从源代码搭建开发环境
第2章深度学习5-4-6速成法
2.1计算图模型与计算框架
2.2五步法构造基本模型
2.3案例教程
2.45-4-6速成法学习PyTorch
2.55-4-6速成法学习TensorFlow
2.6在TensorFlow中使用Keras
2.7本章小结
第3章张量与计算图
3.10维张量:标量
3.2计算图与流程控制
3.3变量
第4章向量与矩阵
4.11维张量:向量
4.22维张量:矩阵
4.3n维:张量
第5章高级矩阵编程
5.1范数及其实现
5.2迹运算
5.3矩阵分解
第6章优化方法
6.1梯度下降的基本原理
6.2高维条件下的梯度下降
6.3PyTorch和TensorFlow中的梯度计算
6.4梯度下降案例教程
6.5优化方法进阶
第7章深度学习基础
7.1从回归到分类
7.2深度学习简史
第8章基础网络结构:卷积网络
8.1卷积的原理与计算
8.2池化层
8.3激活函数
8.4AlexNet
第9章卷积网络图像处理进阶
9.1小卷积核改进VGGNet
9.2GoogLeNet
9.3残差网络
9.4目标检测
9.5人脸识别
第10章基础网络结构:循环神经网络
10.1循环神经网络原理
10.2实用循环神经网络:LSTM
10.3LSTM案例教程
10.4实用循环神经网络:GRU
10.5双向循环神经网络
10.6将隐藏状态串联起来
第11章RNN在自然语言处理中的应用
11.1文本编码:从独热编码到词向量
11.2Char-RNN算法
11.3Char-RNN的训练
11.4Char-RNN的预测推理
11.5Char-RNN完整模型
第12章用JavaScript进行TensorFlow编程
12.1TensorFlow.js的简介和安装
12.2TensorFlow.js的张量操作
12.3TensorFlow.js的常用运算
12.4激活函数
12.5TensorFlow.js变量
12.6TensorFlow.js神经网络编程
12.7TensorFlow.js实现完整模型
12.8TensorFlow.js的后端接口
第13章高级编程
13.1GPU加速
13.2生成对抗网络
13.3Attention机制
13.4多任务学习
第14章超越深度学习
14.1自动机器学习AutoML
14.2Autokeras
14.3WindowsSubsystemforLinux
14.4强化学习
14.5强化学习编程
14.6下一步的学习方法
人工智能时代,深度学习是程序员必须具备的基础技能,此书知识全面,从环境搭建,学习方法到应用分析,真正做到了“深度学习的开发指南”。
——北京人人众包科技有限公司CEO 张建胜
本书是程序员掌握深度学习的利器之一,采用更多示例和工程经验来展示深度学习背后的数学原理,对术语的解释也更贴近程序员的理解范畴,实用性和平缓的学习曲线是本书的一大特点。对于人工智能专业的学生以及工业界的开发人员来说,本书都值得一读。
——开源编译器XOC作者 苏振宇
深度学习涉及的知识点比较多,特别是对数学基础要求很高,而这门学问在高校学习中尚属新宠。从学术的角度,很难绕过这些枯燥的理论,而本书却巧妙的规避了这个难题,通过自己的亲手实践,在作者一步一步的指导下结合具体的应用不断深入。本书另外一个突出点就是并未回避那些必须深入学习的理论。将他们一一罗列出来,给出一个梗概,让学者有迹可循,有纲可依,凭此一书,既可以快速上手又可以寻迹深入,实在难得。在我阅读过程中,丝毫没有违和感,学习起来轻松自在,就好像是在读自己整理的学习笔记。本书即可以作为大学深度学习普及课程用书,也适合做程序员掌中宝。
——清华大学校友会软件学院分会副会长 周虎
人工智能是科技新纪元的开端,深度学习就是打开这个新纪元的钥匙。作为“给程序员看的深度学习教程”,本书既符合了程序员迅速入门深度学习的实际需求,又搭建了一套完整的深度学习知识体系,并且给出了前沿的论文线索,读者可以根据自己的需要进行阅读,由表及里、由浅入深地掌握深度学习的各个层次知识。另外,本书同时讲解多框架也极具特色,有助于读者在比较的基础上进行灵活选用,真正理解深度学习的精华。
——北京微识科技有限公司CEO杨竹筠
曾有幸与本书作者共事,就很佩服他作为一个技术出身的工程师,对待项目有着极其开阔的视野,从大势出发,在细节着眼。本书中不只介绍深度学习开发框架的使用,还通过对比,寄希读者可以更高维度地思考框架背后的设计理念,有所取舍,而不沦为其奴仆。
至今,机器学习还在快速发展中,每天都有各类新的理论、模型去试图解决历史方法无法拟合的场景。各种模型本身并没有高低贵贱之分,只是对当前场景适合与否。作为一个从业者,需要打下扎实的理论基础,多向同行学习一些新的建模思路,定期看paper了解业内的观点,并坚信未来已来。
——今天便利店信息技术负责人 姚军勇
第3章
张量与计算图
第2章我们尝试了深度学习的乐趣。“万丈高楼平地起”,我们看到了目标之后,并不等于有捷径达到目标,还是需要踏踏实实地从基本的元素开始学习。
Google的深度学习框架名称为TensorFlow,可见Tensor张量对于这个框架的重要性。另外,张量虽然很重要,但是如何将张量组合起来也同样重要。目前主流的框架都是通过计算图的方式来将张量组织起来。我们通过静态计算图的典型案例TensorFlow和动态计算图的典型PyTorch,可以深刻地理解计算图的本质。
本章将介绍以下内容
0维张量:标量
计算图与流程控制
变量
3.1 0维张量:标量
所谓张量,从程序员的角度理解,就是一个多维的数组。根据维数不同,不同的张量有不同的别名。
0维的张量,称为标量。标量虽然*简单,但是也涉及数据类型、算术运算、逻辑运算、饱和运算等基础操作。
1维的张量,称为向量。从向量开始,我们就不得不引入Python 生态的重要工具库——
NumPy。作为静态计算图代表的TensorFlow,几乎是完全实现了一套NumPy 的功能,所以它的跨语言能力很强。而PyTorch对于NumPy能支持的功能全部复用,只对NumPy缺少的功能进行补充。例如,NumPy计算无法使用GPU进行加速,而PyTorch就实现了NumPy功能的GPU加速。可以将PyTorch理解为可借用GPU进行加速的NumPy库。
2维的张量,称为矩阵。在机器学习中对于矩阵有非常多的应用,这里涉及不少数学知识。本章我们只讲基本概念和编程,第4章会专门讲矩阵。
3维以上的张量是我们一般意义上所认为的真正的张量。在深度学习所用的数据中,我们基本上都用高维张量来处理,并根据需要不停地将其变换成各种形状的张量。
标量可以理解为一个数。虽然一个数从某方向来讲已是*简单的结构,但是对于机器学习来说,也涉及不少问题,如数据类型、计算精度。很多的优化也跟数据类型相关。
3.1.1 TensorFlow的数据类型
在学习数据类型之前,我们先看一下TensorFlow和PyTorch风格的数据类型对比图。如图3.1所示,TensorFlow比PyTorch多了复数类型。其实总体来说TensorFlow的类型丰富程度远胜于PyTorch。
TensorFlow的数据类型分为整型、浮点型和复数型3种,基本上对应NumPy的整型、浮点型和复数型,只不过每种类型的子类型比NumPy更少一些。而PyTorch比TensorFlow更加精简。原因是TensorFlow是静态计算图语言,相对要比较完备。而PyTorch是动态计算图语言,可以借助NumPy的功能。
图3.1 TensorFlow和PyTorch的数据类型对比
具体类型如图3.2所示。
图3.2 TensorFlow数据类型
其实,除了上面的基本类型以外,TensorFlow还支持量子化的整型,分别是8位的无符号quint8,8位有符号qint8,16位的无符号quint16,16位有符号qint16,还有32位有符号的qint32。
在TensorFlow中,基本上所有涉及数字类型的函数都可以指定类型。
*为常用的就是常量。TensorFlow 是一门静态计算图语言,与普通计算机高级语言一样,定义了常量、变量等常用编程结构。数字常数被TensorFlow使用之前,首先要赋值一个TensorFlow常量。例如:
>>> import tensorflow as tf
>>> a = tf.constant(1, dtype=tf.float64)
这样,a就是一个float64类型值为1的常量。常量也是张量的一种。
>>> a
这个常量是一个静态计算图,如果需要获取计算结果,需要建立一个会话来运行:
>>> sess = tf.Session()
>>> b = sess.run(a)
>>> print(b)
1.0
我们再来看复数的例子:
>>> c = 10 5.2j
>>> b = tf.constant(c)
将复数10 5.2j赋给c,再通过c创建一个常量。这个常量就是一个tf.complex128类型的常量。
>>> b
3.1.2 PyTorch的数据类型
PyTorch没有对应NumPy的复数类型,只支持整型和浮点型两种。种类也比TensorFlow要少一些,更加精练。PyTorch相当于带有GPU支持的NumPy,缺什么直接用NumPy即可,如图3.3所示。
PyTorch是动态计算图语言,不需要tf.constant之类的常量,数据计算之前赋给一个张量即可。建立Tensor是可以指定类型的。例如:
>>> import torch as t
>>> a1 = t.tensor(1, dtype=t.float32)
>>> a1
tensor(1.)
图3.3 PyTorch数据类型
除了通过指定dtype的方式,我们还可以通过直接创建相应的Tensor子类型的方式来创建Tensor。例如:
>>> a2 = t.FloatTensor(1)
>>> a2
tensor([ 0.])
具体类型对应关系如表3.1所示。
表3.1 PyTorch数据类型与张量子类型对应关系
数据类型
类型名称
类型别名
张量子类型
16位浮点数
half
float16
HalfTensor
32位浮点数
float
float32
FloatTensor
64位浮点数
double
float64
DoubleTensor
8位无符号整数
uint8
无
ByteTensor
8位带符号整数
int8
无
CharTensor
16位带符号整数
int16
short
ShortTensor
32位带符号整数
int32
int
IntTensor
64位带符号整数
int64
long
LongTensor
3.1.3 标量算术运算
标量虽然没有矩阵运算那么复杂,但它是承载算术和逻辑运算的载体。对于TensorFlow,标量算术运算还是需要先生成静态计算图,然后通过会话来运行。例如:
>>> a1 = tf.constant(1, dtype=tf.float64)
>>> a2 = tf.constant(2, dtype=tf.float64)
>>> a3 = a1 a2
>>> print(a3)
Tensor(“add:0”, shape=(), dtype=float64)
>>> sess.run(a3)
3.0
对于PyTorch来说,就是两个张量相加,结果还是一个张量,比TensorFlow要简单一些,也不需要会话。例如:
>>> b1 = t.tensor(3, dtype=t.float32)
>>> b2 = t.tensor(4, dtype=t.float32)
>>> b3 = b1 b2
>>> b3
tensor(7.)
除了加减乘除之外,不管是TensorFlow还是PyTorch,都提供了足以满足需求的数学函数。例如三角函数,TensorFlow版计算余弦值:
>>> a20 = tf.constant(0.5)
>>> a21 = tf.cos(a20)
>>> sess.run(a21)
0.87758255
PyTorch版计算余弦值:
>>> b20 = t.tensor(0.5)
>>> b21 = t.cos(b20)
>>> b21
tensor(0.8776)
在NumPy里,对于数据类型相对是比较宽容的,如sqrt、NumPy既支持整数,也支持浮点数:
>>> np.sqrt(20)
4.47213595499958
>>> np.sqrt(20.0)
4.47213595499958
而对于TensorFlow和PyTorch来说,sqrt只支持浮点数,用整数则会报错。TensorFlow版的报错信息,根本不用在会话中执行,创建计算图时就报错:
>>> a22 = tf.constant(20, dtype=tf.int32)
>>> a23 = tf.sqrt(a22)
Traceback (most recent call last):
File “”, line 1, in
…
TypeError: Value passed to parameter ‘x’ has DataType int32 not in list of allowed values: bfloat16, float16, float32, float64, complex64, complex128
PyTorch的报错相对简洁,直接声明,没有实现对于IntTensor类型的torch.sqrt函数:
>> b22 = t.tensor(10,dtype=t.int32)
>>> b23 = t.sqrt(b22)
Traceback (most recent call last):
File “”, line 1, in
RuntimeError: sqrt not implemented for ‘torch.IntTensor’
当然,不是每个函数都要求这么严格,例如,abs求绝对值函数,整数和浮点数都支持:
>>> a10 = tf.constant(10, dtype=tf.float32)
>>> a11 = tf.abs(a10)
>>> sess.run(a11)
10.0
>>> a12 = tf.constant(20, dtype=tf.int32)
>>> a13 = tf.abs(a12)
>>> sess.run(a13)
20
3.1.4 Tensor与NumPy类型的转换
不管TensorFlow还是PyTorch,都跟NumPy有很深的渊源,它们之间的转换也非常重要。
1.PyTorch与NumPy之间交换数据
PyTorch有统一的接口用于与NumPy交换数据。PyTorch的张量(Tensor)可以通过NumPy 函数来转换成NumPy的数组(ndarray)。例如:
>>> b10 = t.tensor(0.2, dtype=t.float64)
>>> c10 = b10.NumPy()
>>> c10
array(0.2)
>>> b10
tensor(0.2000, dtype=torch.float64)
作为逆运算,对于一个NumPy 的数组对象,可以通过torch.from_numpy 函数转换成PyTorch的张量。例如:
>>> c11 = np.array([[1,0],[0,1]])
>>> c11
array([[1, 0],
[0, 1]])
>>> b11 = t.from_NumPy(c11)
>>> b11
tensor([[ 1, 0],
[ 0, 1]])
2.TensorFlow与NumPy之间的数据交换
TensorFlow与NumPy就是构造计算图与执行计算图的过程。将NumPy的数组转成TensorFlow 的Tensor,可以通过tf.constant 来构造一个计算图。而作为逆运算的从TensorFlow的张量转换成NumPy的数组,可以通过创建一个新会话运行计算图。
示例1,从ndarray到Tensor:
>>> a11
array([[1, 0],
[0, 1]])
>>> c11 = tf.constant(a11)
>>> c11
示例2,从Tensor到ndarray:
>>> a11 = sess.run(c11)
>>> a11
array([[1, 0],
[0, 1]])
另外,TensorFlow还提供了一系列的转换函数。
例如,to_int32函数可以将一个Tensor的值转换为32位整数:
>>> a01 = tf.constant(0, tf.int32)
>>> a02 = tf.to_int32(a01)
>>> sess.run(a02)
0
类似的函数还有tf.to_int64、tf.to_float、tf.to_double等,基本上每个主要类型都有一个。定义这么多函数太麻烦,但还是有通用的转换函数tf.cast。格式为:tf.cast(Tensor, 类型名)。例如:
>>> b05 = tf.cast(b02, tf.complex128)
>>> sess.run(b05)
(1 0j)
3.TensorFlow的饱和数据转换
TensorFlow定义了这么多转换函数,有什么好处?答案是功能多。以TensorFlow还支持饱和转换为例,我们将大类型如int64转换成小类型int16,tf.cast转换过程中可能产生溢出,这在机器学习的计算中是件可怕的事情,而使用饱和转换,*多是变成小类型的**值,而不会变成负值。
例如,把65536转换成tf.int8类型。我们知道,int8只能表示-128到127之间的数。使用饱和转换tf.saturate_cast,只要是大于127的数值,转换出来就是127,不会更大。
例如:
>>> b06 = tf.constant(65536,dtype=tf.int64)
>>> sess.run(b06)
65536
>>> b07 = tf.saturate_cast(b06,tf.int8)
>>> sess.run(b07)
127
3.2 计算图与流程控制
计算图是一种特殊的有向无环图DAG,用来表示变量和操作之间的关系。它有点类似于流程图,但是比流程图多了对变量的描述。
既然与流程图类似,那么计算图其实相当于是一种计算机语言,需要有完备的计算机语言的功能。我们知道,一种结构化的计算机语言,除了顺序结构之外,还需要有分支结构和循环结构。下面,我们分别看下静态计算图及其代表TensorFlow与动态计算图及PyTorch如何实现计算图。
3.2.1 静态计算图与TensorFlow
静态计算图有点像编译型的语言,首先要写好完整的代码,然后再编译成机器指令并执行。会话中运行,相当于在TensorFlow机器上运行。
所以TensorFlow的静态计算图语言中,需要包括完整的指令集。因为不能借助宿主机,需要有条件分支指令、循环指令,甚至为了辅助开发,还需要一些调试指令。具体如图3.4所示。
图3.4 TensorFlow主要流程控制功能
1.比较运算
分支的**步是要有比较指令。*简单的指令当然是判断是否相等,TensorFlow提供了equal函数来实现此功能,例如:
>>> c1 = tf.constant(1)
>>> c2 = tf.constant(2)
>>> c3 = tf.equal(c1,c2)
>>> sess.run(c3)
False
结果返回False,说明c1和c2这两个张量不相等。
我们用判断不相等的not_equal函数来比较,结果就会为True,如下例:
>>> c4 = tf.not_equal(c1,c2)
>>> sess.run(c4)
True
如果比较大小,可以用小于less和大于greater两个函数,如下例:
>>> c5 = tf.less(c1,c2)
>>> sess.run(c5)
True
>>> c6 = tf.greater(c1,c2)
>>> sess.run(c6)
False
除了相等、不等、大于、小于之外,还有大于或等于操作greater_equal和小于或等于操作less_equal,我们看两个例子:
>>> c7 = tf.less_equal(c1,c2)
>>> sess.run(c7)
True
>>> c8 = tf.greater_equal(c1,c2)
>>> sess.run(c8)
False
另外,比较大小还可以批量进行,判断条件是一个布尔型的数组,后面是根据不同情况赋的值,这是where操作的功能。我们在后面学习向量之时再详细介绍。
2.逻辑运算
通过上面的6种比较运算,我们可以在TensorFlow的计算流程图中对比较运算的结果进行逻辑运算。
逻辑运算一共有以下4种:
? 与:logical_and;
? 或:logical_or;
? 非:logical_not;
? 异或:logical_xor。
我们举几个例子来介绍,首先是取非的例子:
>>> c9 = tf.logical_not(tf.greater_equal(c1,c2))
>>> sess.run(c9)
True
再用greater、equal和logical_or来实现greater_equal功能,代码如下:
>>> c11 = tf.constant(1)
>>> c12 = tf.constant(2)
>>> c13 = tf.logical_or(tf.greater(c11,c12), tf.equal(c11,c12))
>>> sess.run(c13)
False
例如,我们用数字来调用logical_xor,代码如下:
c10 = tf.logical_xor(1,2)
将报错如下:
TypeError: Expected bool, got 1 of type ‘int’ instead.
如果用两个整数类型的张量去进行逻辑运算,将报错如下:
ValueError: Tensor conversion requested dtype bool for Tensor with dtype int32: ‘Tensor(“Const:0”, shape=(), dtype=int32)’
习惯了C语言的弱类型的读者请特别注意以上情况。
3.流程控制——分支结构
有很多人在学到TensorFlow中还有流程控制操作时觉得很奇怪,这是对于静态计算图的理解还不够清楚的体现。再次强调一下,静态计算图就是一门程序设计语言,所以流程控制是非常重要的基本功能。
流程控制的基础是分支功能,就像Python中的if判断一样。在TensorFlow中,可以用case操作来实现。
我们一步步来展示case的功能。*简单的case语句只有一个判断条件和一个对应和函数。我们来看例子:
>>> d1 = tf.constant(1)
>>> d2 = tf.case([(tf.greater(d1,0), lambda : tf.constant(0))])
>>> sess.run(d2)
0
解释一下上述语句,如果d1大于0,执行后面的lambda函数,返回一个值为0的常量。
下面可以给case语句增加一个default分支:
>>> d3 = tf.case([(tf.greater(d1,0), lambda : tf.constant(0))], default=lambda : tf.constant(-1))
>>> sess.run(d3)
0
然后尝试加多个分支:
>>> d4 = tf.case([(tf.greater(d1,1), lambda : tf.constant(2)),(tf.equal(d1,1),lambda : tf.constant(1))], default=lambda : tf.constant(-1))
>>> sess.run(d4)
1
如果d1大于1,返回值为2的常量。如果d1等于1,则返回值为1的常量。
4.流程控制——循环结构
我们来看看循环结构,*常用的循环是for循环,对应TensorFlow的操作是while_loop操作。我们看个例子:
>>> e0 = tf.constant(1)
>>> e1 = tf.while_loop(lambda i : tf.less(i,10), lambda j : tf.add(j,1), [e0])
>>> sess.run(e1)
我们定义e0用作循环控制变量,while_loop操作*少需要3个参数,**个参数是结束循环的判断条件,第二个参数是循环体,第三个参数是循环控制变量。
所谓循环体,是需要循环多次操作的具体功能,在我们这个例子中,是一个给循环控制变量加1 的操作。
循环控制变量可以设计得很复杂,它会作为参数传给前面的**个和第二个callable参数。例如,**个参数,我们给的是一个lambda表达式,并没有指定要传的参数,形参的名称与实际传入的无关。循环控制变量参数获取之后,才会把这个参数传给lambda表达式去执行。
5.程序调试
当我们写了比较复杂的流程控制到静态计算图中,需要一些调试手段来测试逻辑是否正确。
*基础的功能是可以打印输出debug信息,这可以通过Print函数实现。例如:
>>> e2 = tf.Print(tf.constant(0),[‘Debug info’])
评论
还没有评论。