1.梯度下降:
梯度下降是一种用于最小化损失函数的优化算法。在机器学习中,我们经常需要找到最小化损失函数的参数,以使我们的模型能够更好地拟合数据。
具体来说,假设我们有一个损失函数L(w),其中w是我们需要寻找的参数向量。我们的目标是找到一个w,使得L(w)最小化。为了实现这一目标,我们可以使用梯度下降算法。
梯度下降算法的核心思想是,我们可以通过计算损失函数对参数w的偏导数来确定损失函数下降最快的方向。我们沿着这个方向对w进行更新,以逐步接近损失函数的最小值。
具体来说,梯度下降的更新公式如下:
w = w - α * ∇L(w)
其中,α是我们称之为学习率的超参数,控制我们每次更新参数的步长。∇L(w)表示损失函数L(w)对w的梯度,是一个向量,其方向指向损失函数下降最快的方向。我们通过计算损失函数在当前参数值处的梯度来确定每次更新参数的方向。
梯度下降算法的一般流程如下:
初始化参数向量w的值。
计算当前参数值下的损失函数L(w)。
计算损失函数对参数w的梯度 ∇L(w)。
根据梯度下降公式更新参数w的值:w = w - α * ∇L(w)。
重复执行步骤2-4,直到达到收敛条件。
梯度下降算法的优点是,它是一种通用的优化算法,适用于各种不同的损失函数和模型。同时,梯度下降算法也可以方便地应用于大规模数据集,因为每次迭代只需要计算一小部分数据的梯度。
2.反向传播
反向传播(Backpropagation)是一种用于训练人工神经网络的优化算法,它可以计算代价函数关于权重和偏差的梯度,进而对神经网络的权重和偏差进行更新。它是一种基于梯度下降的算法,通过反向传播算法可以计算神经网络中每个权重和偏差对代价函数的影响,进而使用梯度下降算法来最小化代价函数,以提高神经网络的性能。
反向传播算法的核心思想是利用链式法则(Chain Rule)来计算代价函数关于每个权重和偏差的梯度。具体地,反向传播算法的流程如下:
前向传播:将输入数据通过神经网络进行正向传递,直到得到输出结果。
计算代价函数的梯度:计算代价函数关于输出结果的梯度,即反向传播的起点。
反向传播:从输出层开始,利用链式法则将梯度向前传递,计算代价函数关于每个权重和偏差的梯度。
更新权重和偏差:根据梯度下降算法的更新规则,更新神经网络中每个权重和偏差的值。
在反向传播算法中,通过计算每个权重和偏差对代价函数的偏导数,以及利用链式法则来计算代价函数对每个中间节点输出的偏导数,我们可以逐层向后传递梯度,直到计算出代价函数关于输入数据的梯度,从而对神经网络进行更新。
反向传播算法是神经网络训练的核心算法之一,可以在大量的数据和强大的计算能力下,通过反复迭代调整神经网络中的权重和偏差,以使神经网络能够更好地适应数据,提高其性能。
3.计算图
计算图是一种图形化表示计算的方法。在计算图中,每个计算步骤被表示为节点,节点之间的边表示它们之间的依赖关系。通过将计算过程可视化为计算图,可以更清晰地理解计算的流程以及其中的依赖关系。
在深度学习中,计算图是一种重要的概念。神经网络模型通常由多个层组成,每一层由许多神经元组成,每个神经元都包含权重和偏置。在前向传播过程中,输入数据流经每个层和神经元,并且通过这些权重和偏置产生输出。在反向传播过程中,需要计算权重和偏置的梯度,以便进行参数更新。
通过将神经网络表示为计算图,可以更轻松地计算每个节点(神经元)的梯度,并使用链式法则来计算整个网络的梯度。计算图的节点表示每个神经元的输出,每个节点的梯度表示该神经元的梯度。通过从输出层向输入层传播梯度,可以计算每个节点的梯度,并使用梯度下降算法进行参数更新。
4.例题
5.使用PyTorch的Backward()编程实现例题
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(in_channels=2, out_channels=2, kernel_size=1, padding=0, bias=False)
self.conv2 = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=1, padding=0, bias=False)
def forward(self, z):
return self.conv2(self.conv1(z))
c = 2
h = 5
w = 5
lr = 0.01
inputs = torch.arange(0, c * h * w).float().view(1, c, h, w)
model = MyModel()
outputs = model(inputs)
loss = outputs.sum()
model.zero_grad()
grad = torch.autograd.grad(loss, model.parameters(), retain_graph=True)
for i, (name, param) in enumerate(model.named_parameters()):
print("******************")
print(name)
print("grad using loss.backward: ", param.grad.data)
print("grad using autograd.grad: ", grad[i])
print("******************")
# theta_1 = theta_0 - lr * grad
param.data.sub_(lr * param.grad.data)