• 深度学习--神经网络基础(2)


    损失函数

    在深度学习中, 损失函数是用来衡量模型参数的质量的函数 , 衡量的方式是比较网络输出和真实输
    出的差异:

    分类

    1.多分类损失函数

    在多分类任务通常使用 softmax logits 转换为概率的形式,所以多分类的交叉熵损失也叫做 softmax 损失 ,它的计算方法是:

    其中:
    1. y 是样本 x 属于某一个类别的真实概率
    2. f(x) 是样本属于某一类别的预测分数
    3. S softmax 激活函数 , 将属于某一类别的预测分数转换成概率
    4. L 用来衡量真实值 y 和预测值 f(x) 之间差异性的损失结果

    2.二分类任务损失交叉熵

    在处理二分类任务时,我们不再使用softmax激活函数,而是使用sigmoid激活函数,那损失函数也相应的进行调整, 使用二分类的交叉熵损失函数:

    其中:
    1. y是样本x属于某一个类别的真实概率
    2. 而y^是样本属于某一类别的预测概率
    3. L用来衡量真实值y与预测值y^之间差异性的损失结果。

    3.回归任务损失函数

    MAE损失函数

    Mean absolute loss(MAE)也被称为L1 Loss,是以绝对误差作为距离。损失函数公式:

    曲线如下图所示:

    特点是:
    1. 由于L1 loss具有稀疏性,为了惩罚较大的值,因此常常将其作为 正则项添加到其他loss中作为约束。
    2. L1 loss的最大问题是梯度在零点不平滑,导致会跳过极小值。
    MSE损失函数
    Mean Squared Loss/ Quadratic Loss(MSE loss) 也被称为L2 loss,或欧氏距离,它以误差的平方和的均值作为距离,损失函数公式:

    曲线如下图所示:

    特点是:
    1. L2 loss也常常作为正则项。
    2. 当预测值与目标值相差很大时, 梯度容易爆炸。
    Smooth L1损失函数
    smooth L1 说的是光滑之后的 L1 。损失函数公式 :

    其中: ? =f(x)−y 为真实值和预测值的差值。

    从上图中可以看出,该函数实际上就是一个分段函数
    1. [-1,1] 之间实际上就是 L2 损失,这样解决了 L1 的不光滑问题
    2. [-1,1] 区间外,实际上就是 L1 损失,这样就解决了离群点梯度爆炸的问题

    代码示例

    1. import torch
    2. # 1. 多任务交叉熵损失
    3. # 设置真实值: 可以是热编码后的结果也可以不进行热编码
    4. # 注意的类型必须是64位整型数据
    5. # y_true = torch.tensor([1,2],dtype=torch.int64)
    6. y_true = torch.tensor([[0, 1, 0], [0, 0, 1]], dtype=torch.float32)
    7. y_pred = torch.tensor([[1,10,1],[2,3,10]],dtype=torch.float32)
    8. # 实例化多任务交叉熵损失
    9. L= torch.nn.CrossEntropyLoss()
    10. # 计算损失结果
    11. print(L(y_pred,y_true))
    12. # 2. 二分类的交叉熵
    13. y_true = torch.tensor([0,0,1],dtype=torch.float32)
    14. y_pred = torch.tensor([0.01,0.02,0.7],dtype=torch.float32)
    15. # 二分类交叉熵损失
    16. L= torch.nn.BCELoss()
    17. print(L(y_pred,y_true))
    18. # 3. 回归任务
    19. y_true = torch.tensor([2.0,0.5,10],dtype=torch.float32)
    20. # y_pred = torch.tensor([2,8,0.9],dtype=torch.float32)
    21. y_pred = torch.tensor([2,0.8,9],dtype=torch.float32)
    22. # L =torch.nn.L1Loss()
    23. # L =torch.nn.MSELoss()
    24. L =torch.nn.SmoothL1Loss()
    25. print(L(y_pred,y_true))
    高级数字化帝都下降人才培训专家

    梯度下降优化方法

    梯度下降优化算法中,可能会碰到以下情况:
    1. 碰到平缓区域,梯度值较小,参数优化变慢
    2. 碰到 “鞍点” ,梯度为 0,参数无法优化
    3. 碰到局部最小值,参数不是最优
    对于这些问题, 出现了一些对梯度下降算法的优化方法,例如:Momentum、AdaGrad、RMSprop、Adam 等

     指数加权平均

    指数移动加权平均 则是参考各数值,并且各数值的权重都不同,距离越远的数字对平均数计算的贡献就越小(权重较小),距离越近则对平均数的计算贡献就越大(权重越大)。
    比如:明天气温怎么样,和昨天气温有很大关系,而和一个月前的气温关系就小一些。
    计算公式可以用下面的式子来表示:

    St 表示指数加权平均值 ;
    Yt 表示 t 时刻的值 ;
    β 调节权重系数,该值越大平均数越平缓。
    下面通过代码来看结果,随机产生 30 天的气温数据:

    1. import torch
    2. import matplotlib.pyplot as plt
    3. # 产生30天的随机温度
    4. temperature = torch.randn([30,]) * 10
    5. # 绘制平均温度
    6. x = torch.arange(0,30,1)
    7. plt.scatter(x,temperature)
    8. # 指数加权平均
    9. exp = [] # 指数加权后的值
    10. beta = 0.9
    11. for idx,tmp in enumerate(temperature):
    12. # 第一个元素的的 EWA 值等于自身
    13. if idx ==0:
    14. exp.append(tmp)
    15. continue
    16. # 第二个元素的 EWA 值等于上一个 EWA 乘以 β + 当前气温乘以 (1-β)
    17. t = beta * exp[idx-1] + (1-beta) * tmp
    18. exp.append(t)
    19. plt.scatter(x,temperature)
    20. plt.plot(x,exp)
    21. plt.show()

    上图是 β 0.5 0.9 时的结果,从中可以看出:
    指数加权平均绘制出的气氛变化曲线更加平缓,
    β 的值越大,则绘制出的折线越加平缓,波动越小。

    动量算法Momentum

    梯度计算公式:Dt = β * St-1 + (1- β) * Wt
    1. St-1 表示历史梯度移动加权平均值
    2. Wt 表示当前时刻的梯度值
    3. Dt 为当前时刻的指数加权平均梯度值
    4. β 为权重系数
    假设:权重 β 为 0.9,例如:
            第一次梯度值:s1 = d1 = 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 的梯度值,而是历史梯度值的指数移动加权平
    均值。公式修改为:
    W_t+1 = W_t - a * Dt

    adagrad

    AdaGrad 通过对不同的参数分量使用不同的学习率, AdaGrad 的学习率总体会逐渐减小
    其计算步骤如下:
    1. 初始化学习率 α 、初始化参数 θ 、小常数 σ = 1e-6
    2. 初始化梯度累积变量 s = 0
    3. 从训练集中采样 m 个样本的小批量,计算梯度 g
    4. 累积平方梯度 s = s + g g 表示各个分量相乘
    学习率 α 的计算公式如下:
    参数更新公式如下:

    重复 2-4 步骤 , 即可完成网络训练。
    AdaGrad 缺点是可能会使得学习率过早、过量的降低,导致模型训练后期学习率太小,较难找到最优解。

    RMSProp

    RMSProp 优化算法是对 AdaGrad 的优化 . 最主要的不同是,其使用 指数移动加权平均梯度 替换历史梯度 的平方和。其计算过程如下:
    1. 初始化学习率 α 、初始化参数 θ 、小常数 σ = 1e-6
    2. 初始化参数 θ
    3. 初始化梯度累计变量 s
    4. 从训练集中采样 m 个样本的小批量,计算梯度 g
    5. 使用指数移动平均累积历史梯度,公式如下:
    学习率 α 的计算公式如下:
    参数更新公式如下:
    高级数字化人才培训
    专家

    Adam

    -Momentum 使用指数加权平均计算当前的梯度值
    -AdaGrad、RMSProp 使用自适应的学习率
    -Adam优化算法(Adaptive Moment Estimation,自适应矩估计)将 Momentum 和
     RMSProp 算法结合在一起。
            1.修正梯度: 使⽤ 梯度的指数加权平均
            2.修正学习率: 使⽤ 梯度平 的指数加权平均

    代码示例

    1. import torch
    2. from torch import optim
    3. # 1. SGD
    4. # 初始化权重参数
    5. w = torch.tensor([1.0],requires_grad=True)
    6. y = (w**2/2.0).sum() # 损失函数
    7. # 优化方法:SGD指定参数beta(momentum)
    8. # optimizer = optim.SGD([w],lr=0.01,momentum=0.9)
    9. # 优化方法: Adagrad
    10. # optimizer = optim.Adagrad([w],lr=0.01)
    11. # 优化方法: RMSProp
    12. optimizer = optim.RMSprop([w],lr=0.01,alpha=0.9)
    13. # 优化方法:Adam
    14. optimizer = optim.Adam([w],lr=0.01,betas=[0.9,0.99])
    15. # 第一次更新计算梯度,并对参数进行更新
    16. optimizer.zero_grad() # 梯度清零
    17. y.backward() # 自动微分
    18. optimizer.step() # 更新权重
    19. # 打印结果
    20. print(w.detach().numpy()) # w本身
    21. print(w.grad.numpy()) # 梯度结果
    22. # 第二次更新计算梯度,并对参数进行更新
    23. y = (w**2/2.0).sum()
    24. optimizer.zero_grad() # 梯度清零
    25. y.backward() # 自动微分
    26. optimizer.step() # 更新权重
    27. # 打印结果
    28. print(w.detach().numpy())
    29. print(w.grad.numpy())

    学习率衰减方法

    等间隔学习率衰减

    指定间隔学习率衰减

     按指数学习率衰减

    代码示例

    1. import torch
    2. import matplotlib.pyplot as plt
    3. # 初始化参数
    4. y_true = torch.tensor([0.1])
    5. w = torch.tensor([1.0],requires_grad=True)
    6. x = torch.tensor([1.0])
    7. # 设置优化器
    8. optimizer = torch.optim.SGD([w],lr=0.1,momentum=0.9)
    9. # 设置间隔学习率下降策略 step_size:调整间隔数=50 , gamma:调整系数
    10. lr_s = torch.optim.lr_scheduler.StepLR(optimizer,step_size=20,gamma=0.1)
    11. # 设置指定间隔学习率下降策略 milestones:设定调整轮次 , gamma:调整系数
    12. # lr_s = torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones=[50, 125, 160],gamma=0.1)
    13. # 设置指数学习率下降策略 gamma:指数的底
    14. # lr_s = torch.optim.lr_scheduler.ExponentialLR(optimizer,gamma=0.98)
    15. # 获取学习率和当前的epoch
    16. lr_list = [] # 学习率
    17. for epoch in range(200): # 轮次
    18. lr_list.append(lr_s.get_last_lr()) # get_last_lr 提取学习率
    19. for i in range(10): # 批次
    20. loss = (w*x-y_true)**2/2.0 # 损失函数
    21. optimizer.zero_grad() # 梯度清零
    22. loss.backward() # 自动微分
    23. optimizer.step() # 更新权重
    24. # 更新下一个epoch的学习率
    25. lr_s.step()
    26. plt.plot(torch.arange(0,200),lr_list)
    27. plt.grid()
    28. plt.show()

    正则化

    在设计机器学习算法时希望在新样本上的泛化能力强。许多机器学习算法都采用相关的策略来减小测试误差,这些策 略被统称为正则化。
    神经网络的强大的表示能力经常遇到过拟合,所以需要使用不同形式的正则化策略。
    目前在深度学习中使用较多的策略有 范数惩罚, DropOut ,特殊的网络层等

    DropOut

    在练神经网络中模型参数较多,在数据量不足的情况下,很容易过拟合。 Dropout (随机失活)是一个简单有效的正则 化方法。
    在训练过程中, Dropout 的实现是 让神经元以超参数 p 的概率停止工作或者激活被置为 0, 未被置为 0 的进行缩放,缩放 比例为 1/(1-p) 。训练过程可以认为是对完整的神经网络的一些子集进行训练,每次基于输入数据只更新子网络的参数
      • 在测试过程中,随机失活不起作用。 

    批量归一化(BN)

    先对数据标准化,再对数据重构(缩放 + 平移),如下所示:

    1. λ β 是可学习的参数,它相当于对标准化后的值做了一个 线性变换 λ 为系数, β 为偏置;
    2. eps 通常指为 1e-5 ,避免分母为 0
    3. E(x) 表示变量的均值;
    4. Var(x) 表示变量的方差;

  • 相关阅读:
    网络与信息安全基础知识 (软件设计师笔记)
    23种设计模式之迭代器模式
    Spark - LeftOuterJoin 结果条数与左表条数不一致
    el-table的一些样式总结
    Kubernetes: kube-apiserver 之认证
    中国土工合成水泥复合垫行业应用态势与需求前景预测报告2022-2028年
    vue.js实现科室无限层选中和回显
    Redis的最佳实践?看完不心动,算我输!!
    算法通关村第16关【青铜】| 滑动窗口思想
    RDMA测试集:preftest安装与使用
  • 原文地址:https://blog.csdn.net/ZZ_zhenzhen/article/details/136356458