本地镇江网站建设,泉州网站制作建设,深圳医院网站建设,58同城合肥网站建设三、网络优化方法
1.梯度下降算法梯段下降算法是一种寻找使损失函数最小化的方法#xff0c;从数学上的角度来看#xff0c;梯度的方向是函数增长速度最快的方向#xff0c;那么梯度的反方向就是函数减少最快的方向#xff0c;所以有WijnewWijold−η∂E∂WijW_{ij}^{new} …三、网络优化方法
1.梯度下降算法梯段下降算法是一种寻找使损失函数最小化的方法从数学上的角度来看梯度的方向是函数增长速度最快的方向那么梯度的反方向就是函数减少最快的方向所以有WijnewWijold−η∂E∂WijW_{ij}^{new} W_{ij}^{old}-\eta\frac{\partial E}{\partial W_{ij}}WijnewWijold−η∂Wij∂E
其中η\etaη是学习率如果学习率太小那么每次训练之后得到的效果都太小增大训练的时间成本如果学习率太大那就有可能直接跳过最优解进入无限的训练中。解决的方法就是学习率也需要随着训练的进行而变化在进行模型训练的时候有三个基础的概念
EpochEpochEpoch使用全部数据对模型进行一次完整训练训练轮次Batch_sizeBatch\_sizeBatch_size使用训练集中的小部分样本对模型权重进行以此反向传播的参数更新每次训练每批次样本的数量越大越好IteraionIteraionIteraion使用一个Batch数据对模型进行一次参数更新的过程eg.eg.eg.假设数据集有500005000050000个训练样本现在选择BatchSize256Batch Size 256BatchSize256对模型进行训练每个EpochEpochEpoch要训练的图片数量为500005000050000训练集具有BatchBatchBatch个数为50000/256119650000/256 1 19650000/2561196每个EpochEpochEpoch具有的IterationIterationIteration个数为196196196101010个EpochEpochEpoch具有的IterationIterationIteration个数为196019601960在深度学习中梯度下降的几种方式的根本区别就在于Batch Size不同梯度下降方式Training Set SizeBatch SizeNumber of BatchBGDNN1SGDN1NMini-BatchNBN / B 1注N/ B 1是针对未整除的情况。整除则是 N/ B在工作的时候通常使用的是 Mini-Batch2.反向传播算法过程
1反向传播BP算法
前向传播指的是数据输入的神经网络中逐层向前传输一直运算到输出层为止反向传播BackPropagation利用损失函数ERROR从后往前结合梯度下降算法依次求各个参数的偏导并进行参数更新解释
前向传播获取预测结果计算损失交叉熵/MSE先计算W3W_3W3再计算W2W_2W2最后计算W1W_1W1)反向传播利用梯度下降算法对参数进行更新for _ in range(epochs):for train_x, train_y in dataloader:# 将一个batch的训练数据送入模型y_pred model(train_x.type(torch.float32))# 计算损失值loss criterion(y_pred, train_y, reshape(-1,1).type(torch.float32))total_loss loss.item()train_sample len(train_y)# 梯度清零optimizer.zero_grad()# 自动微分loss.backward()# 更新参数optimizer.step()3.梯度下降的优化方法梯度下降优化算法中可能会碰到以下情况碰到平缓区域梯度值较小参数优化变慢碰到鞍点梯度为0参数无法优化碰到局部最小值参数不是最优对于这些问题出现了一些对梯度下降算法的优化方法例如Momentum AgaGradPMSpropAdam等1指数加权平均
指数移动加权平均参考各数值并且各数值的权重都不同距离越远的数字对平均数计算的贡献就越小权重较小距离越近则对平均数的计算贡献就越大权重越大计算公式st{Y1,t0β⋅st−1(1−β)⋅Yt,t0{s}_t
\begin{cases}
\displaystyle Y_1, t 0 \\
\displaystyle \beta \cdot {s}_{t-1} (1 - \beta) \cdot Y_t, t 0
\end{cases}st{Y1,β⋅st−1(1−β)⋅Yt,t0t0
StS_tSt表示指数加权平均值YtY_tYt表示ttt时刻的值β\betaβ调整权重参数该值越大平均数越平缓2动量算法Momentum
梯度计算公式Dtβ⋅St−1(1−β)⋅WtD_t \beta \cdot S_{t - 1} (1-\beta) \cdot W_tDtβ⋅St−1(1−β)⋅Wt
St−1S_{t - 1}St−1表示表示梯度移动加权平均值WtW_tWt表示当前时刻的梯度值DtD_tDt为当前时刻的梯度值β\betaβ为权重系数示例权重β\betaβ为0.9 则第一次梯度值S1D1W1S_1 D_1 W_1S1D1W1第二次梯度值D2S20.9×S1W2×0.1D_2 S_2 0.9 \times S_1 W_2 \times0.1D2S20.9×S1W2×0.1第三次梯度值D3S30.9×S2W3×0.1D_3 S_3 0.9 \times S_2 W_3 \times 0.1D3S30.9×S2W3×0.1第四次梯度值D4S40.9×S3W4×0.1D_4 S_4 0.9 \times S_3 W_4 \times 0.1D4S40.9×S3W4×0.1
梯度下降公式中梯度的计算就不再是当前时刻t的梯度值而是历史梯度值的指数移动加权平均值公式修改为Wt1Wt−α⋅DtW_{t 1} W_t - \alpha \cdot D_tWt1Wt−α⋅Dt
拓展Monmentum优化方法是如何一定程度上克服“平缓”“鞍点”的问题呢
当处于鞍点位置时由于当前的梯度为0参数无法更新。但是Momentum动量梯度下降算法已经在先前累计了一些梯度值很有可能使得跨过鞍点由于mini-batch普通的梯度下降算法每次选取少数的样本梯度确定前进方向可能会出现震荡使得训练时间变长。Momentum使用移动加权平均平滑了梯度的变化使得前进方向更加平缓有利于加快训练过程
加了动量之后的结果import torchw torch.tensor([1.0], requires_gradTrue, dtypetorch.float32)loss ((w ** 2)*0.5).sum()optimizer torch.optim.SGD([w], lr 0.01, momentum0.9)optimizer.zero_grad()
loss.backward()
optimizer.step()print(第一次更新加了动量之后梯度,w.grad)
print(第一次更新加了动量之后w,w.detach())loss ((w ** 2)*0.5).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()print(第二次更新加了动量之后梯度,w.grad)
print(第二次更新加了动量之后w,w.detach()) # tensor([0.9711])改变了没加动量时 tensor([0.9801])tensor([0.9900])---tensor([0.9711]) 减少得更多更新得更加快一点输出结果
第一次更新加了动量之后梯度 tensor([1.])
第一次更新加了动量之后w tensor([0.9900])
第二次更新加了动量之后梯度 tensor([0.9900])
第二次更新加了动量之后w tensor([0.9711])3AdaGradAdaGrad通过对不同的参数分量使用不同的学习率AdaGrad的学习率总体会逐渐减小计算步骤如下初始化学习率α\alphaα初始化参数θ\thetaθweightbias小常数σ1e−6\sigma 1e - 6σ1e−6放在分母上防止分母为0初始化梯度累计变量s0s 0s0从训练集中采样mmm个样本的小批量计算梯度ggg累积平方梯度ssg⊙g{s} {s} {g} \odot {g}ssg⊙g⊙\odot⊙表示各个分量相乘学习率α\alphaα的计算公式如下ααsσ\alpha \frac{\alpha}{\sqrt s \sigma}αsσα参数更新公式如下θθ−αsσ⋅g\theta \theta - \frac{\alpha}{\sqrt s \sigma} \cdot gθθ−sσα⋅g重复2-4步骤即可完成网络训练
AdaGrad缺点可能会使得学习率过早过量的降低学习率太小了则更新速度变慢了迭代相同次数就不能够到最优解导致训练后期学习率大小较难找到最优解
import torchw torch.tensor([1.0], requires_gradTrue, dtypetorch.float32)
loss ((w ** 2)*0.5).sum()optimizer torch.optim.Adagrad([w], lr 0.01)optimizer.zero_grad()
loss.backward()print(第一次更新 梯度,w.grad) # 获取梯度的值
print(第一次更新 w,w.detach()) # 获取w的值# 再次更新参数
loss ((w ** 2)*0.5).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()print(第二次更新 梯度,w.grad) # 获取梯度的值
print(第二次更新 w,w.detach()) # 获取w的值输出结果
第一次更新 梯度 tensor([1.])
第一次更新 w tensor([1.])
第二次更新 梯度 tensor([1.])
第二次更新 w tensor([0.9900])4RMSPropRMSProp优化算法是对AdaGrad的优化最主要的不同是其使用指数移动加权平均梯度替换历史梯度的平方和。计算过程如下
初始化学习率α\alphaα初始化参数θ\thetaθ小常数σ1e−6\sigma 1e-6σ1e−6初始化参数θ\thetaθ初始化梯度累计变量sss从训练集中采样mmm个样本的小批量计算梯度ggg使用指数移动平均累积历史梯度公式如下sβ⋅s(1−β)g⊙gs \beta \cdot s (1 - \beta)g \odot gsβ⋅s(1−β)g⊙g
学习率α\alphaα的计算公式如下ααsσ\alpha \frac{\alpha}{\sqrt s \sigma}αsσα参数更新公式如下θθ−αsσ⋅g\theta \theta - \frac{\alpha}{\sqrt s \sigma} \cdot gθθ−sσα⋅gimport torchw torch.tensor([0.1], requires_gradTrue, dtype torch.float32)
loss ((w ** 2)*0.5).sum()optimizer torch.optim.RMSprop([w], lr 0.01, alpha 0.9)optimizer.zero_grad()
loss.backward()print(第一次更新 梯度, w.grad)
print(第一次更新 w, w.detach())# 再次更新参数
loss ((w ** 2)*0.5).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()print(第二次更新 梯度,w.grad) # 获取梯度的值
print(第二次更新 w,w.detach()) # 获取w的值输出结果
第一次更新 梯度 tensor([0.1000])
第一次更新 w tensor([0.1000])
第二次更新 梯度 tensor([0.1000])
第二次更新 w tensor([0.0684])4.学习率衰减方法
通常是和 动量算法Momentum 组合在一起后面学习中通常使用指定间隔学习率衰减
1等间隔学习率衰减
import torch
import matplotlib.pyplot as plot# 参数初始化
LR 0.1
iteration 100
epochs 200
# 网络数据初始化
x torch.tensor([1.0])
w torch.tensor([1.0], requires_grad True)
y torch.tensor([1.0])
# 优化器
optimizer torch.optim.SGD([w], lr LR, momentum0.9)
# 学习率策略
scheduler_lr torch.optim.lr_scheduler.StepLR(optimizer, step_size20, gamma 0.8)
# 遍历轮次
epoch_list []
lr_list []
for epoch in range(epochs):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)# 遍历batchfor i in range(iteration):# 计算损失loss ((w*x-y)**2)*0.5# 更新参数optimizer.zero_grad()loss.backward()optimizer.step()# 更新lrscheduler_lr.step()
# 绘制结果
plt.plot(epoch_list, lr_list)
plt.grid()
plt.show()2指定间隔学习率衰减
import torch
import matplotlib.pyplot as plot# 参数初始化
LR 0.1
iteration 100
epochs 200
# 网络数据初始化
x torch.tensor([1.0])
w torch.tensor([1.0], requires_grad True)
y torch.tensor([1.0])
# 优化器
optimizer torch.optim.SGD([w], lr LR, momentum0.9)
# 学习率策略
scheduler_lr torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones [20, 60, 90, 135, 180], gamma 0.8)
# 遍历轮次
epoch_list []
lr_list []
for epoch in range(epochs):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)# 遍历batchfor i in range(iteration):# 计算损失loss ((w*x-y)**2)*0.5# 更新参数optimizer.zero_grad()loss.backward()optimizer.step()# 更新lrscheduler_lr.step()
# 绘制结果
plt.plot(epoch_list, lr_list)
plt.grid()
plt.show()3按指数学习率衰减
这种策略用得很少一般不会选择gamma值通常是小于1它是指 指数的底调整方式lrlr⋅gammaepochlr lr \cdot gamma^{epoch}lrlr⋅gammaepoch
import torch
import matplotlib.pyplot as plot# 参数初始化
LR 0.1
iteration 100
epochs 200
# 网络数据初始化
x torch.tensor([1.0])
w torch.tensor([1.0], requires_grad True)
y torch.tensor([1.0])
# 优化器
optimizer torch.optim.SGD([w], lr LR, momentum0.9)
# 学习率策略
scheduler_lr torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma 0.8)
# 遍历轮次
epoch_list []
lr_list []
for epoch in range(epochs):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)# 遍历batchfor i in range(iteration):# 计算损失loss ((w*x-y)**2)*0.5# 更新参数optimizer.zero_grad()loss.backward()optimizer.step()# 更新lrscheduler_lr.step()
# 绘制结果
plt.plot(epoch_list, lr_list)
plt.grid()
plt.show()