损失函数和网络优化方法(梯度下降、学习率优化方法) 您所在的位置:网站首页 下降率下降梯度地速 损失函数和网络优化方法(梯度下降、学习率优化方法)

损失函数和网络优化方法(梯度下降、学习率优化方法)

2024-06-30 14:10| 来源: 网络整理| 查看: 265

一、损失函数 1. 概述

        用来 衡量模型参数质量的函数,比较网络输出和真实输出的差异,也称为 代价、目标、误差函数:

2. 分类任务的损失函数 (1)多分类

        多分类的交叉熵损失 也叫 softmax损失,计算方法:

                y:样本x属于某一类别的真实概率

                f(x):样本属于某一类别的预测分数

                S:softmax激活函数

                L:衡量真实值y 和预测值 f(x) 之间的差异

 在pytorch中使用nn.CrossEntropyLoss()实现:

# 设置真实值(可热编码) y_true = torch.tensor([1, 2], dtype=torch.int64) # 实例化 交叉熵损失 loss = nn.CrossEntropyLoss() # 计算损失结果 my_loss = loss(y_pred, y_true).detach().numpy() (2)二分类

        用sigmoid激活函数,二分类的交叉熵损失函数:

                y:样本x属于某一类别的真实概率

                y^:样本属于某一类别的预测概率

                L:衡量真实值y 和预测值 y^ 之间的差异

在pytorch中实现时使用nn.BCELoss():

# 实例化二分类交叉熵损失 loss = nn.BCELoss() 3. 回归任务 (1)MAE

(Mean absolute loss):L1 Loss,以绝对误差作为距离

损失函数公式:

特点:1. 具有稀疏性,为了惩罚较大的值,常作为正则项 添加到其他 loss中作为约束

            2. 最大问题是 梯度在零点不平滑,会跳过极小值

在pytorch中实现时使用nn.L1Loss():

# 实例化MAE损失对象 loss = nn.L1Loss() (2)MSE

(Mean Squared Loss):L2 Loss,欧式距离,以误差的平方和的均值 作为距离

损失函数公式:

特点:1. L2 loss 也常作为正则项

            2. 当预测值与目标值相差很大时,梯度容易爆炸

在pytorch中使用nn.MSELoss()实现:

# 实例MSE损失对象 loss = nn.MSELoss() (3)smooth L1

        光滑之后的 L1,损失函数公式:

                x=f(x)-y :为真实值和预测值的差值

                在 [ -1,1 ] 之间就是L2损失,解决L1不光滑问题

                在 [ -1,1 ] 之外就是L1损失,解决离群点梯度爆炸的问题

在pytorch中使用 nn.SmoothL1Loss()实现:

# 实例化smmothL1损失对象 loss = nn.SmoothL1Loss() 二、网络优化方法 1. 基础概念

梯度下降:寻找使损失函数最小化的方法

梯度的反方向:函数减少最快的方向

学习率太小,每次训练的效果太小,增加训练的时间成本;太大,可能会直接跳过最优解,进入无限训练;因此,学习率需随着训练的进行而变化

Epoch:使用全部数据对模型进行一次完整训练的 训练轮次

Batch_size:每次训练的 每批次样本数量

Iteration:使用一个Batch进行一次参数更新

                Mini-Batch 的 Batch 个数 能整除时 则是 N / B

2. 反向传播(BP算法)

        利用损失函数,从后向前,结合梯度下降算法,依次求各个参数的偏导,进行参数更新

三、梯度下降 的优化方法

可能出现的问题:

        1. 遇到 平缓区域,梯度值较小,参数优化变慢

        2. 遇到 “鞍点”,梯度为0,参数无法优化

        3. 遇到 局部最小值,参数不是最优

1. 指数加权平均

        参考各数值,且权重都不同,距离越远的数字 对平均数计算 的贡献就越小(权重较小),距离越近权重越大。

                St:指数加权平均值

                Yt:t 时刻的值

                \beta:调节权重系数,该值越大平均数越平缓

通过代码看结果,随机产生30天的气温数据:

import torch import matplotlib.pyplot as plt num = 30 # 1. 实际平均温度 def test01(): # 固定随机数种子 torch.manual_seed(0) # 产生30天的随机温度 temperature = torch.randn(size=[num,]) * 10 print(temperature) # 绘制平均温度 days = torch.arange(1, num + 1, 1) plt.plot(days, temperature, color='r') plt.scatter(days, temperature) plt.show()

 绘制结果如下:

# 2. 指数加权平均温度 def test02(beta=0.5): # 再看beta=0.9 torch.manual_seed(0) # 固定随机数种子 temperature = torch.randn(size=[num,]) * 10 # 产生30天的随机温度 exp_weight_avg = [] for idx, temp in enumerate(temperature, 1): # 从下标1开始 # 第一个元素的的 EWA 值等于自身 if idx == 1: exp_weight_avg.append(temp) continue # 第二个元素的 EWA 值等于上一个 EWA 乘以 β + 当前气温乘以 (1-β) new_temp = exp_weight_avg[idx - 2] * beta + (1 - beta) * temp exp_weight_avg.append(new_temp) days = torch.arange(1, num + 1, 1) plt.plot(days, exp_weight_avg, color='r') plt.scatter(days, temperature) plt.show()

 绘制结果如下:

 上图为 \beta=0.5和0.9时的结果,可以看出:\beta值 越大,绘制的折线越平缓,波动越小。

2. 动量算法 Momentum

优点:已在先前积累了一些梯度值,使得很有可能跨过鞍点;使用 移动(指数)加权平均 计算当前 梯度值,平滑了梯度的变化,使得前进方向更加平缓,有利于加快训练过程。

def test01(): # 1 初始化权重参数 w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32) y = ((w ** 2) / 2.0).sum() # 2 实例化优化方法:SGD 指定参数beta=0.9 optimizer = torch.optim.SGD([w], lr=0.01, momentum=0.9) # 3 第1次更新 计算梯度,并更新参数 optimizer.zero_grad() y.backward() optimizer.step() print(w.grad.numpy(), w.detach().numpy()) # 4 第2次更新 计算梯度,并更新参数 y = ((w ** 2) / 2.0).sum() optimizer.zero_grad() y.backward() optimizer.step() print(w.grad.numpy(), w.detach().numpy())

momentum:动量参数,取值(0,1),取0时SGD为普通的梯度下降;大于0时,更新会考虑之前的梯度方向,有助于加速收敛并减少在优化过程中的震荡。

3. AdaGrad

概述:对不同的参数分量 使用不同的学习率,学习率总体会逐渐减小(使用自适应学习率)

计算步骤:                 1. 初始化学习率 α、初始化参数 θ,小常数 σ = 1e-6

                2. 初始化 梯度累积变量 s = 0

                3. 从训练集中采样 m 个样本的小批量,计算梯度 g

                4. 累积平方梯度 s = s + g ⊙ g,⊙ 表示各个分量相乘

                学习率 a :

                参数更新:

                重复 2 - 4 步骤,即可完成网络训练

AdaGrad 缺点:可能使 学习率过早、过量的降低,导致训练后期 学习率太小,较难找到最优解

optimizer = torch.optim.Adagrad ([w], lr=0.01) 4. RMSProp

是对 AdaGrad 的优化,用 指数移动加权平均梯度 替换 历史梯度的平方和(使用自适应学习率)

计算过程同下:

                1. 初始化学习率 α、初始化参数 θ,小常数 σ = 1e-6

                2. 初始化 梯度累积变量 s = 0

                3. 从训练集中采样 m 个样本的小批量,计算梯度 g

                4. 使用 指数移动平均累积历史梯度:

optimizer = torch.optim.RMSprop([w], lr=0.01,alpha=0.9) 5. Adam

概述:(Adaptive Moment Estimation,自适应矩估计)结合 Momentum 和 RMSProp 算法

        1. 修正梯度:使用 梯度 的指数加权平均

        2. 修正学习率:使用 梯度平方 的指数加权平均

optimizer = torch.optim.Adam([w], lr=0.01,betas=[0.9,0.99]) 四、学习率 优化方法 1. 等间隔 衰减 def test_StepLR(): # 0.参数初始化 LR = 0.1 # 设置学习率初始化值为0.1 iteration = 10 max_epoch = 200 # 1 初始化参数 y_true = torch.tensor([0]) x = torch.tensor([1.0]) w = torch.tensor([1.0], requires_grad=True) # 2.优化器 optimizer = optim.SGD([w], lr=LR, momentum=0.9) # 3.设置学习率下降策略 scheduler_lr = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # 4.获取学习率的值和当前的epoch lr_list, epoch_list = list(), list() for epoch in range(max_epoch): lr_list.append(scheduler_lr.get_last_lr()) # 获取当前lr epoch_list.append(epoch) # 获取当前的epoch for i in range(iteration): # 遍历每一个batch数据 loss = ((w*x-y_true)**2)/2.0 # 目标函数 optimizer.zero_grad() # 反向传播 loss.backward() optimizer.step() # 更新下一个epoch的学习率 scheduler_lr.step() # 5.绘制学习率变化的曲线 plt.plot(epoch_list, lr_list, label="Step LR Scheduler") plt.xlabel("Epoch") plt.ylabel("Learning rate") plt.legend() plt.show()

 2. 指定间隔 衰减

功能:指定间隔-调整学习率

主要参数:

                milestones:设定调整轮次:[50, 125, 160]

                gamma:调整系数

lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1)

3.  指数衰减          gamma:指数的底 lr_scheduler.ExponentialLR(optimizer, gamma)



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有