(1)几种常见的参数初始化
1.均匀分布初始化
权重参数初始化从区间均匀随机取值。即在均匀分布中生成当前神经元的权重,其中d为每个神经元的输入数量
2.正态分布初始化
随机初始化从均值为0,标准差是1的高斯分布中取样,使用一些很小的值对参数W进行初始化
3.全0初始化
将神经网络中所有参数权重初始化为0
4.全1初始化
将神经网络中所有参数权重初始化为1
5.自定义值初始化
将神经网络中所有参数权重初始化为某个固定值
6.Kaiming初始化(he初始化)
也叫做HE 初始化,HE 初始化分为正态分布的 HE 初始化、均匀分布的 HE 初始化.
- 正态化的he初始化
stddev = sqrt(2 / fan_in)
均匀分布的he初始化
它从 [-limit,limit] 中的均匀分布中抽取样本, limit是 sqrt(6 / fan_in)
fan_in 输入神经元的个数
7.Xavier初始化
也叫做Glorot初始化,该方法也有两种,一种是正态分布的 xavier 初始化、一种是均匀分布的 xavier 初始化.
- 正态化的Xavier初始化
stddev = sqrt(2 / (fan_in + fan_out))
均匀分布的Xavier初始化
[-limit,limit] 中的均匀分布中抽取样本, limit 是 sqrt(6 / (fan_in + fan_out))
fan_in 是输入神经元的个数, fan_out 是输出的神经元个数
import torch import torch.nn.functional as F import torch.nn as nn # 1. 均匀分布随机初始化 def test01(): linear = nn.Linear(5, 3) # 从0-1均匀分布产生参数 nn.init.uniform_(linear.weight) print(linear.weight.data) # 2.固定初始化 def test02(): linear = nn.Linear(5, 3) nn.init.constant_(linear.weight, 5) print(linear.weight.data) # 3. 全0初始化 def test03(): linear = nn.Linear(5, 3) nn.init.zeros_(linear.weight) print(linear.weight.data) # 4. 全1初始化 def test04(): linear = nn.Linear(5, 3) nn.init.ones_(linear.weight) print(linear.weight.data) # 5. 正态分布随机初始化 def test05(): linear = nn.Linear(5, 3) nn.init.normal_(linear.weight, mean=0, std=1) print(linear.weight.data) # 6. kaiming 初始化 def test06(): # kaiming 正态分布初始化 linear = nn.Linear(5, 3) nn.init.kaiming_normal_(linear.weight) print(linear.weight.data) # kaiming 均匀分布初始化 linear = nn.Linear(5, 3) nn.init.kaiming_uniform_(linear.weight) print(linear.weight.data) # 7. xavier 初始化 def test07(): # xavier 正态分布初始化 linear = nn.Linear(5, 3) nn.init.xavier_normal_(linear.weight) print(linear.weight.data) # xavier 均匀分布初始化 linear = nn.Linear(5, 3) nn.init.xavier_uniform_(linear.weight) print(linear.weight.data)(2)神经网络的搭建方法?
搭建神经网络我们要记住一个公式:一个继承(nn.Module),两个方法(__init__(),forward()),搭建所有神经网络都万变不离其宗.
我们来构建如下图所示的神经网络模型:
编码设计如下:
第1个隐藏层:权重初始化采用标准化的xavier初始化 激活函数使用sigmoid
第2个隐藏层:权重初始化采用标准化的He初始化 激活函数采用relu
out输出层线性层 假若二分类,采用softmax做数据归一化
import torch import torch.nn as nn from torchsummary import summary # 计算模型参数,查看模型结构, pip install torchsummary # 创建神经网络模型类 class Model(nn.Module): # 初始化属性值 def __init__(self): super(Model, self).__init__() # 调用父类的初始化属性值 self.linear1 = nn.Linear(3, 3) # 创建第一个隐藏层模型, 3个输入特征,3个输出特征 nn.init.xavier_normal_(self.linear1.weight) # 初始化权 # 创建第二个隐藏层模型, 3个输入特征(上一层的输出特征),2个输出特征 self.linear2 = nn.Linear(3, 2) # 初始化权重 nn.init.kaiming_normal_(self.linear2.weight) # 创建输出层模型 self.out = nn.Linear(2, 2) # 创建前向传播方法,自动执行forward()方法 def forward(self, x): # 数据经过第一个线性层 x = self.linear1(x) # 使用sigmoid激活函数 x = torch.sigmoid(x) # 数据经过第二个线性层 x = self.linear2(x) # 使用relu激活函数 x = torch.relu(x) # 数据经过输出层 x = self.out(x) # 使用softmax激活函数 # dim=-1:每一维度行数据相加为1 x = torch.softmax(x, dim=-1) return x(3)分类损失函数原理及实现方法?
1.多分类任务:
在多分类任务通常使用softmax将logits转换为概率的形式,所以多分类的交叉熵损失也叫做softmax损失,它的计算方法是:
其中:
1.y 是样本 x 属于某一个类别的真实概率
2.而 f(x) 是样本属于某一类别的预测分数
3.S 是 softmax 激活函数,将属于某一类别的预测分数转换成概率
4.L 用来衡量真实值 y 和预测值 f(x) 之间差异性的损失结果
在pytorch中使用nn.CrossEntropyLoss()实现,如下所示:
import torch from torch import nn # 多分类交叉熵损失,使用nn.CrossEntropyLoss()实现。nn.CrossEntropyLoss()=softmax + 损失计算 def test1(): # 设置真实值: 可以是热编码后的结果也可以不进行热编码 # y_true = torch.tensor([[0, 1, 0], [0, 0, 1]], dtype=torch.float32) # 注意的类型必须是64位整型数据 y_true = torch.tensor([1, 2], dtype=torch.int64) y_pred = torch.tensor([[0.2, 0.6, 0.2], [0.1, 0.8, 0.1]], dtype=torch.float32) # 实例化交叉熵损失 loss = nn.CrossEntropyLoss() # 计算损失结果 my_loss = loss(y_pred, y_true).numpy() print('loss:', my_loss)2.二分类任务:
在处理二分类任务时,我们不再使用softmax激活函数,而是使用sigmoid激活函数,那损失函数也相应的进行调整,使用二分类的交叉熵损失函数:
其中:
- y 是样本x属于某一个类别的真实概率
- 而 y^ 是样本属于某一类别的预测概率
- L 用来衡量真实值y与预测值y^之间差异性的损失结果。
import torch from torch import nn def test2(): # 1 设置真实值和预测值 # 预测值是sigmoid输出的结果 y_pred = torch.tensor([0.6901, 0.5459, 0.2469], requires_grad=True) y_true = torch.tensor([0, 1, 0], dtype=torch.float32) # 2 实例化二分类交叉熵损失 criterion = nn.BCELoss() # 3 计算损失 my_loss = criterion(y_pred, y_true).detach().numpy() print('loss:', my_loss)
(4)回归损失函数原理及实现方法?
1.MAE损失
Mean absolute loss(MAE)也被称为L1 Loss,是以绝对误差作为距离。损失函数公式:
曲线如下图所示:
特点是:
- 由于L1 loss具有稀疏性,为了惩罚较大的值,因此常常将其作为
正则项添加到其他loss中作为约束。
- L1 loss的最大问题是梯度在零点不平滑,导致会跳过极小值。
在pytorch中使用nn.L1Loss()实现,如下所示:
import torch from torch import nn def test3(): # 1 设置真实值和预测值 y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True) y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float32) # 2 实例MAE损失对象 loss = nn.L1Loss() # 3 计算损失 my_loss = loss(y_pred, y_true).detach().numpy() print('loss:', my_loss)2.MSE损失
Mean Squared Loss/ Quadratic Loss(MSE loss)也被称为L2 loss,或欧氏距离,它以误差的平方和的均值作为距离
损失函数公式:
图象是:
特点是:
1.L2 loss也常常作为正则项。
2.当预测值与目标值相差很大时, 梯度容易爆炸。
在pytorch中使用nn.MSELoss()实现,如下所示:
import torch from torch import nn def test4(): # 1 设置真实值和预测值 y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True) y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float32) # 2 实例MSE损失对象 loss = nn.MSELoss() # 3 计算损失 my_loss = loss(y_pred, y_true).detach().numpy() print('myloss:', my_loss)3.回归任务损失函数-Smooth L1损失
smooth L1说的是光滑之后的L1。损失函数公式:
其中:𝑥 = f(x) − y 为真实值和预测值的差值。
从下图中可以看出,该函数实际上就是一个分段函数
- 在[-1,1]之间实际上就是L2损失,这样解决了L1的不光滑问题
- 在[-1,1]区间外,实际上就是L1损失,这样就解决了离群点梯度爆炸的问题
在pytorch中使用nn.SmoothL1Loss()实现,如下所示:
import torch from torch import nn def test5(): # 1 设置真实值和预测值 y_true = torch.tensor([0, 3]) y_pred = torch.tensor([0.6, 0.4], requires_grad=True) # 2 实例化smoothL1损失对象 loss = nn.SmoothL1Loss() # 3 计算损失 my_loss = loss(y_pred, y_true).detach().numpy() print('loss:', my_loss)(5)梯度下降算法是什么?
梯度下降法是一种寻找使损失函数最小化的方法。从数学上的角度来看,梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数减少最快的方向,所以有:
在进行模型训练时,有三个基础的概念:
1.Epoch: 使用全部数据对模型进行以此完整训练,训练轮次
2.Batch_size: 使用训练集中的小部分样本对模型权重进行以此反向传播的参数更新,每次训练每批次样本数量
3.Iteration: 使用一个 Batch 数据对模型进行一次参数更新的过程
(6)反向传播的定义及基本原理?
反向传播(Back Propagation):利用损失函数 ERROR,从后往前,结合梯度下降算法,依次求各个参数的偏导,并进行参数更新
反向传播对神经网络中的各个节点的权重进行更新。一个简单的神经网络用来举例:激活函数为sigmoid
我们先来求最简单的,求误差E对w5的导数。要求误差E对w5的导数,需要先求误差E对out o1的导数,再求out o1对net o1的导数,最后再求net o1对w5的导数,经过这个处理,我们就可以求出误差E对w5的导数(偏导),如下图所示:
导数(梯度)已经计算出来了,下面就是反向传播与参数更新过程:
如果要想求误差E对w1的导数,误差E对w1的求导路径不止一条,这会稍微复杂一点,但换汤不换药,计算过程如下所示:
(7)梯度下降优化方法-momentum?
momentum指的就是动量算法,用大白话来讲一下这个算法原理就是将动量比作一个大球,一直在推着你走.
梯度计算公式:Dt = β *St-1 + (1- β) *Wt
- St-1 表示历史梯度移动加权平均值
- Wt 表示当前时刻的梯度值
- Dt 为当前时刻的指数加权平均梯度值
- β 为权重系数
假设:权重 β 为 0.9,例如:
- 第一次梯度值:D1 =S1 =W1
- 第二次梯度值:D2=S2 = 0.9 *S1 +W2 * 0.1
- 第三次梯度值:D3=S3 = 0.9 *S2 +W3 * 0.1
- 第四次梯度值:D4=S4 = 0.9 *S3 +W4 * 0.1
梯度下降公式中梯度的计算,就不再是当前时刻 t 的梯度值,而是历史梯度值的指数移动加权平均值。公式修改为: