损失函数和网络优化方法(梯度下降、学习率优化方法) | 您所在的位置:网站首页 › 下降率下降梯度地速 › 损失函数和网络优化方法(梯度下降、学习率优化方法) |
一、损失函数
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 时刻的值 :调节权重系数,该值越大平均数越平缓 通过代码看结果,随机产生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()绘制结果如下: 上图为 =0.5和0.9时的结果,可以看出:值 越大,绘制的折线越平缓,波动越小。 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 实验室设备网 版权所有 |