目录
loss_fn = nn.MSELoss(reduction='sum')
for param in model.parameters(): param -= learning_rate * param.grad # 模型中所有的参数更新
import torch
import torch.nn as nn # 各种定义 neural network 的方法
import matplotlib.pyplot as plt
N, D_in, H, D_out = 64, 1000, 100, 10 # 64个训练数据(只是一个batch),输入是1000维,hidden是100维,输出是10维
'''随机创建一些训练数据'''
X = torch.randn(N, D_in)
y = torch.randn(N, D_out)
model = torch.nn.Sequential(
torch.nn.Linear(D_in, H, bias=True), # W1 * X + b,默认True
torch.nn.ReLU(),
torch.nn.Linear(H, D_out)
)
# model = model.cuda() #这是使用GPU的情况
loss_fn = nn.MSELoss(reduction='sum')
all_loss = []
learning_rate = 1e-4
for t in range(500): # 做500次迭代
'''前向传播(forward pass)'''
y_hat = model(X) # model(X) = model.forward(X), N * D_out
'''计算损失函数(compute loss)'''
loss = loss_fn(y_hat, y) # 均方误差,忽略了÷N,loss就是一个计算图(computation graph)
print("Epoch:{} Loss:{}".format(t, loss.item())) # 打印每个迭代的损失
all_loss.append(loss.item())
'''后向传播(backward pass)'''
loss.backward()
'''参数更新(update weights of W1 and W2)'''
with torch.no_grad():
for param in model.parameters():
param -= learning_rate * param.grad # 模型中所有的参数更新
model.zero_grad()
plt.plot(all_loss)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()
torch.nn
torch.nn
是PyTorch的一个子库,提供了神经网络构建的基本组件。它包括一系列预定义的层,损失函数,优化器等,用于简化深度学习模型的开发和训练。
以下是torch.nn
中一些主要的组件:
-
层(Layers): 例如线性层(
nn.Linear
),卷积层(nn.Conv2d
),激活函数(例如nn.ReLU
),正则化层等。这些都是用于构建神经网络架构的基本组件。 -
损失函数(Loss Functions): 例如均方误差损失(
nn.MSELoss
),交叉熵损失(nn.CrossEntropyLoss
)等。损失函数用于衡量模型的预测与实际目标之间的差异,并在训练过程中进行优化。 -
容器(Containers): 如
nn.Sequential
,用于封装一系列层,使它们可以作为一个整体运行。 -
正则化和归一化层(Normalization Layers): 如批量归一化(
nn.BatchNorm2d
),用于改善训练过程的稳定性和性能。 -
优化器(Optimizers): 虽然优化器通常位于
torch.optim
中,但它们与torch.nn
紧密协同工作,用于根据计算的梯度更新模型的权重。 -
工具和工具函数(Utilities and Utility Functions): 如
nn.utils.clip_grad_norm_
,用于裁剪梯度,防止训练过程中的梯度爆炸等问题。
当使用PyTorch的torch.nn.Linear
或其他层创建网络时,权重(和偏置,如果有的话)通常会自动初始化。
model = torch.nn.Sequential(
torch.nn.Linear(D_in, H, bias=True), # W1 * X + b,默认True
torch.nn.ReLU(),
torch.nn.Linear(H, D_out)
)
这段代码使用PyTorch的torch.nn
模块构建了一个简单的前馈神经网络(Feed-Forward Neural Network),并将其组装为一个顺序模型(Sequential model)。以下是代码的解释:
-
torch.nn.Sequential
: 通过把多个模块串联在一起,来构建一个整体的网络。数据按顺序通过定义的每一层。 -
torch.nn.Linear(D_in, H, bias=True)
: 这是一个全连接(线性)层,接受D_in
大小的输入,有H
个隐藏单元,并输出H
大小的结果。bias=True
表示该层包括偏置项。 -
torch.nn.ReLU()
: 这是一个ReLU(Rectified Linear Unit)激活函数。它会对上一层的输出应用ReLU激活函数,该函数将所有负数值设置为0。 -
torch.nn.Linear(H, D_out)
: 这是另一个全连接层,接受H
大小的输入(与上一层的输出相匹配),并输出D_out
大小的结果。
loss_fn = nn.MSELoss(reduction='sum')
这段代码定义了一个均方误差(Mean Squared Error, MSE)损失函数,并设置了reduction='sum'
参数。
解释如下:
-
nn.MSELoss()
: 在PyTorch中,nn.MSELoss
创建了一个均方误差损失对象。这种损失通常用于回归问题,衡量模型预测值与实际目标值之间的平均平方差异。 -
reduction='sum'
: 默认情况下,MSE损失计算一个批次中每个样本的损失,并将其平均。设置reduction='sum'
会改变这个行为,将一个批次中所有样本的损失相加,而不是取平均。
for param in model.parameters():
param -= learning_rate * param.grad # 模型中所有的参数更新
-
model.parameters()
: 这是一个迭代器,返回模型中所有的可训练参数(权重和偏置)。在你之前定义的Sequential
模型中,这将包括两个全连接层的权重和偏置。 -
param -= learning_rate * param.grad
: 这是梯度下降的核心更新步骤。每个参数(param
)根据其梯度(param.grad
)和学习率(learning_rate
)进行更新。学习率是一个超参数,控制更新的步长。梯度方向指向损失函数在当前参数位置的最陡增长方向,所以减去梯度实现了沿损失函数下降方向的移动。
model.zero_grad()
model.zero_grad()
是PyTorch中的一个方法,用于将模型所有参数的梯度设置为0。在进行下一次前向和反向传播之前,通常需要调用此方法。
在训练神经网络时,梯度是累积的,即每次调用.backward()
时,梯度会累积在现有梯度之上。因此,如果不将梯度清零,下一次的梯度计算将会与上一次的梯度叠加,导致错误的更新。
通过调用model.zero_grad()
,可以确保每一次迭代的梯度计算都是从零开始的,不受前一次迭代梯度计算的影响,从而确保正确的训练过程。