新手必备 | PyTorch基础入门教程(四)

第四周

1. 权值初始化

1.1 梯度消失与爆炸

H 2 = H 1 × W 2 H_2 = H_1 \times W_2 H2=H1×W2

Δ W 2 = ∂ L o s s ∂ o u t × ∂ o u t ∂ H 2 × ∂ H 2 ∂ w 2 = ∂ L o s s ∂ o u t × ∂ o u t ∂ H 2 × H 1 \begin{aligned}{\Delta W_{2}}=\frac{\partial Loss}{\partial out} \times \frac{\partial o u t}{\partial H_{2}} \times \frac{\partial H_{2}}{\partial w_{2}} \\=\frac{\partial Loss}{\partial out} \times \frac{\partial o u t}{\partial H_{2}} \times H_1 \end{aligned} ΔW2=outLoss×H2out×w2H2=outLoss×H2out×H1

Δ W 2 \Delta W_2 ΔW2 的梯度取决于上一层的输出 H 1 H_1 H1

梯度消失:

H 1 → 0 ⇒ Δ W 2 → 0 \begin{aligned} &\mathrm{H}_{1} \rightarrow 0 \Rightarrow \Delta \mathrm{W}_{2} \rightarrow 0 \end{aligned} H10ΔW20

梯度爆炸:

H 1 → ∞ ⇒ Δ W 2 → ∞ \begin{aligned} &\mathrm{H}_{1} \rightarrow \infty \Rightarrow \Delta \mathrm{W}_{2} \rightarrow \infty \end{aligned} H1ΔW2

1.2 Xavier初始化

Xavier初始化
在这里插入图片描述

Kaiming初始化

其中, a a a 为负半轴斜率

1.3 权值初始化方法

  • Xavier均匀分布
  • Xavier标准正态分布
  • Kaiming均匀分布
  • Kaiming标准正态分布
  • 均匀分布
  • 正态分布
  • 常数分布
  • 正交矩阵初始化
  • 单位矩阵初始化
  • 稀疏矩阵初始化
# 计算激活函数的方差变换尺度
nn.init.calculate_gain(nonlinearity,    # 激活函数名称
        param=None)    # 激活函数参数,如Leaky ReLU的negative_slop

2. 损失函数

2.1 损失函数概念

  • 损失函数:衡量模型输出与真实标签的差异
  • 损失函数(Loss Function): L o s s = f ( y ′ , y ) Loss = f(y^\prime, y) Loss=f(y,y)
  • 代价函数(Cost Function): C o s t = 1 N ∑ i N f ( y i ′ , y i ) Cost=\frac{1}{N} \sum_{i}^{N} f\left(y_{i}^{\prime}, y_{i}\right) Cost=N1iNf(yi,yi)
  • 目标函数(Objective Function): O b j = C o s t + R e g u l a r i z a t i o n Obj=Cost+Regularization Obj=Cost+Regularization(L1/L2··正则项)
class _Loss(Module):
    def __init__(self,reduction='mean'):
        super(_Loss, slef).__init__()
        self.reduction = reduction

2.2 交叉熵损失函数

  • 相对熵:KL散度
  • P P P 为训练集数据分布; Q Q Q 为模型输出数据分布
# 计算交叉熵
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 其他损失函数

  1. nn.L1Loss l n = ∣ x n − y n ∣ l_n=|x_n-y_n| ln=xnyn

  2. nn.MSELoss l n = ( x n − y n ) 2 l_n=(x_n-y_n)^2 ln=(xnyn)2

  3. nn.SmoothL1Loss l o s s ( x , y ) = 1 n ∑ i = 1 n z i loss(x,y)=\frac{1}{n} \sum_{i=1}^{n}{z_i} loss(x,y)=n1i=1nzi

    其中, z i = { 0.5 ( x i − y i ) 2 ,  if  ∣ x i − y i ∣ < 1 ∣ x i − y i ∣ − 0.5 ,  otherwise  z_{i}=\left\{\begin{array}{ll}{0.5\left(x_{i}-y_{i}\right)^{2},} & {\text { if }\left|x_{i}-y_{i}\right|<1} \\ {\left|x_{i}-y_{i}\right|-0.5,} & {\text { otherwise }}\end{array}\right. zi={0.5(xiyi)2,xiyi0.5, if xiyi<1 otherwise 

  4. nn.PoissonNLLLoss

  5. nn.KLDivLoss l n = y n × ( l o g y n − x n ) l_n=y_n \times (logy_n-x_n) ln=yn×(logynxn)

  6. nn.MarginRankingLoss l o s s ( x , y ) = m a x ( 0 , − y × ( x 1 − x 2 ) + m a r g i n ) loss(x,y)=max(0,-y \times (x_1-x_2)+margin) loss(x,y)=max(0,y×(x1x2)+margin)

  7. nn.MultiLabelMarginLoss loss ⁡ ( x , y ) = ∑ i j max ⁡ ( 0 , 1 − ( x [ y ( j ] ) − x [ i ] ) ) x . s i z e ( 0 ) \operatorname{loss}(x, y)=\sum_{ij} \frac{\max (0,1-(x[y(j])-x[i]))}{x.size(0)} loss(x,y)=ijx.size(0)max(0,1(x[y(j])x[i]))

  8. nn.SoftMarginLoss loss ⁡ ( x , y ) = ∑ i log ⁡ ( 1 + exp ⁡ ( − y [ i ] ∗ x [ i ] ) ) x . n e l e m e n t ( ) \operatorname{loss}(x, y)=\sum_{i} \frac{\log (1+\exp (-y[i] * x[i]))}{x.nelement()} loss(x,y)=ix.nelement()log(1+exp(y[i]x[i]))

  9. nn.MultiLabelSoftMarginLoss loss ⁡ ( x , y ) = − 1 x . n e l e m e n t ( ) ∗ ∑ i y [ i ] ∗ log ⁡ ( ( 1 + exp ⁡ ( − x [ i ] ) ) − 1 ) + ( 1 − y [ i ] ) ∗ log ⁡ ( exp ⁡ ( − x ∣ i ∣ ) ( 1 + exp ⁡ ( − x [ i ) ) ) ) \operatorname{loss}(x, y)=-\frac{1}{x.nelement()} * \sum_{i} y[i] * \log \left((1+\exp (-x[i]))^{-1}\right)+(1-y[i]) * \log \left(\frac{\exp (-x|i|)}{(1+\exp (-x[i)))}\right) loss(x,y)=x.nelement()1iy[i]log((1+exp(x[i]))1)+(1y[i])log((1+exp(x[i)))exp(xi))

  10. nn.MultiMarginLoss loss ⁡ ( x , y ) = ∑ i max ⁡ ( 0 , margin ⁡ − x [ y ] + x [ i ] ) ) p x . s i z e ( 0 ) \operatorname{loss}(x, y)=\frac{\left.\sum_{i} \max (0, \operatorname{margin}-x[y]+x[i])\right)^{p}}{x.size(0)} loss(x,y)=x.size(0)imax(0,marginx[y]+x[i]))p

  11. nn.TripletMarginLoss L ( a , p , n ) = m a x { d ( a i , p i ) − d ( a i , n i ) + margin , 0 } L(a,p,n)=max\{d(a_i,p_i)-d(a_i,n_i)+\text{margin},0\} L(a,p,n)=max{d(ai,pi)d(ai,ni)+margin,0}
    其中, d ( x i , y i ) = ∣ ∣ x i − y i ∣ ∣ p d(x_i,y_i)={||x_i-y_i||}_p d(xi,yi)=xiyip

  12. nn.HingeEmbeddingLoss l n = { x n ,  if  y n = 1 max ⁡ { 0 , margin − x n } ,  if  y n = − 1 l_{n}=\left\{\begin{array}{ll}{x_{n},} & {\text { if } y_{n}=1} \\ {\max \left\{0, \text{margin}-x_{n}\right\},} & {\text { if } y_{n}=-1}\end{array}\right. ln={xn,max{0,marginxn}, if yn=1 if yn=1

  13. nn.CosineEmbeddingLoss loss ⁡ ( x , y ) = { 1 − cos ⁡ ( x 1 , x 2 ) ,  if  y = 1 max ⁡ ( 0 , cos ⁡ ( x 1 , x 2 ) −  margin  ) ,  if  y = − 1 \operatorname{loss}(x, y)=\left\{\begin{array}{ll}{1-\cos \left(x_{1}, x_{2}\right),} & {\text { if } y=1} \\ {\max \left(0, \cos \left(x_{1}, x_{2}\right)-\text { margin }\right),} & {\text { if } y=-1}\end{array}\right. loss(x,y)={1cos(x1,x2),max(0,cos(x1,x2) margin ), if y=1 if y=1

  14. 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 动量

  • 结合当前梯度与上一次更新信息,用于当前更新

  • 指数加权平均: v t = β × v t − 1 + ( 1 − β ) × θ t v_t=\beta \times v_{t-1}+(1-\beta)\times \theta_t vt=β×vt1+(1β)×θt

4.3 torch.optim.SGD

v i = m × v i − 1 + g ( w i ) v_i=m \times v_{i-1}+g(w_i) vi=m×vi1+g(wi)

w i + 1 = w i − l r × v i w_{i+1}=w_i-lr \times v_i wi+1=wilr×vi

其中, w i + 1 w_{i+1} wi+1 为第 i + 1 i+1 i+1 次更新的参数; l r lr lr 为学习率; v i v_i vi 为更新量; m m m 为momentum系数; g ( w i ) g(w_i) g(wi) w i wi wi 的梯度

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("==============================================")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mrrunsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值