当先锋百科网

首页 1 2 3 4 5 6 7

目标

我们想通过随机初始化的参数 ω , b \omega ,b ω,b能在迭代过程中使预测值和目标值能无限接近
y = ω x + b y=\omega x+b y=ωx+b

定义数据

x = torch.rand([60, 1])*10
y = x*2 + torch.randn(60,1)

构建模型

利用pytorch中的nn.Module
想要构建模型时,继承这个类即可
一些重写nn.Module类时的注意事项
(1)一般把网络中具有可学习参数的层(如全连接层、卷积层等)放在构造函数__init__()中;
(2)一般把不具有可学习参数的层(如ReLU、dropout、BatchNormanation层)可放在构造函数中,也可不放在构造函数中,如果不放在构造函数__init__里面,则在forward方法里面可以使用nn.functional来代替
(3)forward方法是必须要重写的,它是实现模型的功能,实现各个层之间的连接关系的核心。

from torch import nn
class Lr(nn.Module):
    def __init__(self):
        super(Lr, self).__init__()  #继承父类init的参数
        self.linear = nn.Linear(1, 1) #只有线性层(全链接层)
 
    def forward(self, x):
        out = self.linear(x)#输出
        return out

输出的数量nn.Linear(in_features, out_features);nn.Linear(1, 1)这里的参数易知我们通过方程得到的最终是一列数

# 实例化模型
model = Lr()
# 传入数据,计算结果
predict = model(x)

优化器

1、优化器主要是在模型训练阶段对模型可学习参数进行更新, 常用优化器有 SGD,RMSprop,Adam等
2、优化器初始化时传入传入模型的可学习参数,以及其他超参数如 lr,momentum等
3、在训练过程中先调用 optimizer.zero_grad() 清空梯度,再调用 loss.backward() 反向传播,最后调用 optimizer.step()更新模型参数
4、参数可以使用model.parameters()来获取,获取模型中所有requires_grad=True的参数

optimizer = optim.SGD(model.parameters(), lr=1e-3) #1. 实例化,1e-3也可以写成0.001
optimizer.zero_grad() #2. 梯度置为0
loss.backward() #3. 计算梯度
optimizer.step()  #4. 更新参数的值

损失函数

torch中有很多损失函数

1、均方误差:nn.MSELoss(),常用于回归问题

2、交叉熵损失:nn.CrossEntropyLoss(),常用于分类问题

训练模型

1、定义一个epoch,代表需要将所有数据训练epoch个轮次
2、数据传入模型,获取预测值
3、将预测值和目标值传入损失函数,计算损失
4、优化器的梯度归零,在每次更新参数中必须进行此步骤,否则梯度会一直累加
5、计算梯度,此步骤在4之后进行
6、更新梯度,参数随之更新
7、(可选)在训练过程中每隔一段时间打印下损失,观察收敛速度

#训练模型
for i in range(30000):
    out = model(x)  # 3.1 获取预测值
    loss = criterion(y, out)  # 3.2 计算损失
    optimizer.zero_grad()  # 3.3 梯度归零
    loss.backward()  # 3.4 计算梯度
    optimizer.step()  # 3.5 更新梯度
    if i % 300 == 0:
        print('Epoch[{}/{}], loss: {:.6f}'.format(i, 30000, loss.data))

模型测试

在模型的测试中,我们一般会使用测试集来评估训练得到的模型,这时候我们不需要梯度相关的操作,只需要将数据通过模型,得到损失、精确率等即可。测试中有以下需要注意:

model.eval()  # 设置模型为评估模式,即预测模式
predict = model(x)

绘图

predict = predict.data.numpy()
plt.scatter(x.data.numpy(), y.data.numpy(), c="r")
plt.plot(x.data.numpy(), predict)
plt.show()

在GPU上运行

判断GPU是否可用torch.cuda.is_available()

1、torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)

device(type=‘cuda’, index=0) #使用gpu
device(type=‘cpu’) #使用cpu

2、把模型参数和input数据转化为cuda的支持类型

model.to(device)
x_true.to(device)

3、在GPU上计算结果也为cuda的数据类型,需要转化为numpy或者torch的cpu的tensor类型

predict = predict.cpu().detach().numpy()
detach()的效果和data的相似,但是detach()是深拷贝,data是取值,是浅拷贝

完整代码

import torch
from torch import nn
from torch import optim
import numpy as np
from matplotlib import pyplot as plt

# 1. 定义数据
x = torch.rand([60, 1])*10
y = x*2 + torch.randn(60,1)


# 2 .定义模型
class Lr(nn.Module):
    def __init__(self):
        super(Lr, self).__init__()
        self.linear = nn.Linear(1, 1)

    def forward(self, x):
        out = self.linear(x)
        return out


# 2. 实例化模型,loss,和优化器
model = Lr()
# 损失函数
criterion = nn.MSELoss()
# 优化器
optimizer = optim.SGD(model.parameters(), lr=1e-3)
# 3. 训练模型
for i in range(30000):
    out = model(x)  # 3.1 获取预测值
    loss = criterion(y, out)  # 3.2 计算损失
    optimizer.zero_grad()  # 3.3 梯度归零
    loss.backward()  # 3.4 计算梯度
    optimizer.step()  # 3.5 更新梯度
    if i % 300 == 0:
        print('Epoch[{}/{}], loss: {:.6f}'.format(i, 30000, loss.data))

# 4. 模型评估
model.eval()  # 设置模型为评估模式,即预测模式
predict = model(x)
predict = predict.data.numpy()
plt.scatter(x.data.numpy(), y.data.numpy(), c="r")
plt.plot(x.data.numpy(), predict)
plt.show()

在这里插入图片描述

在这里插入图片描述