PyTorch深度学习实践
第1章 深度学习基础
1.1 人工智能、机器学习与深度学习
1.1.1 人工智能简介
人工智能:是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。
人工智能的目的:就是让计算机能够像人一样思考。
人工智能、机器学习与深度学习的关系如下图:
人工智能三种形态:
-
弱人工智能:单个方面的人工智能。目前,主流科研集中在弱人工智能上。并且一般认为这一研究领域已经取得可观的成就。
-
强人工智能:使机器学习人的理解、学习和执行任务的能力,不仅能真正推理和解决问题的智能机器,还具有知觉的或自我意识。
-
超人工智能:超越人类智慧并且将人类智慧延展的智能体系,各方面都可以比人类强。
1.1.2 机器学习简介
机器学习的广义概念:是指从已知数据中获得规律,并利用规律对未知数据进行预测的方法。
机器学习可用于:自然语言处理、图像识别、生物信息学以及风险预测等,已在工程学、经济学以及心理学等多个领域。
机器学习是一种统计学习方法,机器人和计算机等机器需要使用大量数据进行学习,从而提取出所需的信息。
机器学习的任务,就是要在基于大数据量的基础上,发掘其中蕴含并且有用的信息。
** 机器学习的分类**
机器学习主要分为有监督学习(也称监督学习)和无监督学习两种。
监督学习需要为机器提供一组标记数据。有监督学习通过训练,从标记数据中提取通用信息或特征信息, 以此得到预测模型。
监督学习的两种主要类型是分类和回归。
无监督学习两种主要类型是聚类和降维。
1.1.3 深度学习简介
深度学习定义:
就是一种利用深度人工神经网络来进行自动分类、预测和学习的技术。
深度学习的本质就是一个深层神经网络。深度学习的基本思想就是对堆叠多个层,将上一层的输出作为下一层的输入,逐步实现对输入信息的分级表达,让程序从中自动学习深入、抽象的特征。尤其值得注意的是“深度学习减少了人为干预,而这恰恰保留了数据客观性,因此可以提取出更加准确的特征”。深度学习的训练过程:
机器学习与深度学习流程对比
深度学习和传统机器学习在流程上的差异:深度学习算法可以从数据中学习更加复杂的特征表达,使得最后一步权重学习变得更加简单且有效。
深度学习发展历史
1.2 深度学习的三大核心要素
大数据
深度网络架构
所谓的深度网络架构,就是整个网络体系的构建方式和拓扑连接结构.
目前最常用的有4种:
- 全连接网络FC、
- 卷积神经网络CNN、
- 循环神经网络RNN
- 生成对抗网络GAN。
高性能的计算力
GPU
1.3 神经元与深度神经网络
神经元模型
人体的神经元包含树突、细胞核和轴突。
1.4 神经网络中常用的激励函数
如果每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合。
激活函数
激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
- Sigmoid 函数
- tanh 函数
- ReLU函数
- 指数线性单元 ELU函数
- Leaky ReLU 渗漏型整流线性单元激活函数
- Maxout 函数
1.5 深度学习的优势
- 不用再提取特征
- 处理线性不可分的能力强。
1.6 常见的深度学习框架
- PyTorch
2017年1月Facebook开源Torch库的Python版本(由Lua语言编写)。https://pytorch.org/ - TensorFlow
2015年9月谷歌大脑开源的深度学习框架
练习
第2章 深度学习框架PyTorch的安装
2.1 PyTorch 介绍
2.2 Windows下PyTorch 深度学习环境的配置
安装Python
pip安装torch
- 登录PyTorch官网安装
- 点击Get Started
3.复制命令到终端执行
1 | pip install torch==1.8.0+cpu torchvision==0.9.0+cpu torchaudio===0.8.0 -f https://download.pytorch.org/whl/torch_stable.html |
4.安装torchvision
pip3 install torchvision
2.3 Linux下PyTorch 深度学习环境的配置
同上
2.4 PyTorch开发工具
PyCharm不多说,或者Notebook
第3章 PyTorch基础
3.1张量是什么
PyTorch处理的最基本操作对象就是张量,张量的英文是Tensor,表示的是一个多维的矩阵。
零阶张量就是一个数,一阶张量就是向量,二阶张量就是一般的矩阵,多阶张量就相当于一个多维的数组。
张量的3个属性:
- 阶(rank):维数。
- 形状(shape): 行和列的数目。
- 类型(type): 元素的数据类型。
3.2 Tensor的创建
创建给定元素值的Tensor
【例3.1】假设要创建一个32位浮点数的Tensor,其值是矩阵[[-1,-2],[3,4],[5,6]],
1 | import torch |
【例3.2】查看的Tensor的尺寸,属性类型和元素数量,
1 | import torch as t |
【例3.3】可以在创建时给Tensor直接赋值,也可以先创建一个未赋值的Tensor。
1 | import torch as t |
【例3.4】创建一个和给定的Tensor形状一样的新Tensor
1 | import torch as t |
其他创建方法
1 | a = torch.zeros(2,3) #返回全零Tensor |
1 | #************随机初始化*********** |
3.3 Tensor的调整形状操作
【例3.5】创建一个一阶张量,长度为6,元素为[0,1,2,3,4,5],使用torch.view()函数将其调整为二阶张量2*3的Tensor。
1 | import torch as t |
【例3.6】改变形状的其他方法torch.resize_(), torch.reshape()。
1 | import torch as t |
3.4 Tensor的运算
【例3.7】 对 Tensor的加、减、乘、除、取绝对值操作。
3.5 Tensor的比较操作
Tensor常用的比较函数有很多,比如
- torch.equal( )、
- torch.eq( )、
- torch.gt( )、
- torch.lt( )、
- torch.ge( )、
- torch.le( )、
- torch.ne( )、
- torch.topk( )、
- torch.sort( )
等等,这里简单介绍几个。
torch.equal( )
若两个Tensor具有相同的形状和元素,则返回True,否则返回False。
torch.gt( )
逐元素比较input和other, 若input元素严格大于other元素,则返回True,否则返回False。
3.6 Tensor的数理统计操作
Tensor中的求最小值、最大值、均值、累加、累积等的操作比如:torch.min( )、torch.max( )、torch.mean( )等。
torch.max( )、torch.mean( )
3.7 Tensor与Numpy的互相转换操作
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。它提供了一个多维数组(ndarray)数据类型,以及关于多维数组的操作,NumPy 已经成为其他大数据和机器学习模块的基础。
Tensor类似于Numpy的ndarray,但ndarray 不支持GPU运算,而Tensor支持。
Tensor与Numpy可以方便的互相转换。
3.8 Tensor 的降维和增维操作
1 | #关于Tensor维度的操作有很多, |
3.9 Tensor 的裁剪操作
torch.clamp()对Tensor中的元素进行范围过滤,不符合条件的可以把它变换到范围内部(边界)上,常用于梯度裁剪(gradient clipping),即在发生梯度离散或者梯度爆炸时对梯度的处理。
torch.clamp(input,min,max ,out=None)
3.10 Tensor 的索引操作
Tensor支持与numpy.ndarray类似的索引操作,下面通过一些例子讲解常用的索引操作。如无特殊说明,索引出来的结果与原Tensor共享内存,即修改一个,另一个也会跟着改。
3.11 把Tensor 移到GPU上去
PyTorch提供了一个名为cuda( )的简单函数,将张量从CPU复制到GPU上。
自动求导
- autograd.grad()函数
- backward()函数
功能模块 数据集
在处理任何机器学习问题之前都需要数据读取,并进行预处理。
PyTorch 提供了很多工具使得数据的读取和预处理变得很容易。
想让PyTorch能读取我们自己的数据,首先要了解pytroch读取图片的机制和流程。
主要使用以下两个类:
1 | torch.utils.data.Dataset |
第一步:定义一个子类,继承Dataset类, 重写__len()__, __getitem()__ 方法。
第二步: 实例化一个对象,对数据集进行变换
第三步: 使用DataLoader进行包装,可视化等
功能模块 神经网络工具箱 nn.model
使用torch.nn包中的工具来构建神经网络,构建一个神经网络需要以下几步:
定义神经网络的权重,搭建网络结构
遍历整个数据集进行训练
- 将数据输入神经网络
- 计算loss 正向传播
- 计算网络权重的梯度 反向传播
- 更新网络权重weight = weight - learning_rate * gradient
在PyTorch里面编写神经网络,所有的层结构和损失函数都来自于torch.nn, 所有的模型构建都是从基类nn.Module 继承的,于是有了搭建结构的模板。
全连接示例:
卷积神经网络结构:
1 | import torch.nn as nn |
1 | criterion = nn. CrossEntropyLoss() |
功能模块 优化器torch.optim
在机器学习或者深度学习中,我们需要通过修改参数使得损失函数最小化(或最大化),优化算法就是一种调整模型参数更新的策略。
优化算法分为两大类:
- SGD
- ASGD
- Adadelta
- Adagrad
- Adam
- AdamW
- Adamax
- SparseAdam
- RMSprop
- Rprop
- LBFGS
- optimizer. zeros() #需要先将梯度归零
- loss . backward()#反向传播,自动求导得到每个参数的梯度,
- optimizer . step()#最后就可以通过梯度做-一步参数更新。
计算机视觉工具包:torchvision
主要包含以下三部分:
- models:提供深度学习中各种经典网络结构及预训练好的模型,包括AlexNet、VGG系列、ResNet系列、Inception系列等。
- datasets:提供常用的数据集下载,设计上都是继承torch.utils.data.Dataset,主要包括MNIST、CIFAR10/100、ImageNet、COCO等。
- transform:提供常用的数据预处理操作,主要包括对Tensor及PIL Image对象的操作。transforms中涵盖了大部分对Tensor和PIL Image的常用处理。
对PIL Image的操作包括:
(1)Scale:调整图片尺寸,长宽比保持不变。
(2)CenterCrop、RandomCrop: 裁剪图片。
(3)Pad:填充。
(4)ToTensor:将PIL Image对象转成Tensor,会自动将[0, 255] 归一化至[0, 1]。
对Tensor的操作包括:
(1)Normalize:标准化(减均值,除以标准差)。
(2)ToPILImage:将Tensor转为PIL Image对象。
第4章 线性回归和逻辑回归
4.1 正向学习过程
- 样本由输入层传入第一层layer,经第一层每个节点计算,每个节点得到一个输出,其输出继续作为下一层的输入,向前传播,直到输出层输出预测的结果。
- 初次正向传播会先初始化网络的权值,得到的输出值并不一定正确值。
4.2 反向调整过程
梯度
梯度下降法:
梯度下降法是最常用的神经网络优化算法。
若将代价函数简单可视化,代价函数相当于一个崎岖不平的盆地,有高峰也有低谷(最小值)。梯度下降的目标是取得最小值,每次沿着最陡峭的方向(梯度反方向),下降一定的距离(步长)。
梯度下降的步长不是一直不变的,当下降接近底部的时候,需要调整步子的大小,小心试探。当步子太大时,容易跨过最低点,在底部来回震荡。步子过小,下降速度会较慢。
在梯度下降过程中,节点i和j之间连接的权重$$W_{ji}$$的更新如下:其中η为学习速率,用于控制步长的变化。
在梯度下降法调优中,影响较大的三个因素为步长、初始值和归一化。
- 步长:又称学习率,决定了梯度下降迭代过程中每一步沿梯度负方向前进的长度。也就是上述所说的沿最陡峭的位置走的那一步的长度。
- 初始值:随机选取的值,当损失函数是非凸函数时,找到的可能是局部最优解,此时需要多测试几次,从局部最优解中找出最优解。当损失函数是凸函数时,得到的解就是最优解。
- 归一化:若不进行归一化,会导致收敛速度很慢,从而形成“之”字形的路线。
反向传播的问题
- 梯度消失:由于sigmod函数在趋于无限大时,梯度会逐渐消失,随着传播深度的增加(如7层以上),残差传播到底层时已经变得太小,梯度的幅度也会急剧减小,导致浅层神经元的权重更新非常缓慢,无法有效进行学习。深层模型也就变成了前几层几乎固定,只能调节后几层的浅层模型,形成梯度弥散(vanishing gradient)。
- 局部最优:深层模型的每个神经元都是非线性变换,代价函数是高度非凸函数,与浅层模型的目标函数不同。所以采用梯度下降的方法容易陷入局部最优。
优化算法的改进
- 激活函数选择
- 梯度剪切、正则
- Batch Normalization
- 残差结构
4.3 线性回归实现
一元线性回归
本节主要实现基于pytorch的线性回归实现:torch.nn.Linear( )
1 | def __init__(self, in_features: int, out_features: int, bias: bool = True) -> None: |
迭代的次数为200次。模型训练最终Loss到0.27(200)
model.eval()表示,只进行预测,不进行参数更新
多元线性回归
原始函数:$$𝑦=4𝑥3+3𝑥2+2𝑥+1$$
假设拟合函数:$$𝑦=𝑤_3 𝑥^3+𝑤_2 𝑥^2+𝑤_1 𝑥+𝑏$$
迭代的终止条件los<1e-3。模型训练大约100batch。
4.4 逻辑回归实现
逻辑回归是一种广义的回归模型,其与线性回归有着很多相似之处,模型的形式基本相同,都是 y = xw + b。
逻辑回归的损失函数-Cross Entropy Loss
第5章 全连接神经网络
理论和定理
在机器学习中,有一些非常有名的理论或定理,对理解深度学习的内在特性非常有帮助.
PAC 学习理论:可能近似正确( Probably Approximately Correct , PAC )学习理论
没有免费午餐定理:“具体问题具体分析”
奥卡姆剃刀原理:: “如无必要,勿增实体”
丑小鸭定理:特征筛选标准的重要性
归纳偏置(贝叶斯称为先验prior):对问题的假设
5.1 全连接神经网络(FC)
全连接神经网络的准则很简单:神经网络中除输入层之外的每个节点都和上一层的所有节点有连接。
5.2多分类问题
5.3 softmax与交叉熵
softmax函数,又称归一化指数函数。
它是二分类函数Sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。
交叉熵是用来衡量两个概率分布的距离(也可以叫差别)。
交叉熵数值越小说明两个概率分布越接近。
概率分布:即[0.1,0.5,0.2,0.1,0.1],每个类别的概率都在0-1,且加起来为1。
若有两个概率分布p(x)和q(x),它们的交叉熵为:
假设有一个三分类的问题,某样本的真实分类标签是p=(1,0,0),
某个模型经过Softmax函数之后预测结果,若
q=(0.5,0.4, 0.1),那么它们的交叉熵为
H(p,q) =-(1*log0.5+0*log0.4+0*log0.1)~0.3
q=(0.8,0.1, 0.1),那么它们的交叉熵为
H(p,q) =-(1*log0.8+0*log0.1+0*log0.1)~0.1
由于后者更小,所以第二个模型参数性能更好
5.4 计算机视觉工具包:torchvision
torchvision主要包含以下三部分:
models:提供深度学习中各种经典网络结构及预训练好的模型,包括AlexNet、VGG系列、ResNet系列、Inception系列等。
**datasets:**提供常用的数据集下载,设计上都是继承torch.utils.data.Dataset,主要包括MNIST、CIFAR10/100、ImageNet、COCO等。
**transform:**提供常用的数据预处理操作,主要包括对Tensor及PIL Image对象的操作。
transforms中涵盖了大部分对Tensor和PIL Image的常用处理。
对PIL Image的操作包括:
(1)Scale:调整图片尺寸,长宽比保持不变。
(2)CenterCrop、RandomCrop、RandomResizedCrop: 裁剪图片。
(3)Pad:填充。
(4)ToTensor:将PIL Image对象转成Tensor,会自动将[0, 255]归一化至[0, 1]。
对Tensor的操作包括:
(1)Normalize:标准化(减均值,除以标准差)。
(2)ToPILImage:将Tensor转为PIL Image对象。
torchvision还提供了两个常用的函数。
make_gri(),它能将多张图片拼接成一个网格中。
save_img(),它能将Tensor保存成图片。
5.5 用全连接神经网络实现多分类
简易神经网络搭建
我们从最简单的网络建起,
然后建立一个加入激励函数的网络,
最后建立一个加入批标准化函数的网络。
批标准化函数
BN的作用:
(1)加快训练速度,减少了对学习率的要求,可以使用很大的学习率或者较小的学习率,算法也能够快速训练。
(2)增加模型的稳定性,有效减少梯度消失/爆炸,提高训练精度。
(3)BN具有轻微的正则化效果,在某些情况下可以取消 dropout 和 L2 正则项参数,或者采取更小的 L2 正则项约束参数。
(4)减少了人为选择参数的过程(权重的初始化方式,正则化方式的超参数的选择,学习率等)。
BN的缺陷:
(1)无法使用小batch进行训练,小batch的均值和方差可能与整体训练样本偏差很大。
(2)无法在RNN等网络中使用。
全连接识别MNIST手写数字
MNIST数据集是一个非常出名的数据集,基本上很多网络都将其作为一个测试的标准,其来自美国国家标准与技术研究所,National Institute of Standards and Technology (NIST)。训练集(training set) 由来自250个不同人手写的数字构成,其中50% 是高中学生,50% 来自人口普查局 (the Census Bureau)的工作人员,一共有 60000 张图片。 测试集(testing set)也是同样比例的手写数字数据,一共有10000张图片。图5.11就是数据集中的一些数字图片。
第一步:导入要用的包、定义超参数,比如训练中每批多少图片(batch_size),学习率(learning_rate),迭代次数num epoches。
第二步:下载MNIST数据集,同时对数据进行标准化预处理。
第三步:定义带有激活函数和批标准化的网络。
第四步:导入网络、定义损失函数和优化方法。
第五步:训练网络模型,
第六步:测试网络
训练误差和泛化误差:模型应关注降低泛化误差
- 模型在训练数据集上表现出的误差叫做训练误差
- 在任意一个测试数据样本上表现出的误差的期望值叫做泛化误差
- 欠拟合:模型⽆法得到较低的训练误差。
- 过拟合:模型的训练误差远小于它在测试数据集上的误差。
防止过拟合的方法:
- 更多数据more data
- 数据扩充 data argumentation
- 降低模型复杂度:正则化regularization,浅层shallow
- Dropout
- 早停技术early stopping
Dropout
如何使用Dropout?在训练DNN网络的过程中,对于每一个神经元,以p的概率被随机的drop out,也就是将其值置零。这样,在该轮前传和反传的过程中,该神经元将失去作用,相当于不存在,如下图所示。
early stop
原理
- 将数据分为训练集和验证集
- 每个epoch结束后(或每N个epoch后): 在验证集上获取测试结果,随着epoch的增加,如果在验证集上发现测试误差上升,则停止训练;
- 将停止之后的权重作为网络的最终参数。
第6章 卷积神经网络
6.1深度前馈网络
在前馈神经网络中,各神经元分别属于不同的层。每一层的神经元可以接受到前一层的神经元信号,并产生信号输出到下一层。
对于具有线性输出层和至少一个使用“挤压”性质的激活函数的隐藏层组成的前馈神经网络,只要其隐藏层神经元的数量足够,它可以以任意精度来近似任何从一个定义在实数空间中的有界闭集函数。
6.2 全连接网络和卷积神经网络
整个网络中无反馈,信号从输入层向输出层单向传播,可用一个有向无环图表示。
[3,4,4,1]
参数量=3x4+4x4+4x1=32
用全连接前馈网络来处理图像时,会存在两个问题:
- 权重矩阵的参数非常多
- 局部不变性特征不易提取
6.3卷积神经网络原理
卷积神经网络( Convolutional Neural Network , CNN 或 ConvNet )
- 卷积神经网络最早主要用来处理图像信息.
- 包含卷积计算且具有深度结构的前馈神经网络
- 具有特征学习能力,能够按其阶层结构对输入信息进行平移不变分类。
- 一种具有局部连接、权重共享等特性的深层前馈神经网络.
CNN主要应用:计算机视觉,图像和视频分析的各种任务上。近年来,卷积神经网络也应用到自然语言处理和推荐系统等领域。
生物学上感受野 Receptive Field
在神经网络中,感受野的定义是:
卷积神经网络的每一层输出的特征图(Feature map)上的像素点在原图像上映射的区域大小。
卷积神经网络的三个思想根源如下:
- 局部性
- 相同性
- 不变性
一维卷积
二维卷积
互相关运算
虽然卷积层得名于卷积(convolution)运算,但我们通常在卷积层中使用更加直观的互相关(cross-correlation)运算。在二维卷积层中,一个二维输⼊数组和⼀个二维核(kernel)数组通过互相关运算输出⼀个二维数组。
卷积种类
在卷积的标准定义基础上,还可以引入卷积核的滑动步长S和零填充P来增加卷积的多样性,可以更灵活地进行特征抽取。
小结
6.4 典型的卷积神经网络
卷积神经网络一般由卷积层、汇聚层和全连接层构成。
用卷积来代替全连接
卷积层
- 卷积层的每个神经元只与输入数据的一个局部区域连接,因此过滤器(卷积核)提取到的是图像的局部特征。
- 卷积层的作用是提取局部区域的特征,不同的卷积核相当于不同的特征提取器.
- 通常将神经元组织为三维结构的神经层,其大小为高度 M× 宽度 N× 深度 D ,由 D 个 M × N 大小的特征映射构成.
- 特征映射( Feature Map )为一幅图像(一组特征映射)在经过卷积提取到的特征,每个特征映射可以作为一类抽取的图像特征.
如果是灰度图像,就是有一个特征映射,输入层的深度 D = 1 ;
如果是彩色图像,分别有 RGB 三个颜色通道的特征映D=3.
感受野计算
卷积层实现
在卷积层中要设定的参数:
1.滤波器(卷积核)的长,宽,深度
2.步长
3.边界填充
torch.nn.Conv2d()函数
池化层
- 最大池化(max-pooling)
- 平均池化(mean-pooling)
池化层的作用有:
- 特征降维,避免过拟合
- 空间不变性
- 减少参数,降低训练难度。
第二部分 经典的卷积神经网络
6.5 经典CNN-LeNet5
LeNet神经网络由深度学习三巨头之一的Yan LeCun在1998年提出,他同时也是卷积神经网络 (CNN,Convolutional Neural Networks)之父。LeNet的实现确立了CNN的结构,自那时起,CNN的最基本的架构就定下来了:卷积层、池化层、全连接层。
LenNet-5共有7层(不包括输入层),每层都包含不同数量的训练参数。
主要有2个卷积层、2个下抽样层(池化层)、3个全连接层3种连接方式。
6.6 经典CNN- VGGNet
VGGNet特点
- 小卷积核。卷积核全部替换为3x3(极少用了1x1);
- 小池化核。相比AlexNet的3x3的池化核,VGG全部为2x2的池化核;
- 层数更深特征图更宽。基于前两点外,由于卷积核专注于扩大通道数、池化专注于缩小宽和高,使得模型架构上更深更宽的同时,计算量的增加放缓;
- 全连接转卷积。网络测试阶段将训练阶段的三个全连接替换为三个卷积,测试重用训练时的参数,使得测试得到的全卷积网络因为没有全连接的限制,因而可以接收任意宽或高度的输入
- VGG耗费更多计算资源
实验表明 当层数达到一定数量比如20层左右以上,性能反而下降,小于这个层数会呈增长趋势
6.7 经典CNN-ResNet
小结
- 卷积的原理:卷积运算和互相关运算
- 典型卷积神经网络:卷积层,池化层,全连接层
- 经典卷积神经网络:LeNet,VGG,ResNet
- 常用数据集:MNIST CIFAR10/100 ImageNet