Pytorch学习笔记05----损失函数与优化器

  在前文,我们初步完成了梯度下降算法求解线性回归问题的实例。在这个过程中,我们自己定义了损失函数和权重的更新,其实 PyTorch 也为我们直接定义了相应的工具包,使我们能够简洁快速的实现损失函数、权重的更新和梯度的求解。

import torch
import torch.nn as nn

一、模型的内置函数

1.损失函数 torch.nn.MSELoss()

  在Pytorch中的torch.nn中封装了很多损失函数,避免了我们手动定义损失函数,如均方差损失:torch.nn.MSELoss()
首先,我们把需要的变量和数据集定义出来:

#初始化数据集
X=torch.tensor([1,2,3,4],dtype=torch.float32)
Y=torch.tensor([2,4,6,8],dtype=torch.float32)
w=torch.tensor(0.0,dtype=torch.float32,requires_grad=True)

def forward(x):
  #正向传播函数
  return w*x

#测试代码:w是0,前向推导的结果也应该是0
pre=forward(X)
pre

输出结果如下:

tensor([0., 0., 0., 0.], grad_fn=<MulBackward0>)

接下来,让我们通过 nn.MSELoss() 计算此时预测值和真实值之间的损失:

loss=nn.MSELoss()
loss(forward(X),Y)

输出结果如下:

tensor(30., grad_fn=<MseLossBackward0>)

2.优化器 torch.optim

  优化器可以理解为一种利用梯度下降算法自动求解所需参数的工具包。在 PyTorch 中提供了 torch.optim 方法优化我们的模型。 torch.optim 工具包中存在着各种梯度下降的改进算法,比如 SGDMomentumRMSPropAdam 等。这些算法都是以传统梯度下降算法为基础,提出的改进算法,这些算法可以更快更准确地求解最佳模型参数。
我们可以通过下面方式定义一个 SGD 优化器:

optimizer = torch.optim.SGD([w], lr=learning_rate)

其中第一个参数,表示的是损失函数中的权重,即我们需要求取的值。 l r lr lr 表示的是梯度下降的步长。

由于一般的模型都是复杂的多元函数,每次使用梯度下降算法时,我们都需要手动的对每个变量进行更新,这无疑是非常繁琐的。而使用优化器,我们可以一次性对所有的变量进行更新。函数如下:

optimizer.step() :对模型(神经网络)中的参数进行更新,即所有参数值向梯度相反方向走一步。
optimizer.zero_grad() :对损失函数的相关变量进行梯度的清空。
综上,让我们完整的进行一次线性回归的求解。

首先,定义损失函数和优化器:

# 定义损失和优化器
learning_rate = 0.01
n_iters = 100
loss = nn.MSELoss()
optimizer = torch.optim.SGD([w], lr=learning_rate)
optimizer

输出结果如下:

SGD (
Parameter Group 0
    dampening: 0
    lr: 0.01
    momentum: 0
    nesterov: False
    weight_decay: 0
)

接下来,根据正向传播结果,更新梯度,进而更新权重值:

# 模型的训练过程
for epoch in range(n_iters):
    y_predicted = forward(X)
    # 计算损失
    l = loss(Y, y_predicted)
    # 计算梯度
    l.backward()
    # 更新权重,即向梯度方向走一步
    optimizer.step()
    # 清空梯度
    optimizer.zero_grad()

    if epoch % 10 == 0:
        print('epoch ', epoch+1, ': w = ', w, ' loss = ', l)

print(f'根据训练模型预测,当 x =5 时,y 的值为: {forward(5):.3f}')

输出结果如下:

epoch  1 : w =  tensor(0.3000, requires_grad=True)  loss =  tensor(30., grad_fn=<MeanBackward0>)
epoch  11 : w =  tensor(1.6653, requires_grad=True)  loss =  tensor(1.1628, grad_fn=<MeanBackward0>)
epoch  21 : w =  tensor(1.9341, requires_grad=True)  loss =  tensor(0.0451, grad_fn=<MeanBackward0>)
epoch  31 : w =  tensor(1.9870, requires_grad=True)  loss =  tensor(0.0017, grad_fn=<MeanBackward0>)
epoch  41 : w =  tensor(1.9974, requires_grad=True)  loss =  tensor(6.7705e-05, grad_fn=<MeanBackward0>)
epoch  51 : w =  tensor(1.9995, requires_grad=True)  loss =  tensor(2.6244e-06, grad_fn=<MeanBackward0>)
epoch  61 : w =  tensor(1.9999, requires_grad=True)  loss =  tensor(1.0176e-07, grad_fn=<MeanBackward0>)
epoch  71 : w =  tensor(2.0000, requires_grad=True)  loss =  tensor(3.9742e-09, grad_fn=<MeanBackward0>)
epoch  81 : w =  tensor(2.0000, requires_grad=True)  loss =  tensor(1.4670e-10, grad_fn=<MeanBackward0>)
epoch  91 : w =  tensor(2.0000, requires_grad=True)  loss =  tensor(5.0768e-12, grad_fn=<MeanBackward0>)
根据训练模型预测,当 x =5 时,y 的值为: 10.000

  这里我们进行了 100 次的迭代,可以发现得到的权重 ω \omega ω和实际值相同,损失无限接近于 0 。

二、模型的建立

  除了梯度的求解、权重的更新和梯度的清空外,PyTorch 实际上还为我们提供了模型的定义。也就是说,我们不用手动定义 forward 函数了。PyTorch 中为我们提供了预定义模型,可以直接使用。如 torch.nn.Linear(input_size, output_size) 表示线性函数模型。

input_size:输入数据的维度
output_size:输出数据的维度

总结一下,我们可以将一个线性问题的求解分为下面三个步骤:

1.定义模型(即正向传播函数)。
2.定义损失和优化器。
3.模型的训练(正向传播、反向传播、更新梯度、梯度下降、循环)。

1.定义线性模型 Linear

首先,让我们利用 PyTorch 定义线性函数模型:

# 由于使用 PyTorch ,因此所有的变量都为张量
X = torch.tensor([[1], [2], [3], [4]], dtype=torch.float32)
Y = torch.tensor([[2], [4], [6], [8]], dtype=torch.float32)
X_test = torch.tensor([5], dtype=torch.float32)

# 1. 定义模型
n_samples, n_features = X.shape
# 这里输入和输出的维度相同
model = nn.Linear(n_features, n_features)
model

输出结果如下:

Linear(in_features=1, out_features=1, bias=True)

2.定义优化器和损失函数

  在模型训练时,我们可以直接利用 model(x)作为模型的正向传播,该函数返回数据 x x x的预测结果。

# 2. 定义优化器和损失函数
learning_rate = 0.1
n_iters = 100

loss = nn.MSELoss()
# 在定义优化器时,直接利用 model.parameters() 表示模型中所有需要求的权重
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
optimizer

输出结果如下:

SGD (
Parameter Group 0
    dampening: 0
    lr: 0.1
    momentum: 0
    nesterov: False
    weight_decay: 0
)

3.模型的训练

  最后,我们就可以利用上面定义的模型、优化器和损失函数进行模型的训练了(即利用梯度下降算法,求解损失最小时的权重值):

# 3. 模型的训练,固定的步骤:正向传播、计算损失、反向传播、更新权重、梯度清空
for epoch in range(n_iters):
    # 正向传播
    y_predicted = model(X)
    # 损失
    l = loss(Y, y_predicted)
    # 反向传播
    l.backward()
    # 更新权重
    optimizer.step()
    # 清空梯度
    optimizer.zero_grad()

    if epoch % 10 == 0:
        [w, b] = model.parameters()  # unpack parameters
        print('epoch ', epoch+1, ': w = ', w[0][0].item(), ' loss = ', l)

print(f'根据训练模型预测,当 x =5 时,y 的值为:', forward(X_test))

输出结果如下:

epoch  1 : w =  2.7811810970306396  loss =  tensor(16.4686, grad_fn=<MeanBackward0>)
epoch  11 : w =  1.9356615543365479  loss =  tensor(0.0154, grad_fn=<MeanBackward0>)
epoch  21 : w =  1.940834641456604  loss =  tensor(0.0054, grad_fn=<MeanBackward0>)
epoch  31 : w =  1.9561294317245483  loss =  tensor(0.0030, grad_fn=<MeanBackward0>)
epoch  41 : w =  1.967624545097351  loss =  tensor(0.0016, grad_fn=<MeanBackward0>)
epoch  51 : w =  1.9761104583740234  loss =  tensor(0.0009, grad_fn=<MeanBackward0>)
epoch  61 : w =  1.9823722839355469  loss =  tensor(0.0005, grad_fn=<MeanBackward0>)
epoch  71 : w =  1.9869927167892456  loss =  tensor(0.0003, grad_fn=<MeanBackward0>)
epoch  81 : w =  1.990402102470398  loss =  tensor(0.0001, grad_fn=<MeanBackward0>)
epoch  91 : w =  1.992917776107788  loss =  tensor(7.6951e-05, grad_fn=<MeanBackward0>)
根据训练模型预测,当 x =5 时,y 的值为: tensor([[9.9731]], grad_fn=<MulBackward0>)

三、总结


模型训练的步骤是固定的:
1.利用 nn.Linear 定义模型。
2.利用 nn.MSELoss 定义损失。
3.利用 torch.optim 定义优化器。
4.利用梯度下降算法进行模型的训练。


模型的训练步骤也是固定的:
1.利用 model(X) 进行正向传播。
2.利用 loss(Y, y_predicted) 计算模型损失。
3.利用 loss.backward() 计算模型梯度。
4.利用 optimizer.step() 更新权重。
5.利用 optimizer.zero_grad() 清空梯度。
6.重复 1-5 的操作。
  因此,使用 PyTorch 可以大大的简化我们的编程难度。我们只需要改变模型的形式、损失函数的形式、优化器的形式以及各个参数的值,就能够训练出不同的模型,进而解决不同的深度学习问题了。


  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Pytorch是机学习中的一个重要框架,它与TensorFlow一起被认为是机学习的两大框架。Pytorch学习可以从以下几个方面入手: 1. Pytorch基本语法:了解Pytorch的基本语法和操作,包括张量(Tensors)的创建、导入torch库、基本运算等\[2\]。 2. Pytorch中的autograd:了解autograd的概念和使用方法,它是Pytorch中用于自动计算梯度的工具,可以方便地进行反向传播\[2\]。 3. 使用Pytorch构建一个神经网络:学习使用torch.nn库构建神经网络的典型流程,包括定义网络结构、损失函数、反向传播和更新网络参数等\[2\]。 4. 使用Pytorch构建一个分类:了解如何使用Pytorch构建一个分类,包括任务和数据介绍、训练分类的步骤以及在GPU上进行训练等\[2\]。 5. Pytorch的安装:可以通过pip命令安装Pytorch,具体命令为"pip install torch torchvision torchaudio",这样就可以在Python环境中使用Pytorch了\[3\]。 以上是一些关于Pytorch学习笔记,希望对你有帮助。如果你需要更详细的学习资料,可以参考引用\[1\]中提到的网上帖子,或者查阅Pytorch官方文档。 #### 引用[.reference_title] - *1* [pytorch自学笔记](https://blog.csdn.net/qq_41597915/article/details/123415393)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Pytorch学习笔记](https://blog.csdn.net/pizm123/article/details/126748381)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值