深度学习入门
前言:依据李沐视频整理
数据操作
按元素操作
各个矩阵的元素都是按照对应位置来操作
1 |
|
1 |
|
逻辑判断
1 |
|
1 |
|
广播机制
在形状不同的张量上,会调用广播机制来执行按元素操作,也就是通过适当的复制元素来扩展一个或者两个数组,以便在转换之后,可以按照对应位置的元素进行操作
在大多数情况下,我们将沿着数组中长度为1的轴进行广播,如下例子:
1 |
|
1 |
|
由于a
和b
分别是3×1和1×2矩阵,如果让它们相加,它们的形状不匹配。 我们将两个矩阵广播为一个更大的3×2矩阵,如下所示:矩阵a
将复制列, 矩阵b
将复制行,然后再按元素相加。
1 |
|
1 |
|
转换为其他python对象
将深度学习框架定义的张量转换为NumPy张量(ndarray
)很容易,反之也同样容易。 torch张量和numpy数组将共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量。
1 |
|
1 |
|
将张量转换为标量,可以调用item函数
1 |
|
1 |
|
数据预处理
处理缺失值
典型的方法包括插值法和删除法。先使用pandas进行读取,然后进行插值操作
1 |
|
转换为张量
将pandas里面的数值转换为张量
1 |
|
1 |
|
线性代数
点积
通俗的讲就是是相同位置的按元素乘积的和:
1 |
|
1 |
|
也可以这样写
1 |
|
范数
简单讲范数即是向量的大小
- L1范数
向量绝对值相加
- L2范数
像是以前高中学过的向量的模
- F范数
针对矩阵的范数
调用以下函数将计算矩阵的Frobenius范数
1 |
|
矩阵计算
通常所指的梯度就是导数,即函数的斜率。梯度指向的是值变化最大的方向
自动求导的两种模式
- 正向累积
- 反向累积
链式法则的公式
正向累积 示意
反向累积、又称反向传递 示意
一个例子
对函数进行求导
1 |
|
损失函数
损失函数(loss function)能够量化目标的实际值与预测值之间的差距。 通常我们会选择非负数作为损失,且数值越小表示损失越小,完美预测时的损失为0。
回归问题中最常用的损失函数是平方误差函数。
分类问题中则多采用交叉熵损失函数
交叉熵损失函数
交叉熵常用来衡量两个概率的区别
将他作为损失
其中,对于任何标签y}和模型预测y^,损失函数为:
其梯度是真实概率和预测概率的区别
损失函数:用来衡量模型预测值与真实值之间的差异。
- 损失函数越小说明模型和参数越符合训练样本。
- 任何能够衡量模型预测值与真实值之间差异的函数都可以叫做损失函数。
- 为了避免过拟合,一般在损失函数的后面添加正则化项:
(F = 损失函数 + 正则化项)
常用的损失函数
1、交叉熵(Cross Entropy),用于分类:反应两个概率分布的距离(不是欧式距离)。交叉熵又称为对数似然损失、对数损失;二分类时还可称为逻辑回归损失。
1 |
|
其中:c表示损失值;
n表示样本数量,也就是batchsize;
x表示预测向量维度,主要是因为需要在输出的特征向量维度上一个个计算并求和;
y表示真实值,对应x维度上的标签(1 或 0);
a表示输出的预测概率值(0~1之间,总和为1)。
2、均方误差(Mean Squared error,MSE),用于回归:反应预测值与实际值之间的欧氏距离。
1 |
|
梯度下降
那么怎么进行模型的优化呢?我们用到一种名为梯度下降(gradient descent)的方法, 这种方法几乎可以优化所有深度学习模型。 它通过不断地在损失函数递减的方向上更新参数来降低误差。
那么,为什么需要进行梯度下降呢
有个挺不错的视频:[5分钟深度学习] #01 梯度下降算法_哔哩哔哩_bilibili
以线性的时候为例,现在需要一条直线来回归拟合这三个点
直线的方程是y =wx + b
,而通过上述的损失函数,也就是直线到点的距离量化,作为与实际相差的值,那么得到损失函数就是一个二次函数
这个二次函数的最小值,也就是损失函数的最小值,就是这个直线方程与实际相差最小,最拟合。这里我们使用牛顿迭代法来求出这个最小值,也就是图中所示的b的更新方程。其中ε就是学习率
梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)。 但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做小批量随机梯度下降(minibatch stochastic gradient descent)。
在每次迭代中,我们首先随机抽样一个小批量样本, 它是由固定数量的训练样本组成的。 然后,我们计算小批量的平均损失关于模型参数的导数(也可以称为梯度)。 最后,我们将梯度乘以一个预先确定的正数,并从当前参数的值中减掉。
计算梯度和损失值:
- 挑选一个初始值w0
- 重复迭代参数t = 1,2,3
- 沿梯度方向将增加损失函数值
- 学习率:步长的超参数
选择学习率,不能太大也不能太小
太小会导致训练慢
太大则会导致震荡
1 |
|
经典的梯度下降法
先假设一个学习率,参数沿梯度的反方向移动。
- 计算:每次迭代过程中,采用所有的训练数据的平均损失来近似目标函数。
- 特点:(1)靠近极值点时收敛速度减慢;(2)可能会" 之 "字形的下降。(3)对学习率非常敏感,难以驾驭;(4)对参数空间的方向没有解决方法。
SGD、SGDM、NAG
SGD(随机梯度下降法)
- 计算:每次只使用一个数据样本,去计算损失函数,求梯度,更新参数。
- 特点:(1)计算速度快,但是梯度下降慢(2)可能会在最低处两边震荡,停留在局部最优。
SGDM(SGM with Momentum:动量梯度下降)
-
计算:对已有的梯度进行指数加权平均,然后加上(1 - beta)。即在现有梯度信息的基础上,加入一个惯性。而梯度方向,由之前与现在的梯度方向共同决定。
-
优缺点:
-
(1)与SGD相比,训练过程的震荡幅度会变小,速度变快。
-
(2)SGDM速度没Adam快,但泛化能力好。
-
NAG(Nesterov Accelerated Gradient)
- 计算:先使用累积的动量计算一次,得到下一次的梯度方向,再把下一个点的梯度方向,与历史累积动量相结合,计算现在这个时刻的累计动量。
AdaGrad、RMSProp、Adam
-
AdaGrad(Adaptive Gradient,自适应步长):累积梯度平方
- 计算:在现有的(梯度 * 步长)上,添加了一个系数:1 /(历史梯度的平方和,再开根号)。
- 优缺点:(1)适合处理稀疏数据,可以对稀疏特征进行大幅更新。(2)学习率单调递减,最终会趋于0,学习提前终止。
-
RMSProp(root mean square prop,梯度平方根):累积梯度平方的滑动平均
- 计算:该方法和Adagrad的区别就是分母不一样,使得系数不会因为前几步的梯度太大而导致分母太大,从而导致系数变得太小而走不动。
-
Adam(Adaptive Moment Estimation,自适应估计):利用梯度的一阶、二阶矩阵估计
- 优缺点:Adam是一种在深度学习模型中用来替代随机梯度下降的优化算法。它是SGDM和RMSProp算法的结合,训练速度快,泛化能力不太行。
softmax
与线性回归一样,softmax回归也是一个单层神经网络。 由于计算每个输出o1、o2和o3取决于 所有输入x1、x2、x3和x4, 所以softmax回归的输出层也是全连接层。
简单的来说:
-
Softmax 回归是一个多分类模型
-
使用softmax操作子类得到每个类的预测置信度
-
使用交叉熵来衡量预测和标号的区别
在实际的应用中,可以直接使用softmax函数对模型输出的pred_logits进行处理,得到预测概率,且各个种类概率加起来等于1
使用F.softmax函数计算概率分布
1 |
|
感知机
XOR问题
当使用线性模型的时候,如果数据呈现下面的这种分布,很明显,我们无法通过一个线性模型来达到分类的目的
因此,聪明的人们想出了使用多层模型来达到分类的目的。
使用两个线性模型(上图的两条直线)先进行分类,然后进行异或运算,即可得到最终正确的分类,这就是多层的感知机
多层感知机在输出层和输入层之间增加一个或多个全连接隐藏层,并通过激活函数转换隐藏层的输出
激活函数
为什么要一个非线性激活函数
如果没有—那么最后多层感知机依旧是一个线性的模型,等价于一个单层的感知机
ReLU函数
最受欢迎的激活函数是修正线性单元(Rectified linear unit,ReLU), 因为它实现简单,同时在各种预测任务中表现良好。 ReLU提供了一种非常简单的非线性变换。 给定元素x,ReLU函数被定义为该元素与0的最大值:
说白了就是一个和0比较的max函数
1 |
|
sigmoid函数
对于一个定义域在R中的输入, sigmoid函数将输入变换为区间(0, 1)上的输出。 因此,sigmoid通常称为挤压函数(squashing function): 它将范围(-inf, inf)中的任意输入压缩到区间(0, 1)中的某个值
1 |
|
tanh函数
与sigmoid函数类似, tanh(双曲正切)函数也能将其输入压缩转换到区间(-1, 1)上。
1 |
|
(1)用于神经网络的隐含层与输出层之间(如:卷积层+激活函数+池化层),为神经网络提供非线性建模能力。
(2)若没有激励函数,则模型只能处理线性可分问题。与最原始的感知机相当,拟合能力有限。
深度学习的四种激活函数:
如何选择激活函数:
(1)任选其一:若网络层数不多
(2)ReLU:若网络层数较多
- 不宜选择sigmoid、tanh,因为它们的导数都小于1,sigmoid的导数更是在[0, 1/4]之间。
- 根据微积分链式法则,随着网络层数增加,导数或偏导将指数级变小。
- 网络层数较多的激活函数其导数不宜小于1也不能大于1,大于1将导致梯度爆炸,导数为1最好,而relu正好满足这个要
(3)Softmax:用于多分类神经网络输出层。
正则化
提高模型的泛化能力,防止过拟合
L1 正则化
L1正则化(L1范数),通常表示为:||W||1
:指权值向量 W 中各个元素的绝对值之和。- 特点:又叫特征选择,产生稀疏权值矩阵。即提取权重值最大的前N个值,并将冗余的权重值置0,直接删除。
L2 正则化
L2正则化(L2范数),通常表示为:||W||2
:指权值向量 W 中各个元素的平方和,然后求平方根。- 特点:又叫权重衰减。即抑制模型中产生过拟合的参数,使其趋近于0(而不等于0),影响变小。
- 特点:倾向于让所有参数的权值尽可能小。
若不关心显式特征(哪些特征重要或不重要),L2正则化的性能往往优于L1正则化。
Dropout 正则化
随机删除一定比例的神经元
1 |
|
Dropout正则化: 在训练过程中,随机删除一定比例的神经元(比例参数可设置)。
一般只在训练阶段使用,测试阶段不使用。
一般控制在20% ~ 50%。太低没有效果,太高则会导致模型欠学习。
应用场景:
(1)在大型网络模型上效果显著
(2)在输入层和隐藏层都使用Dropout
(3)当学习率和冲量值较大时:如学习率扩大10 ~ 100倍,冲量值调高到0.9 ~ 0.99。
(4)用于限制网络模型的权重时:学习率越大,权重值越大。
通常将其作用在隐藏全连接层的输出上
丢弃法将一些输出项随机置0来控制模型复杂度
丢弃概率是控制模型复杂度的超参数
1 |
|
前向传播
实现信息的前向传导,即数据从输入层,依次经过多个隐藏层,最终到达输出层。数据每经过一个网络层,其节点输出的值所代表的信息层次就越高阶和概括
反向传播
再贴一个视频 介绍反向传播
迭代训练,降低损失(loss,与最优化方法(如:梯度下降法)结合使用的,用来训练神经网络的常见方法。
通过损失函数,计算模型中所有权重参数的梯度,并反馈给优化算法进行梯度(权值)更新。迭代训练 N 次,获得最小损失。
这种沿着黄色箭头,从后向前计算参数梯度值的方法就叫反向传播算法。
单次反向传播的过程:首先是离输出层最近的网络层E,然后是网络层D,并按照EDCBA的依次顺序进行反向传播,直到所有层都完成一次。