深度学习入门
1 深度学习基础
人工智能包含机器学习,而机器学习又包含深度学习
-
人工智能是指拥有人的智能,能做出与人类智能相似反应的智能机器
-
机器学习可以被定义为从数据中总结经验,找出某种规律或者模型,利用这些经验、规律或者模型来解决实际问题。
-
深度学习是机器学习的一个分支。源于对人工神经网络(ANN)的研究,其动机在于建立、模拟人脑进行分析学习的神经网络,模仿人脑的机制来解释图像、声音和文本等数据。
为什么以神经网络为核心的深度学习直到近几年才得到如此迅速的发展呢?
-
大数据的涌现。机器学习一样,深度学习也是基于数据的学习,数据量越大,训练的模型就越准确。
-
计算机硬件水平提高。
-
算法的改进。
2 PyTorch
2.1 PyTorch概述
PyTorch可以拆分成两部分:Py和Torch。Py就是Python,Torch是一个有大量机器学习算法支持的科学计算框架。可以把PyTorch看成是支持GPU运算的Numpy,且可以用来搭建和训练深度神经网络。
torch就是PyTorch的核心库,torchvision包是服务于PyTorch深度学习框架的,用来生成图片、视频数据集、一些流行的模型类和预训练模型。
2.2 张量
张量(tensor)是PyTorch里基础的运算单位,即多维数组。类似Numpy的数组,但是张量可以在GPU上运算。
PyTorch中的张量与NumPy数组可以互相转化,而且两者共享内存位置,如果一个发生改变,另一个也随之改变。
新建的张量默认保存在CPU里,如果安装了GPU版本的PyTorch,就可以将张量移动到GPU里。
反向传播求导数,自动求导(autograd)模块可以为张量自动提供微分,tensor.requires_grad=True
2.3 torch.nn和torch.optim
PyTorch中,训练神经网络离不开两个重要的包:torch.nn和torch.optim。
-
torch.nn是专门为神经网络设计的模块化接口,构建于自动求导模块的基础上,可用来定义和运行神经网络。
-
torch.optim是一个实现了各种优化算法的库,包括最简单的梯度下降(Gradient Descent,GD)、随机梯度下降(Stochastic Gradient Descent,SGD)及其他更复杂的优化算法。
损失函数用于计算每个实例的输出与真实样本的标签是否一致,并评估差距的大小。最简单的是均方误差nn.MSELoss()
。
2.4 线性回归
线性回归一般用于数值预测,线性回归算法就是要找出这样一条拟合线或拟合面,能够最大限度地拟合真实的数据分布。
代价函数是所有样本损失函数的平均。代价函数与损失函数的唯一区别,前者针对整个训练集,后者针对单个样本。
如何最小化代价函数J呢?最简单的方法就是使用梯度下降算法,其核心思想是在函数曲线上的某一点,函数沿梯度方向具有最大的变化率,那么沿着负梯度方向移动会不断逼近最小值,这样一个迭代的过程可以最终实现代价函数的最小化目标。
通过model.eval()函数将模型由训练模式变为测试模式
.detach()用于停止对张量的梯度跟踪
3 TensorFlow
3.1 TensorFlow概述
TensorFlow也可以拆分成两部分:Tensor+Flow。Tensor即张量,可以在GPU中运行的多维数组;Flow是流,TensorFlow是一个采用数据流图进行数值计算的开源软件库。
TensorFlow的基本原理是基于图运算,而且可以将一个计算图划分成多个子图,然后在多个CPU或者GPU上并行地执行。
可移植性、可视化(TensorBoard)
如果安装GPU版本的TensorFlow,计算机中需要有一块NVIDIA的GPU显卡并安装了显卡驱动。在安装TensorFlow之前,需要提前安装CUDA和CUDNN。
3.2 张量
TensorFlow中,张量的数学运算和普通计算是不同的,保存的是计算过程而非计算结果,需要在会话中计算结果。
3.3 数据流图
TensorFlow是一个采用数据流图进行数值计算的深度学习框架
使用tf.constant()创建的张量都是常量,一旦创建后其中的值就不能改变了
tf.Variable创建变量
3.4 会话
init = tf.global_variables_initializer() # 定义全局初始化节点
with tf.Session() as sess:
init.run() # 初始化所有变量
result = f.eval()
一个TensorFlow程序通常可以分成两部分:第一部分用来构建一个数据流图,称为构建阶段;第二部分用来执行这个图,称为执行阶段。
从外部传入数据,例如训练集,那就需要使用TensorFlow中的占位符来表示,写成tf.placeholder()。
3.5 线性回归
均方误差(Mean Squared Error, MSE)均方误差是各数据偏离真实值的距离平方和的平均数,也即误差平方和的平均数。
均方误差(MSE)定义为其损失函数,使用tf.reduce_mean()来计算均方误差
loss = tf.reduce_mean(tf.square(y_hat - y))
3.6 TensorBoard
TensorBoard是TensorFlow的可视化工具,它可以通过TensorFlow程序运行过程中输出的日志文件对TensorFlow程序的运行状态进行可视化。
通过TensorBoard,我们可以查看模型的数据流图、损失函数随迭代次数的变化等。
4 神经网络基础知识
4.1 感知机
感知机是一种最简单的线性二分类模型,是神经网络的基础。
神经元计算所有输入信号的加权和之后,与固定偏置参数b做比较。当输入信号的加权和大于这个阈值时,神经元通路打开,输出为1,否则输出为0。
将偏置b移到不等式左边。因为b是常数,变换正负号对最终得到的值并无影响。
4.2 多层感知机
对于稍微复杂一点的逻辑电路,线性感知机是无法处理的,此时就需要使用多层感知机。
感知机无法处理异或问题,无法在二维平面上找到一条直线进行完全正确的分类
异或门可以由与门和或门搭建
两层感知机可实现对非线性异或逻辑的划分,得到的分类线不再是一条直线,而是一条曲线
通过叠加感知机能够进行非线性的表示,神经网络就是由多层感知机发展并优化而来的
4.3 逻辑回归
感知机是神经网络的基础,多层感知机MLP与神经网络非常相似。
阶跃函数(大于0为正,小于0为负)有个缺点,既在s=0处是不可导的,无法计算梯度,也就无法使用梯度下降算法来确定模型参数wi和b。
使用Sigmoid函数代替阶跃函数,不仅让函数连续,可利用梯度下降算法,而且引入了概率来表示预测为正类的把握有多大。
最大化问题转换为最小化问题。最终的目标,即最小化-log(P(y|x))。通常把-log(P(y|x))称为损失函数
交叉熵损失,实际反映了真实标签y与预测值之间的差距
代价函数:所有损失函数的均值
逻辑回归的目标就是最小化代价函数J,并计算出此时对应的模型参数w和b。
梯度下降,下山的方向就是梯度的负方向。梯度就是某一个函数在该点处的方向导数沿着该方向取得的最大值,即函数在当前位置的导数。
5 神经网络
神经网络是多层感知机MLP与逻辑回归结合和优化的模型,MLP用于拟合函数,逻辑回归用于更新权重。
5.1 基本结构
之所以称之为两层神经网络,是因为一般不把输入层考虑在内。
神经元是一个非线性单元,它的结构类似于一个逻辑回归模型,由线性单元和非线性单元组成。
z=w1x1+w2x2+b表示线性运算,a=g(z)表示非线性运算。
5.2 前向传播
前向传播过程,即神经网络从输入层到输出层的计算过程。
5.3 激活函数
神经元包含了非线性计算,用g(•)来表示
单个神经元实现的功能就相当于逻辑回归。
ReLU(Rectified Linear Unit,修正线性单元),z>0时梯度恒为1
Leaky ReLU函数与ReLU函数的区别仅在于当z≤0时,a不恒为0,而是有一个较小的梯度,此处为0.01,不唯一。这样做的好处是始终保持梯度不为0。
对于隐藏层的激活函数,一般来说,tanh函数要比Sigmoid函数的表现更好一些
而对于输出层的激活函数,因为二分类问题的输出取值为{0, 1},所以一般会选择Sigmoid作为激活函数。就是当激活值|z|很大的时候,激活函数的斜率(梯度)很小
在隐藏层,选择ReLU作为激活函数能够保证z>0时梯度始终为1,从而提高神经网络梯度下降算法的运算速度。存在梯度为0的缺点,实际应用中,这个缺点的影响不是很大。
如果所有隐藏层都使用线性激活函数,只有输出层使用非线性激活函数,那么整个神经网络的结构就类似于一个简单的逻辑回归模型,相当于只使用一个神经元。
5.4 反向传播
神经网络经过前向传播之后,接下来就可以计算其损失函数。反向传播是对神经网络输出层、隐藏层的参数W和b计算偏导数的过程。
点乘要求参与运算的两个量两必须是维数相同,是对应元素的相乘。
矩阵相乘要求内维相同,也即前一个矩阵的列的维数等于后一个矩阵的行的维数。
5.5 更新参数
神经网络完成反向传播之后,得到了各层的参数梯度dW和db。需要根据梯度下降算法对参数W和b进行更新。
经过前向传播、反向传播、更新参数之后,神经网络的一次训练就完成了。经过N次迭代训练,参数W和b会不断更新,并接近全局最优解。
5.6 初始化
神经网络中的参数W不能初始化为0,b可以。
隐藏层3个神经元完全对称,效果相同。这样的话,隐藏层设置多个神经元就没有任何意义了
神经网络的权重系数W一般不会初始化为零,可以进行随机初始化。但是,偏置项系数b一般可以初始化为零,并不会影响神经网络的训练效果
6 深层神经网络
与逻辑回归相比,神经网络可以实现非线性分类,效果非常好。
6.1 深层神经网络的优势
即便是单隐藏层神经网络,只要隐藏层有足够多的神经元,神经网络的宽度足够大,那么该神经网络复杂度就高,就能拟合任意复杂的函数
并不是神经网络越宽越好,神经网络的强大能力主要由于神经网络足够“深”
神经网络的输入是一张图片,从计算机的角度来看,即一个个像素值。第一层主要从原始图片中提取一些边缘信息。第二层将前一层得到的边缘信息进行整合,提取面部的一些局部特征。
实际应用中,我们还是要尽量选择层数较少的神经网络,这样能够有效避免发生过拟合
6.2 符号标记
假设神经网络是L层。这里的L为隐藏层和输出层的层数之和,即隐藏层为L-1层。
Z[l]表示该层线性输出,A[l]表示该层非线性输出
6.3 前向传播与反向传播
输出层L中dA[L]的计算公式由交叉熵损失得到
6.4 多分类函数Softmax
二分类模型的输出层只有一个神经元,而多分类模型的输出层有多个神经元。
二分类使用Sigmoid函数,将Z[L]映射到预测概率上。
Softmax就是处理多分类问题的函数。Softmax函数的功能是将Z[L]映射到区间[0,1],将其看成概率。各神经元输出概率之和为1
6.5 深层神经网络的Python实现
在浅层神经网络中,隐藏层的激活函数选择tanh函数,但如果是深层神经网络,隐藏层的激活函数一般选择ReLU函数。
使用tanh函数,当|Z|很大的时候,激活函数的斜率(梯度)很小。因此,在这个区域内,梯度下降算法会运行得比较慢。而ReLU激活函数在Z>0时梯度始终为1,从而提高梯度下降算法的运算速度。
参数初始化,权重W随机;前向传播,z=g(Wx+b),在输出层计算损失;反向传播,对损失loss分别求w和b的偏导,一次性得到所有的梯度,使用梯度下降的思想更新权重W=W-lr*dW
7 优化神经网络
7.1 正则化
欠拟合、适拟合和过拟合
虽然预测值与样本实际值完全吻合,但是该模型在训练样本之外的数据上拟合的效果可能很差,该模型很可能把噪声也学习了,这种情况称为过拟合
欠拟合和过拟合分别对应高偏差和高方差
偏差度量了算法的期望预测与真实结果的偏离程度;方差度量了训练集的变化导致学习性能的变化,描述了数据扰动造成的影响;噪声则表示任何学习算法的泛化能力的下界
误差 = 偏差 + 方差 + 噪声
验证集用来验证不同算法的表现情况,以便从中选择最好的算法模型。
为了避免发生过拟合,通常需要采取一些方法提高模型的泛化能力。
正则化就是指在代价函数后加上一个正则化项,正则化项也叫惩罚项。
L2正则化就是在代价函数后面加上神经网络各层的权重参数W所有元素的二次方和。
一般只对权重参数W进行正则化而不对偏置参数b进行正则化,原因是一般W的维度很大,而b只是一个常数。
神经网络模型之所以发生过拟合,是因为参数W普遍比较大。
L1正则化就是在代价函数后面加上神经网络各层的权重参数W所有元素的绝对值之和。
对于L2正则化来说,限定区域是圆,得到的解w1或w2为0的概率很小,很大概率是非零的;对于L1正则化来说,限定区域是正方形。
Dropout正则化,顾名思义,是指在深层神经网络的训练过程中,按照一定的概率将每层的神经元暂时从神经网络中丢弃。
7.2 梯度优化
批量梯度下降(Batch Gradient Descent,BGD)
批量是指整个训练集里包含的所有样本。
随机梯度下降(Stochastic Gradient Descent,SGD)
小批量梯度下降(Mini-Batch Gradient Descent,MBGD)
每次epoch训练之前,最好随机打乱所有训练样本
从性能上来说,小批量梯度下降不比批量梯度下降差,而且小批量梯度下降的运算速度更快一些。小批量梯度下降结合了批量梯度下降和随机梯度下降的优点。
Adam实际上是把动量梯度下降和RMSprop结合起来的一种算法。
梯度下降算法中的学习率α决定了梯度下降每次更新参数的尺度大小,俗称步进长度。
8 卷积神经网络
8.1 为什么选择卷积神经网络
传统神经网络结构存在以下两个缺点。
-
输入层维度过大;
-
不符合图像特征提取的机制。
拉伸成一维特征,作为神经网络的输入层,将图片的各个像素点独立开来,忽略了各个像素点之间的区域性联系。
8.2 卷积神经网络的基本结构
卷积神经网络最基本的结构有三种,分别是卷积层、池化层、全连接层。
8.3 卷积层
卷积层(convolutional layer),顾名思义,它实现的是对图片的卷积操作。
卷积运算的具体操作步骤为:已知原图像和模板图像,首先,将模板图像在原图像中移动;然后,每到一个位置,将原图像与模板图像定义域相交的元素进行乘积且求和,得出新的图像点;最后,遍历原图像所有像素点,得到卷积后的图像,整个卷积运算完成。这里的模板图像又称卷积核。
点积(dot product),也叫点乘。 点积的代数定义:对应元素相乘再求和,结果是一个数
边缘检测(edge detection)是图像处理中最常用的算法之一,其目的是检测图片中包含的边缘信息
为了解决图片缩小的问题,可以使用填充的方法,即对原始图片的尺寸进行扩展,扩展区域补零
填充之后,原始图片尺寸扩展为(n+2p)×(n+2p),卷积核尺寸为f×f,则卷积运算后的图片尺寸为(n+2p-f+1)×(n+2p-f+1)。
步幅表示卷积核在原图片中每次移动的步长。
二维平面卷积,针对的是单通道图片。三维卷积运算的基本原理与二维卷积相同,只是增加了一个维度。三维卷积运算需要使用3个卷积核
1层卷积层提取的是人脸的边缘、线条、轮廓等浅层特征;第2层卷积层提取的是人脸的一些器官,如眼镜、鼻子、耳朵等;第3层卷积层提取的是人脸的整体面部轮廓
卷积神经网络不同的卷积层会根据网络深浅提取不同层次的特征
8.4 池化层
在卷积神经网络中用于减小尺寸,提高运算速度,也能减小噪声的影响,让各特征更具有健壮性。
最大池化的做法就是选择一个类似于卷积核的滤波器算子,在上一层输出矩阵上滑动;然后,每到一个位置,计算两者定义域相交元素的最大值,作为新的图像点;最后,遍历原图片所有像素点,得到最大池化之后的图片。
最大池化有两个参数需要注意:一个是滤波器算子(滑动窗)的尺寸f,另外一个是滤波器算子每次移动的步幅s。
平均池化就是在滤波器算子滑动区域计算平均值,优点是顾及每一个像素。
实际应用中,最大池化比平均池化更常用一些。
8.5 全连接层
全连接层实际上就是传统的前馈神经元网络结构,一般出现在卷积神经网络的末端,输出层之前。
单个神经元(二分类)用sigmoid,多个神经元(多分类)用softmax,输出的是预测的概率值。
卷积层类比眼睛,提取局部特征,全连接层类比大脑,把之前按所有的局部特征重新通过权值矩阵组装成完整的图。
卷积神经网络的强大之处其实就在于其卷积层强大的特征提取能力
8.6 卷积神经网络模型
在卷积层CONV1中,使用的卷积核尺寸f=5,卷积核的个数为6个,步幅s=1,则该层输出的尺寸为32-5+1=28,维度为28×28×6。包含的参数个数为(5×5×3+1)×6=456,因为每个卷积核有5×5×3=75个参数,还有1个偏置参数,6个卷积核。
在池化层POOL1中,使用的滤波器算子尺寸f=2,滤波器算子个数为6个,步幅s=2,则该层输出的尺寸为28÷2=14,维度为14×14×6。包含的参数为0,因为池化层没有参数。
8.7 典型的卷积神经网络模型
- LeNet-5
卷积层→池化层→卷积层→池化层→全连接层→全连接层→输出层
- AlexNet
由5个卷积层和3个全连接层组成
卷积层→池化层→卷积层→池化层→卷积层→卷积层→卷积层→池化层→全连接层→全连接层→输出层
9 循环神经网络
循环神经网络是一类以序列数据为输入,在序列的演进方向进行递归且所有节点(循环单元)按链式连接的递归神经网络。
9.1 为什么选择循环神经网络
使用传统的前馈神经网络解决序列信号问题存在两个困难:
-
不同样本的输入序列长度或输出序列长度可能不同,即无法确定两句话包含的单词数目一样,这就造成模型难以统一
-
无法共享序列不同x<t>之间的特征。如“张三”表示人名,那么句子其他位置出现的“张三”很可能也是人名
9.2 循环神经网络的基本结构
输入序列中的每个元素x<t>都是一维向量。最常用的方法就是使用独热编码进行处理。每个单词就由维度为10001×的向量组成。该向量对应词汇表顺序,相应单词对应位置数值为1,其他位置数值全为0。每个单词经过独热编码之后,就成了一维向量,向量长度与单词表的长度相同。
模型中的a<t>是记忆单元,是当前层的输出,同时也作为下一层的输入
9.3 模型参数
循环神经网络模型包含三类权重系数,分别是\(W_{ax}\)、\(W_{aa}\)、\(W_{ya}\),同时包含两类偏置系数,分别是\(b_a\)、\(b_y\)
不同元素在同一位置共享权重系数和偏置系数,这样做的目的是让模型参数与序列信号长度无关。
如果是分类问题,则一般使用交叉熵损失;如果是回归问题,则一般使用均方误差。
9.4 梯度消失
序列信号可能存在跨度很大的依赖关系,某个单词可能与它距离较远。由于跨度很大,普通的循环神经网络容易出现梯度消失,因此很难捕捉到它们之间的依赖,容易造成语法错误。
9.5 GRU
GRU(Gated Recurrent Unit),解决梯度消失问题。
\(Г_u\)和\(Г_r\)都是门控单元,取值范围为[0,1]。\(Г_u\)=0时,代表记忆值越小,代表“记住”得越明显。
•表示矩阵相乘,而*表示矩阵对应元素相乘。
9.6 LSTM
长短期记忆模型(Long Short-Term Memory)
LSTM是循环神经网络模型的一个优秀的变种,继承了大部分循环神经网络模型的特性,同时解决了神经网络反向传播过程中容易发生的梯度消失问题。具体到语言处理任务中,LSTM非常适合处理与时间序列高度相关的问题,如机器翻译、对话生成、编解码等。
9.7 多种循环神经网络模型
-
双向循环神经网络(Bidirectional RNN,BRNN)
-
深度循环神经网络(Deep RNN)