深度学习基础2

1.损失函数

1.1 线性回归损失函数

1.1.1 MAE损失

MAE(Mean Absolute Error,平均绝对误差)通常也被称为 L1-Loss,通过对预测值和真实值之间的绝对差取平均值来衡量他们之间的差异。。

公式:

其中:

  • n 是样本的总数。

  • y_i 是第 i 个样本的真实值。

  • \hat{y}_i 是第 i 个样本的预测值。

  • \left| y_i - \hat{y}_i \right| 是真实值和预测值之间的绝对误差。

特点

  • 鲁棒性:与均方误差(MSE)相比,MAE对异常值(outliers)更为鲁棒,因为它不会像MSE那样对较大误差平方敏感。

  • 物理意义直观:MAE以与原始数据相同的单位度量误差,使其易于解释。

应用场景

MAE通常用于需要对误差进行线性度量的情况,尤其是当数据中可能存在异常值时,MAE可以避免对异常值的过度惩罚。

import torch
import torch.nn as nny_true = torch.tensor([1.0, 2.0, 3.0])
y_pred = torch.tensor([4.0, 5.0, 6.0])mae = nn.L1Loss()loss  = mae(y_true,y_pred)print(loss)

1.1.2 MSE损失

均方差损失,也叫L2Loss

MSE(Mean Squared Error,均方误差)通过对预测值和真实值之间的误差平方取平均值,来衡量预测值与真实值之间的差异。

公式:

其中:

  • n 是样本的总数。

  • y_i 是第 i 个样本的真实值。

  • \hat{y}_i 是第 i 个样本的预测值。

  • \left( y_i - \hat{y}_i \right)^2 是真实值和预测值之间的误差平方。

 特点

  • 平方惩罚:因为误差平方,MSE 对较大误差施加更大惩罚,所以 MSE 对异常值更为敏感。

  • 凸性:MSE 是一个凸函数,这意味着它具有一个唯一的全局最小值,有助于优化问题的求解。

应用场景

MSE被广泛应用在神经网络中。

y_true = torch.tensor([1.0, 4.0, 5.0])
y_pred = torch.tensor([6.0, 3.0, 2.0])mae = nn.MSELoss()loss  = mae(y_true,y_pred)print(loss)

1.1.3 SmoothL1Loss

SmoothL1Loss可以做到在损失较小时表现为 L2 损失,而在损失较大时表现为 L1 损失。

公式:

其中,x 表示预测值和真实值之间的误差,即x = y_i - \hat{y}_i。

所有样本的平均损失为:

特点:

  • 平滑过渡:当误差较小时,损失函数表现为 L2 Loss(平方惩罚);当误差较大时,损失函数逐渐向 L1 Loss过渡。这种平滑过渡既能对大误差有所控制,又不会对异常值过度敏感。

  • 稳健性:对于异常值更加稳健,同时在小误差范围内提供了较好的优化效果。

应用场景:

常用于需要对大误差进行一定控制但又不希望完全忽略小误差的回归任务。特别适用于目标检测任务中的边界框回归,如 Faster R-CNN 等算法中。

predictions = torch.tensor([1.0, 2.0, 3.0, 4.0])
targets = torch.tensor([3.0, 2.5, 3.5, 4.5])# 方式一:
smooth_loss = nn.SmoothL1Loss()
loss = smooth_loss(predictions,targets)
print(loss)# 方式二:
loss1 = nn.functional.smooth_l1_loss(predictions,targets)
print(loss1)

1.2 CrossEntropyLoss

交叉熵损失函数,使用在输出层使用softmax激活函数进行多分类时,一般都采用交叉熵损失函数。

对于多分类问题,CrossEntropyLoss 公式如下:

其中:

  • C 是类别的总数。

  • y 是真实标签的one-hot编码向量,表示真实类别。

  • \hat{y} 是模型的输出(经过 softmax 后的概率分布)。

  • y_i 是真实类别的第 i 个元素(0 或 1)。

  • \hat{y}_i 是预测的类别概率分布中对应类别 i 的概率。

特点:

Softmax 就是将网络输出的 logits 通过 softmax 函数,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们将它理解成概率,选取概率最大(也就是值对应最大的)节点,作为我们的预测目标类别。

# 假设有三个类别,模型输出是未经softmax的logits
logits = torch.tensor([[1.5, 2.0, 0.5], [0.5, 1.0, 1.5]])
labels = torch.tensor([1,2])criterion = nn.CrossEntropyLoss()loss = criterion(logits,labels)
print(loss)

1.3 BCELoss

二分类交叉熵损失函数,使用在输出层使用sigmoid激活函数进行二分类时。

公式:

log的底数一般默认为e,y是真实类别目标,根据公式可知L是一个分段函数 :

以上损失函数是一个样本的损失值,总样本的损失值是求损失均值即可。

# y 是模型的输出,已经被sigmoid处理过,确保其值域在(0,1)
y = torch.tensor([[0.7], [0.2], [0.9], [0.7]],dtype=torch.float32)
# targets 是真实的标签,0或1
t = torch.tensor([[1], [0], [1], [0]],dtype=torch.float32)# 计算损失方式一:
bceloss = nn.BCELoss()
loss = bceloss(y,t)
print(loss)#计算损失方式二: 
loss2 = nn.functional.binary_cross_entropy(y,t)
print(loss2)

1.4. 总结

(1)当输出层使用softmax多分类时,使用交叉熵损失函数;

(2)当输出层使用sigmoid二分类时,使用二分类交叉熵损失函数, 比如在逻辑回归中使用;

(3)当功能为线性回归时,使用smooth L1损失函数或均方差损失-L2 loss;

2.BP算法

多层神经网络的学习能力比单层网络强得多。想要训练多层网络,需要更强大的学习算法。误差反向传播算法(Back Propagation)是其中最杰出的代表,它是目前最成功的神经网络学习算法。BP 算法不仅可用于多层前馈神经网络,还可以用于其他类型的神经网络。通常说 BP 网络时,一般是指用 BP 算法训练的多层前馈神经网络。

误差反向传播算法(BP)的基本步骤:

(1)前向传播:正向计算得到预测值。

(2)计算损失:通过损失函数计算预测值和真实值的差距。

(3)梯度计算:反向传播的核心是计算损失函数 L 对每个权重和偏置的梯度。

(4)更新参数:一旦得到每层梯度,就可以使用梯度下降算法来更新每层的权重和偏置,使得损失逐渐减小。

(5)迭代训练:将前向传播、梯度计算、参数更新的步骤重复多次,直到损失函数收敛或达到预定的停止条件。

2.1 前向传播

前向传播(Forward Propagation)把输入数据经过各层神经元的运算并逐层向前传输,一直到输出层为止。

作用:

  • 计算神经网络的输出结果,用于预测或计算损失。

  • 在反向传播中使用,通过计算损失函数相对于每个参数的梯度来优化网络。

2.2 反向传播

反向传播(Back Propagation,简称BP)通过计算损失函数相对于每个参数的梯度来调整权重,使模型在训练数据上的表现逐渐优化。反向传播结合了链式求导法则和梯度下降算法,是神经网络模型训练过程中更新参数的关键步骤。

2.2.1 原理

利用链式求导法则对每一层进行求导,直到求出输入层x的导数,然后利用导数值进行梯度更新

2.2.2. 链式法则

链式求导法则(Chain Rule)是微积分中的一个重要法则,用于求复合函数的导数。在深度学习中,链式法则是反向传播算法的基础,这样就可以通过分层的计算求得损失函数相对于每个参数的梯度。以下面的复合函数为例:

 其中 x 是输入数据,w 是权重,b 是偏置。

函数分解:

可以将该复合函数分解为:

链式求导:

x = torch.tensor(1.0)
w = torch.tensor(0.0,requires_grad =True)
b = torch.tensor(0.0,requires_grad =True)# 函数
y = (torch.exp(-(w*x+b)+1))**-1# 自动微分
y.backward()print(w.grad)

2.2.3 重要性

反向传播算法极大地提高了多层神经网络训练的效率,使得训练深度模型成为可能。通过链式法则逐层计算梯度,反向传播可以有效地处理复杂的网络结构,确保每一层的参数都能得到合理的调整。

2.2.4 案例

2.2.4.1 数据准备

整体网络结构及神经元数据和权重参数如下图所示:

2.2.4.2 神经元计算

2.2.4.3 损失计算

2.2.4.5 梯度计算

2.2.4.5 参数更新  

假设学习率是0.5

方式1:

import math# 前向传播
i1 = 0.05
i2 = 0.10
b1 = 0.35w1 = 0.15
w2 = 0.20w3 = 0.25
w4 = 0.30w5 = 0.40
w6 = 0.45w7 = 0.50
w8 = 0.55# 神经元h1
def h1():# 线性l1_1 = i1 * w1 + i2 * w2 + b1# 激活函数return 1 / (1 + math.exp(-l1_1))# 神经元h2
def h2():# 线性l1_2 = i1 * w3 + i2 * w4 + b1# 激活函数return 1 / (1 + math.exp(-l1_2))b2 = 0.60# 神经元o1
def o1(h1_val, h2_val):# 线性l2_1 = h1_val * w5 + h2_val * w6 + b2# 激活函数return 1 / (1 + math.exp(-l2_1))# 神经元o2
def o2(h1_val, h2_val):# 线性l2_2 = h1_val * w7 + h2_val * w8 + b2# 激活函数return 1 / (1 + math.exp(-l2_2))# 计算前向传播的结果
h1_val = h1()
h2_val = h2()
o1_val = o1(h1_val, h2_val)
o2_val = o2(h1_val, h2_val)print('h1:', h1_val)
print('h2:', h2_val)
print('o1:', o1_val)
print('o2:', o2_val)# 计算MSE损失
def mse(o1_val, o2_val):return 0.5 * ((o1_val - 0.01) ** 2 + (o2_val - 0.99) ** 2)print('MSE Loss:', mse(o1_val, o2_val))# 求w5的梯度 = mse()对o1求导  *  o1对l2_1求导  *  l2_1对w5求导
# dw5 = (o1 - 0.01) * [o1 * (1 - o1)] * h1
dw5 = (o1_val - 0.01) * (o1_val * (1.0 - o1_val)) * h1_val
print('dw5:', dw5)# 求w7的梯度 = mse()对o2求导  *  o2对l2_2求导  *  l2_2对w7求导
# dw7 = (o2 - 0.99) * [o2 * (1 - o2)] * h1
dw7 = (o2_val - 0.99) * (o2_val * (1.0 - o2_val)) * h1_val
print('dw7:', dw7)# 求w1的梯度 = mse()对o1求导  *  o1对l2_1求导  *  l2_1对h1求导 * h1对l1_1求导 *l1_1对w1求导 + mse()对o2求导  *  o2对l2_2求导  *  l2_2对h1求导 * h1对l1_1求导 *l1_1对w1求导
# dw1 = (o1() - 0.01) * [o1() * (1 - o1())] * w5 * [h1() * (1 - h1())] * i1 + (o2 - 0.99) * [o2 * (1 - o2)] *w7 * [h1() * (1 - h1())] * i1
dw1 = (o1_val - 0.01) * (o1_val * (1.0 - o1_val)) * w5 * h1_val*(1.0-h1_val) * 0.05 + (o2_val - 0.99) * (o2_val * (1.0 - o2_val)) * w7 *h1_val*(1.0-h1_val) * 0.05
print('dw1:', dw1)

方式2:

# 前向传播
i1_i2 = torch.tensor([0.05,0.10])model1 = nn.Linear(2,2)
model1.weight.data = torch.tensor([[0.15,0.20],[0.25,0.30]])
model1.bias.data = torch.tensor([0.35])
l11_l12 = model1(i1_i2)
h1_h2 =torch.sigmoid(l11_l12)model2 = nn.Linear(2,2)
model2.weight.data = torch.tensor([[0.40,0.45],[0.50,0.55]])
model2.bias.data = torch.tensor([0.60])
l21_l22 = model2(h1_h2)
o1_o2 = torch.sigmoid(l21_l22)# 反向传播
true_o1_o2 = torch.tensor([0.01,0.99])
mse = nn.MSELoss()
loss = mse(o1_o2,true_o1_o2)
print(loss)loss.backward()
print(model1.weight.grad)
print(model2.weight.grad)

方式3:

import torch
import torch.nn as nn
import torch.optim as optimclass Net(nn.Module):def __init__(self):super(Net,self).__init__()self.linear1 = nn.Linear(2,2)self.linear2 = nn.Linear(2,2)self.linear1.weight.data=torch.tensor([[0.15,0.20],[0.25,0.30]])self.linear2.weight.data=torch.tensor([[0.40,0.45],[0.50,0.55]])self.linear1.bias.data = torch.tensor([0.35], dtype=torch.float32)self.linear2.bias.data = torch.tensor([0.60], dtype=torch.float32)def forward(self,x):x = self.linear1(x)x = torch.sigmoid(x)x = self.linear2(x)x = torch.sigmoid(x)return xinput = torch.tensor([[0.05, 0.10]])
target = torch.tensor([[0.01, 0.99]])model = Net()
output = model(input)print(output)
mse = torch.sum((output-target)**2)/2
print(mse)optimizer = optim.SGD(model.parameters(), lr=0.5)
# 梯度清零
optimizer.zero_grad()mse .backward()print(model.linear1.weight.grad)
print(model.linear2.weight.grad)#更新梯度
optimizer.step()# 打印更新后的网络参数
print(model.state_dict())

2.3 BP之梯度下降

梯度下降算法的目标是找到使损失函数 L(\theta) 最小的参数 \theta,其核心是沿着损失函数梯度的负方向更新参数,以逐步逼近局部或全局最优解,从而使模型更好地拟合训练数据。

2.3.1 传统下降方式

2.3.1.1 批量梯度下降

Batch Gradient Descent 简称BGD

特点: 每次更新参数时,使用整个训练集来计算梯度。

优点

  • 收敛稳定,能准确地沿着损失函数的真实梯度方向下降。

  • 适用于小型数据集。

缺点

  • 对于大型数据集,计算量巨大,更新速度慢。

  • 需要大量内存来存储整个数据集。

公式

其中,m 是训练集样本总数,x^{(i)}, y^{(i)} 是第 i 个样本及其标签。

2.3.1.2 随机梯度下降

Stochastic Gradient Descent 简称SGD

特点:每次更新参数时,仅使用一个样本来计算梯度。

优点

  • 更新频率高,计算快,适合大规模数据集。

  • 能够跳出局部最小值,有助于找到全局最优解。

缺点

  • 收敛不稳定,容易震荡,因为每个样本的梯度可能都不完全代表整体方向。

  • 需要较小的学习率来缓解震荡。

公式

  其中,x^{(i)}, y^{(i)} 是当前随机抽取的样本及其标签。

2.3.1.3 小批量梯度下降

Mini-batch Gradient Descent 简称MGBD

特点:每次更新参数时,使用一小部分训练集(小批量)来计算梯度。

优点

  • 在计算效率和收敛稳定性之间取得平衡。

  • 能够利用向量化加速计算,适合现代硬件(如GPU)。

缺点

  • 选择适当的批量大小比较困难;批量太小则接近SGD,批量太大则接近批量梯度下降。

  • 通常会根据硬件算力设置为32\64\128\256等2的次方。

公式

2.3.2 存在的问题

  • 收敛速度慢:BGD和MBGD使用固定学习率,太大会导致震荡,太小又收敛缓慢。

  • 局部最小值和鞍点问题:SGD在遇到局部最小值或鞍点时容易停滞,导致模型难以达到全局最优。

  • 训练不稳定:SGD中的噪声容易导致训练过程中不稳定,使得训练陷入震荡或不收敛。

2.3.3 优化梯度下降方式

2.3.3.1 指数加权平均

指数移动加权平均(Exponential Moving Average简称EMA) 则是参考各数值,并且各数值的权重都不同,距离越远的数字对平均数计算的贡献就越小(权重较小),距离越近则对平均数的计算贡献就越大(权重越大)。

算数平均将所有数加起来除以数的个数,每个数的权重是相同的
加权平均给每个数赋予不同的权重求得平均数
移动平均计算最近邻的 N 个数来获得平均数

公式:

其中:

  • St 表示指数加权平均值(EMA);

  • Yt 表示 t 时刻的值;

  • \beta 是平滑系数,取值范围为 0\leq \beta < 1。\beta 越接近 1,表示对历史数据依赖性越高;越接近 0 则越依赖当前数据。该值越大平均数越平缓

import numpy as np
import matplotlib.pyplot as plt
import torchtemperature  =  np.array([10,10.5,11,11.2,11.3,12,12.1,12.6,12.4,13,13.8,13.91,14.0,13.6,14.9,15.21,15.64,16,16.89,17.9])def origial():# 每天的温度变化图days = np.arange(1,len(temperature)+1,1)plt.plot(days,temperature,color ='r')plt.scatter(days,temperature)plt.show()# Exponentail Moving Average
def ema(beta):'''bata:指数加权平均的平滑系数'''# ema_list存储处理后的数据ema_list=[]for index,value in enumerate(temperature):if index ==0:ema_list.append(value)else:# beta*(上一转换元素)+(1-beta)*(未转换的此元素)new_value = beta*ema_list[-1]+(1-beta)*valueema_list.append(new_value)days = np.arange(1,len(temperature)+1,1)plt.scatter(days,temperature)plt.plot(days,ema_list,color='r')plt.show()origial()
# bate值越大,图像越平缓
ema(0.5)
ema(0.9)

2.3.3.2 Momentum

特点:

动量(Momentum)是对梯度下降的优化方法,可以更好地应对梯度变化和梯度消失问题,从而提高训练模型的效率和稳定性。

  • 惯性效应: 该方法加入前面梯度的累积,这种惯性使得算法沿着当前的方向继续更新。如遇到鞍点,也不会因梯度逼近零而停滞。

  • 减少震荡: 该方法平滑了梯度更新,减少在鞍点附近的震荡,帮助优化过程稳定向前推进。

  • 加速收敛: 该方法在优化过程中持续沿着某个方向前进,能够更快地穿越鞍点区域,避免在鞍点附近长时间停留。

梯度计算公式:

Dt = β * St-1 + (1- β) * Dt

  • St-1 表示历史梯度移动加权平均值

  • wt 表示当前时刻的梯度值

  • β 为权重系数

原理:

Monmentum 优化方法是如何一定程度上克服 “平缓”、”鞍点”、”峡谷” 的问题呢?

当处于鞍点位置时,由于当前的梯度为 0,参数无法更新。但是 Momentum 动量梯度下降算法已经在先前积累了一些梯度值,很有可能使得跨过鞍点。

由于 mini-batch 普通的梯度下降算法,每次选取少数的样本梯度确定前进方向,可能会出现震荡,使得训练时间变长。Momentum 使用移动加权平均,平滑了梯度的变化,使得前进方向更加平缓,有利于加快训练过程。一定程度上有利于降低 “峡谷” 问题(就是会使得参数更新出现剧烈震荡)的影响。

API :

optimizer = optim.SGD(model.parameters(), lr, momentum)  

momentum (动量系数)通常设置为 0 到0.5 之间的一个值,也可根据具体的应用场景调整。

总结

  • 动量项更新:利用当前梯度和历史动量来计算新的动量项。

  • 权重参数更新:利用更新后的动量项来调整权重参数。

  • 梯度计算:在每个时间步计算当前的梯度,用于更新动量项和权重参数。

  • Momentum 算法是对梯度值的平滑调整,但是并没有对梯度下降中的学习率进行优化

import torch
import torch.nn as nn
import torch.optim as optimclass Net(nn.Module):def __init__(self):super(Net,self).__init__()# 输入层self.linear1 = nn.Linear(2,2)self.linear1.weight.data=torch.tensor([[0.15,0.20],[0.25,0.30]])self.linear1.bias.data = torch.tensor([0.35], dtype=torch.float32)# 输出层self.linear2 = nn.Linear(2,2)self.linear2.weight.data=torch.tensor([[0.40,0.45],[0.50,0.55]])self.linear2.bias.data = torch.tensor([0.60], dtype=torch.float32)self.activation = nn.Sigmoid()def forward(self,input):x = self.linear1(input)x = self.activation(x)x = self.linear2(x)output = self.activation(x)return outputdef backward():model = Net()optimizer = optim.SGD(model.parameters(),lr=1,momentum=0.5)for epoch in range(100):input = torch.tensor([0.05,0.10])true  = torch.tensor([0.01,0.99])predict = model.forward(input)mse = nn.MSELoss()loss = mse(predict,true)print(f"{epoch}",loss)optimizer.zero_grad()loss.backward()optimizer.step()backward()
2.3.3.3 AdaGrad

自适应梯度算法 AdaGrad(Adaptive Gradient Algorithm)为每个参数引入独立的学习率,它根据历史梯度的平方和来调整这些学习率,这样就使得参数具有较大的历史梯度的学习率减小,而参数具有较小的历史梯度的学习率保持较大,从而实现更有效的学习。AdaGrad避免了统一学习率的不足,更多用于处理稀疏数据和梯度变化较大的问题。

AdaGrad流程:

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

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

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

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

(5)学习率 α 的计算公式如下:

(6)参数更新公式如下:

其中:

  • \alpha 是全局的初始学习率。

  • \sigma 是一个非常小的常数,用于避免除零操作(通常取 10^{-8})。

  • \frac{\alpha}{\sqrt{s }+\sigma} 是自适应调整后的学习率

API: 

optimizer = optim.Adagrad(model.parameters(), lr)  

import torch
import torch.nn as nn
import torch.optim as optimclass Net(nn.Module):def __init__(self):super(Net,self).__init__()# 输入层self.linear1 = nn.Linear(2,2)self.linear1.weight.data=torch.tensor([[0.15,0.20],[0.25,0.30]])self.linear1.bias.data = torch.tensor([0.35], dtype=torch.float32)# 输出层self.linear2 = nn.Linear(2,2)self.linear2.weight.data=torch.tensor([[0.40,0.45],[0.50,0.55]])self.linear2.bias.data = torch.tensor([0.60], dtype=torch.float32)self.activation = nn.Sigmoid()def forward(self,input):x = self.linear1(input)x = self.activation(x)x = self.linear2(x)output = self.activation(x)return outputdef backward():model = Net()optimizer = optim.Adagrad(model.parameters(),lr=1)for epoch in range(100):input = torch.tensor([0.05,0.10])true  = torch.tensor([0.01,0.99])predict = model.forward(input)mse = nn.MSELoss()loss = mse(predict,true)print(f"{epoch}",loss)optimizer.zero_grad()loss.backward()optimizer.step()backward()
2.3.3.4 RMSProp

均方根传播 RMSProp(Root Mean Square Propagation)在时间步中,不是简单地累积所有梯度平方和,而是使用指数加权平均来逐步衰减过时的梯度信息。这种方法专门用于解决AdaGrad在训练过程中学习率过度衰减的问题。

RMSProp过程

(1)初始化学习率 α、初始化参数 θ、小常数 σ = 1e-8( 用于防止除零操作(通常取 10^{-8} ))。

(2)初始化参数 θ

(3)初始化梯度累计变量 s=0

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

(5)使用指数移动平均累积历史梯度,公式如下:

(6)学习率 α 的计算公式如下:

(7)参数更新公式如下:

API:

optimizer = optim.RMSprop(model.parameters(), lr, momentum)  

import torch
import torch.nn as nn
import torch.optim as optimclass Net(nn.Module):def __init__(self):super(Net,self).__init__()# 输入层self.linear1 = nn.Linear(2,2)self.linear1.weight.data=torch.tensor([[0.15,0.20],[0.25,0.30]])self.linear1.bias.data = torch.tensor([0.35], dtype=torch.float32)# 输出层self.linear2 = nn.Linear(2,2)self.linear2.weight.data=torch.tensor([[0.40,0.45],[0.50,0.55]])self.linear2.bias.data = torch.tensor([0.60], dtype=torch.float32)self.activation = nn.Sigmoid()def forward(self,input):x = self.linear1(input)x = self.activation(x)x = self.linear2(x)output = self.activation(x)return outputdef backward():model = Net()optimizer = optim.RMSprop(model.parameters(),lr=0.01,momentum=0.5)for epoch in range(100):input = torch.tensor([0.05,0.10])true  = torch.tensor([0.01,0.99])predict = model.forward(input)mse = nn.MSELoss()loss = mse(predict,true)print(f"{epoch}",loss)optimizer.zero_grad()loss.backward()optimizer.step()backward()
2.3.3.5 Adam

自适应矩估计 Adam(Adaptive Moment Estimation)算法将动量法和RMSProp的优点结合在一起:

  • 动量法:通过一阶动量(即梯度的指数加权平均)来加速收敛,尤其是在有噪声或梯度稀疏的情况下。

  • RMSProp:通过二阶动量(即梯度平方的指数加权平均)来调整学习率,使得每个参数的学习率适应其梯度的变化。

  • Momentum 使用指数加权平均计算当前的梯度值、AdaGrad、RMSProp 使用自适应的学习率,Adam 结合了 Momentum、RMSProp 的优点,使用:移动加权平均的梯度和移动加权平均的学习率。使得能够自适应学习率的同时,也能够使用 Momentum 的优点。

 API:

optimizer = optim.Adam(model.parameters(), lr)  

import torch
import torch.nn as nn
import torch.optim as optimclass Net(nn.Module):def __init__(self):super(Net,self).__init__()# 输入层self.linear1 = nn.Linear(2,2)self.linear1.weight.data=torch.tensor([[0.15,0.20],[0.25,0.30]])self.linear1.bias.data = torch.tensor([0.35], dtype=torch.float32)# 输出层self.linear2 = nn.Linear(2,2)self.linear2.weight.data=torch.tensor([[0.40,0.45],[0.50,0.55]])self.linear2.bias.data = torch.tensor([0.60], dtype=torch.float32)self.activation = nn.Sigmoid()def forward(self,input):x = self.linear1(input)x = self.activation(x)x = self.linear2(x)output = self.activation(x)return outputdef backward():model = Net()optimizer = optim.Adam(model.parameters(),lr=0.01)for epoch in range(100):input = torch.tensor([0.05,0.10])true  = torch.tensor([0.01,0.99])predict = model.forward(input)mse = nn.MSELoss()loss = mse(predict,true)print(f"{epoch}",loss)optimizer.zero_grad()loss.backward()optimizer.step()backward()

2.3.4 总结

梯度下降算法通过不断更新参数来最小化损失函数,是反向传播算法中计算权重调整的基础。在实际应用中,根据数据的规模和计算资源的情况,选择合适的梯度下降方式(批量、随机、小批量)及其变种(如动量法、Adam等)可以显著提高模型训练的效率和效果。

Adam是目前最为流行的优化算法之一,因其稳定性和高效性,广泛应用于各种深度学习模型的训练中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/482390.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android】组件化嘻嘻嘻gradle耶耶耶

文章目录 Gradle基础总结&#xff1a;gradle-wrapper项目根目录下的 build.gradlesetting.gradle模块中的 build.gradlelocal.properties 和 gradle.properties 组件化&#xff1a;项目下新建一个Gradle文件定义一个ext扩展区域config.gradle全局基础配置&#xff08;使用在项目…

基础Web安全|SQL注入

基础Web安全 URI Uniform Resource Identifier&#xff0c;统一资源标识符&#xff0c;用来唯一的标识一个资源。 URL Uniform Resource Locator&#xff0c;统一资源定位器&#xff0c;一种具体的URI&#xff0c;可以标识一个资源&#xff0c;并且指明了如何定位这个资源…

【插入排序】:直接插入排序、二分插入排序、shell排序

【插入排序】&#xff1a;直接插入排序、二分插入排序、shell排序 1. 直接插入排序1.1 详细过程1.2 代码实现 2. 二分插入排序2.1 详细过程2.2 代码实现 3. shell排序3.1 详细过程3.2 代码实现 1. 直接插入排序 1.1 详细过程 1.2 代码实现 public static void swap(int[]arr,…

一万台服务器用saltstack还是ansible?

一万台服务器用saltstack还是ansible? 选择使用 SaltStack 还是 Ansible 来管理一万台服务器&#xff0c;取决于几个关键因素&#xff0c;如性能、扩展性、易用性、配置管理需求和团队的熟悉度。以下是两者的对比分析&#xff0c;帮助你做出决策&#xff1a; SaltStack&…

通讯专题4.1——CAN通信之计算机网络与现场总线

从通讯专题4开始&#xff0c;来学习CAN总线的内容。 为了更好的学习CAN&#xff0c;先从计算机网络与现场总线开始了解。 1 计算机网络体系的结构 在我们生活当中&#xff0c;有许多的网络&#xff0c;如交通网&#xff08;铁路、公路等&#xff09;、通信网&#xff08;电信、…

使用OSPF配置不同进程的中小型网络

要求&#xff1a; 给每个设备的接口配置好相应的地址 对进程1的各区域使用认证&#xff0c;认证为明文发送&#xff0c;明文保存 对骨干区域使用接口认证&#xff0c;非骨干区域使用区域认证 其他ospf进程均使用区域0 FW1上配置接口信任域和非信任域和服务器&#xff0c…

软考高项经验分享:我的备考之路与实战心得

软考&#xff0c;尤其是信息系统项目管理师&#xff08;高项&#xff09;考试&#xff0c;对于众多追求职业提升与专业认可的人士来说&#xff0c;是一场充满挑战与机遇的征程。我在当年参加软考高项的经历&#xff0c;可谓是一波三折&#xff0c;其中既有成功的喜悦&#xff0…

Transformers在计算机视觉领域中的应用【第1篇:ViT——Transformer杀入CV界之开山之作】

目录 1 模型结构2 模型的前向过程3 思考4 结论 论文&#xff1a; AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE 代码&#xff1a;https://github.com/google-research/vision_transformer Huggingface&#xff1a;https://github.com/huggingf…

Unity3D模型场景等测量长度和角度功能demo开发

最近项目用到多段连续测量物体长度和角度功能&#xff0c;自己研究了下。 1.其中向量角度计算&#xff1a; 需要传入三个坐标来进行计算。三个坐标确定两条向量线段的方向&#xff0c;从而来计算夹角。 public Vector3 SetAngle(Vector3 p1, Vector3 p2,Vector3 p3) { …

蓝桥杯第 23 场 小白入门赛

一、前言 好久没打蓝桥杯官网上的比赛了&#xff0c;回来感受一下&#xff0c;这难度区分度还是挺大的 二、题目总览 三、具体题目 3.1 1. 三体时间【算法赛】 思路 额...签到题 我的代码 // Problem: 1. 三体时间【算法赛】 // Contest: Lanqiao - 第 23 场 小白入门赛 …

从0开始学PHP面向对象内容之常用设计模式(享元)

二、结构型设计模式 7、享元模式&#xff08;Flyweight Pattern&#xff09; 这里是引用享元模式&#xff08;Flyweight Pattern&#xff09; 是一种结构型设计模式&#xff0c;旨在通过共享对象来减少内存使用&#xff0c;尤其适用于大量相似对象的场景。通过共享和重用对象的…

YOLO 标注工具 AutoLabel 支持 win mac linux

常见的标注工具&#xff0c;功能基础操作繁琐&#xff0c;无复制粘贴&#xff0c;标签无法排序修改&#xff0c;UI不美观&#xff0c;bug修正不及时&#xff0c;没有集成识别、训练、模型导出… 怎么办呢&#xff1f;AutoLabel它来了 Quick Start 一图胜千言 图像标注 支持YOL…

《Python基础》之Python中可以转换成json数据类型的数据

目录 一、JSON简介 JSON有两种基本结构 1、对象&#xff08;Object&#xff09; 2、数组&#xff08;Array&#xff09; 二、将数据装换成json数据类型方法 三、在Python中&#xff0c;以下数据类型可以直接转换为JSON数据类型 1、字典&#xff08;Dictionary&#xff09…

如何在Bash中等待多个子进程完成,并且当其中任何一个子进程以非零退出状态结束时,使主进程也返回一个非零的退出码?

文章目录 问题回答参考 问题 如何在 Bash 脚本中等待该脚本启动的多个子进程完成&#xff0c;并且当这其中任意一个子进程以非零退出码结束时&#xff0c;让该脚本也返回一个非零的退出码&#xff1f; 简单的脚本: #!/bin/bash for i in seq 0 9; docalculations $i & d…

远程桌面协助控制软件 RustDesk v1.3.3 多语言中文版

RustDesk 是一款开源的远程桌面软件&#xff0c;支持多平台操作&#xff0c;包括Windows、macOS、Linux、iOS、Android和Web。它提供端到端加密和基于角色的访问控制&#xff0c;确保安全性和隐私保护。使用简单&#xff0c;无需复杂配置&#xff0c;通过输入ID和密码即可快速连…

LWIP和FATFS 实现 FTP 服务端

目录 一、前言 二、LWIP 和 FTP 简介 1.LWIP 2.FTP 三、实现 FTP 服务端的主要步骤 1.初始化 LWIP 2.创建 FTP 服务器任务 3.处理客户端连接 4.实现 FTP 命令处理 5.文件系统操作 6.错误处理和日志记录 四、示例代码 1.创建FTP任务 2. FTP任务代码 3.处理交互数据…

多线程篇-8--线程安全(死锁,常用保障安全的方法,安全容器,原子类,Fork/Join框架等)

1、线程安全和不安全定义 &#xff08;1&#xff09;、线程安全 线程安全是指一个类或方法在被多个线程访问的情况下可以正确得到结果&#xff0c;不会出现数据不一致或其他错误行为。 线程安全的条件 1、原子性&#xff08;Atomicity&#xff09; 多个操作要么全部完成&a…

【css实现收货地址下边的平行四边形彩色线条】

废话不多说&#xff0c;直接上代码&#xff1a; <div class"address-block" ><!-- 其他内容... --><div class"checked-ar"></div> </div> .address-block{height:120px;position: relative;overflow: hidden;width: 500p…

【Python网络爬虫笔记】5-(Request 带参数的get请求) 爬取豆瓣电影排行信息

目录 1.抓包工具查看网站信息2.代码实现3.运行结果 1.抓包工具查看网站信息 请求路径 url:https://movie.douban.com/typerank请求参数 页面往下拉&#xff0c;出现新的请求结果&#xff0c;参数start更新&#xff0c;每次刷新出20条新的电影数据 2.代码实现 # 使用网络爬…

「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历

本篇将带你实现一个简易日历应用&#xff0c;显示当前月份的日期&#xff0c;并支持选择特定日期的功能。用户可以通过点击日期高亮选中&#xff0c;还可以切换上下月份&#xff0c;体验动态界面的交互效果。 关键词 UI互动应用简易日历动态界面状态管理用户交互 一、功能说明…