文章目录
- 第四周
- 1. 权值初始化
- 1.1 梯度消失与爆炸
- 1.2 Xavier初始化
- 1.3 权值初始化方法
- 2. 损失函数
- 2.1 损失函数概念
- 2.2 交叉熵损失函数
- 2.3 NLL/BCE/BCEWithLogits Loss
- 2.4 其他损失函数
- 2.5 作业
- 3. 优化器
- 3.1 优化器的概念
- 3.2 优化器的属性
- 3.3 优化器的方法
- 4. 随机梯度下降
- 4.1 learning rate 学习率
- 4.2 momentum 动量
- 4.3 torch.optim.SGD
- 4.4 Pytorch的十种优化器
- 4.5 作业
第四周
1. 权值初始化
1.1 梯度消失与爆炸
的梯度取决于上一层的输出
梯度消失:
梯度爆炸:
1.2 Xavier初始化
Xavier初始化
Kaiming初始化
其中,
1.3 权值初始化方法
- Xavier均匀分布
- Xavier标准正态分布
- Kaiming均匀分布
- Kaiming标准正态分布
- 均匀分布
- 正态分布
- 常数分布
- 正交矩阵初始化
- 单位矩阵初始化
- 稀疏矩阵初始化
# 计算激活函数的方差变换尺度
nn.init.calculate_gain(nonlinearity, # 激活函数名称
param=None) # 激活函数参数,如Leaky ReLU的negative_slop
2. 损失函数
2.1 损失函数概念
- 损失函数:衡量模型输出与真实标签的差异
- 损失函数(Loss Function):
- 代价函数(Cost Function):
- 目标函数(Objective Function):(L1/L2··正则项)
class _Loss(Module):
def __init__(self,reduction='mean'):
super(_Loss, slef).__init__()
self.reduction = reduction
2.2 交叉熵损失函数
- 相对熵:KL散度
- 为训练集数据分布;
# 计算交叉熵
nn.CrossEntropyLoss(weight=None, # 各类别loss设置的权值
ignore_index=-100, # 忽略某个类别
reduction='mean') # 计算模式,如none/sum/mean
# none:逐个元素计算
# sum:所有元素求和,返回标题
# mean:加权平均,返回标量
2.3 NLL/BCE/BCEWithLogits Loss
# 1. 实现负对数似然函数中的负号功能
nn.NLLLoss(weight=None, # 各类别的loss设置权值
ignore_index=-100, # 忽略某个类别
reduction='mean') # 计算模式,如none/sum/mean
# 2. 二分类交叉熵
# 注:输入值为[0,1],可配合sigmoid函数使用
nn.BCELoss(weight=None, # 各类别loss设置的权值
ignore_index=-100, # 忽略某个类别
reduction='mean') # 计算模式,如none/sum/mean
# 3. 结合Sigmoid与二分类交叉熵
# 注:不需要额外加入Sigmoid函数
nn.BCEWithLogitsLoss(weight=None, # 各类别loss设置的权值
ignore_index=-100, # 忽略某个类别
reduction='mean', # 计算模式,如none/sum/mean
pos_weight=None) # 正样本的权值
2.4 其他损失函数
nn.L1Loss
:nn.MSELoss
:nn.SmoothL1Loss
:
其中,nn.PoissonNLLLoss
nn.KLDivLoss
:nn.MarginRankingLoss
:nn.MultiLabelMarginLoss
:nn.SoftMarginLoss
:nn.MultiLabelSoftMarginLoss
:nn.MultiMarginLoss
:nn.TripletMarginLoss
:
其中,nn.HingeEmbeddingLoss
:nn.CosineEmbeddingLoss
:nn.CTCLoss
(新添加)
# 1. nn.L1Loss
# 计算inputs与target之差的绝对值
nn.L1Loss(reduction='mean') # 计算模式,如none/sum/mean
# 2. nn.MSELoss
# 计算inputs与target之差的屏方
nn.MSELoss(reduction='mean')
# 3. SmoothL1Loss
# 平滑的L1Loss
nn.SmoothL1Loss(reduction='mean')
# 4. PoissonNLLLoss
# 泊松分布的负对数似然损失函数
# log_input = True:loss(input,target)=exp(input)-target*input
# log_input = False:loss(input,target)=input-target*log(input+eps)
nn.PoissonNLLLoss(log_input=True, # 输入是否为对数形式
full=False, # 是否计算所有loss
eps=1e-08, # 修正项,避免log为nan
reduction='mean')
# 5. KLDivLoss
# 计算KL散度,相对熵
# 注:需提前输入计算log-probabilities,如通过nn.logsoftmax()计算
# batchmean:在batchsize维度求平均值
nn.KLDivLoss(reduction='mean') # 计算模式增加batchmean
# 6. MarginRankingLoss
# 计算两个向量之间的相似度,用于排序任务,返回一个n*n的loss矩阵
# y=1时,当x1>x2,不产生loss;y=-1时,当x2>x1,不产生loss
nn.MarginRankingLoss(margin=0, # 边界值,x1与x2之间的差异值
reduction='mean')
# 7. MultiLabelMarginLoss
# 多标签边界损失函数
# 例:四分类任务/样本属于0类和3类,标签为[0,3,-1,-1]
nn.MultiLabelMarginLoss(reduction='mean')
# 8. SoftMarginLoss
# 计算二分类的logistic损失
nn.SoftMarginLoss(reduction='mean')
# 9. MultiLabelSoftMarginLoss
# SoftMarginLoss多标签版本,标签为[1,0,0,1]
nn.MultiLabelSoftMarginLoss(weight=None, # 各类别的loss设置权值
reduction='mean')
# 10. MultiMarginLoss
# 计算多分类的折页损失
nn.MultiMarginLoss(p=1, # 可选1或2
margin=1.0, # 边界值
weight=None, # 各类别的loss设置权值
reduction='mean')
# 11. TripletMarginLoss
# 计算三元组损失,人脸验证中常用
nn.TripletMarginLoss(margin=1.0, # 边界值
p=2, # 范数的阶
eps=1e-06,
swap=False,
reductionn='mean')
# 12. HingeEmbeddingLoss
# 计算两个输入的相似性,常用于非线性embedding和半监督学习
# 注:输入x为两个输入之差的绝对值
nn.HingeEmbeddingLoss(margin=1.0,
reduction='mean')
# 13. CosineEmbeddingLoss
# 采用余弦相似度计算两个输入的相似性
nn.CosineEmbeddingLoss(margin=0, # 可取值[-1,1],推荐[0,0.5]
reductionn='mean')
# 14. CTCLoss
# 计算CTC损失,解决时序类数据的分类
nn.CTCLoss(blank=0, # blank label
reduction='mean', # 无穷大的值或梯度置0
zero_infinity=False)
2.5 作业
# -*- coding: utf-8 -*-
'''
第四周作业1:
1. Lossfunction依旧属于网络层的概念,即仍旧是Module的子类,为了对lossfunction有一个更清晰的概念,
需要大家采用步进(Step into)的调试方法从loss_functoin = nn.CrossEntropyLoss()语句进入函数,
观察从nn.CrossEntropyLoss()到class Module(object)一共经历了哪些类,记录其中所有进入的类及函数
2. 损失函数的reduction有三种模式,它们的作用分别是什么?
当inputs和target及weight分别如以下参数时,reduction='mean'模式时,loss是如何计算得到的?
inputs = torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
target = torch.tensor([0, 1, 1], dtype=torch.long)
weights = torch.tensor([1, 2])
'''
# ================================ 1 ================================
'''
第一步:CrossEntropyLoss类,super(CrossEntropyLoss, self).__init__
第二步:_WeightedLoss类,__init__()函数
第三步:_Loss类,__init__()函数
第四步:进入Module类
'''
# ================================ 2 ================================
'''
none:逐个元素计算
sum:所有元素求和
mean:加权平均
'''
# 加权平均:总loss/(1+2+2)
import torch
import torch.nn as nn
inputs = torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
target = torch.tensor([0, 1, 1], dtype=torch.long)
weights = torch.tensor([1, 2], dtype=torch.float)
loss_f_mean = nn.CrossEntropyLoss(weight=weights, reduction='mean')
loss_mean = loss_f_mean(inputs,target)
print("Cross Entropy Loss:\n ", loss_mean)
3. 优化器
3.1 优化器的概念
- 优化器:管理并更新模型中可学习参数的值,使得模型输出更接近真实标签
- 导数:函数在指定坐标轴上的变化率
- 方向导数:函数在指定方向上的变化率
- 梯度:向量,方向为方向导数取得最大值的方向
3.2 优化器的属性
class Optimizer(object):
def __init__(self, params, defaults):
self.defaults = defaults # 优化器超参数
self.state = defaultdict(dict) # 参数的缓存,如momentum的缓存
# param_groups = [{'params': param_groups}]
self.param_grops = [] # 管理的参数组,包含字典元素的list
# _step_count:记录更新次数,学习率调整中使用
...
3.3 优化器的方法
-
zero_grad()
:清空管理参数的梯度
注:pytorch中张量梯度不自动清零 -
step()
:执行一步更新 -
add_param_group
:添加参数组 -
state_dict()
:获取优化器当前状态信息字典 -
load_state_dict()
:加载状态信息字典
4. 随机梯度下降
4.1 learning rate 学习率
- 控制更新的步伐
4.2 momentum 动量
- 结合当前梯度与上一次更新信息,用于当前更新
- 指数加权平均:
4.3 torch.optim.SGD
其中, 为第 次更新的参数; 为学习率; 为更新量; 为momentum系数; 为
torch.optim.SGD(params, # 管理的参数组
lr=<object object>, # 初始学习率
momentum=0, # 动量系数beta
dampening=0, # L2正则化系数
weight_decay=0,
nesterov=False) # 是否采用NAG
4.4 Pytorch的十种优化器
-
optim.SGD
:随机梯度下降法 -
optim.Adagrad
:自适应学习率梯度下降法 -
optim.RMSprop
:Adagrad的改进 -
optim.Adadelta
:Adagrad的改进 -
optim.Adam
:RMSprop结合Momentum -
optim.Adamax
:Adam增加学习率上限 -
optim.SparseAdam
:稀疏版的Adam -
optim.ASGD
:随机平均梯度下降 -
optim.Rprop
:弹性反向传播 -
optim.LBFGS
:BFGS的改进
4.5 作业
# -*- coding: utf-8 -*-
'''
第四周作业3:
1. 优化器的作用是管理并更新参数组,请构建一个SGD优化器,通过add_param_group方法添加三组参数,
三组参数的学习率分别为0.01,0.02,0.03,momentum分别为0.9, 0.8, 0.7,构建好之后,
并打印优化器中的param_groups属性中的每一个元素的key和value(提示:param_groups是list,其每一个元素是一个字典)
'''
# ================================ 1 ================================
import torch
import torch.optim as optim
w1 = torch.randn((2, 2), requires_grad=True)
w2 = torch.randn((2, 2), requires_grad=True)
w3 = torch.randn((2, 2), requires_grad=True)
optimizer = optim.SGD([w1], lr=0.01, momentum=0.9)
optimizer.add_param_group({'params': w2, 'lr':0.02, 'momentum':0.8})
optimizer.add_param_group({'params': w3, 'lr':0.03, 'momentum':0.7})
#print("optimizer.param_groups is\n{}".format(optimizer.param_groups))
for index, group in enumerate(optimizer.param_groups):
params = group['params']
lr = group['lr']
momentum = group['momentum']
print("第【{}】组参数 params 为:\n{} \n学习率 lr 为:{} \n动量 momentum 为:{}".format(index, params, lr, momentum))
print("==============================================")