强化学习入门01——Pytorch

版本

  • python version: 3.11.5
  • pytorch version: 2.1.2

Pytorch基础

Tensor操作

Tensor是PyTorch中最基本的数据结构,可以将其视为多维数组或者矩阵。PyTorch tensor和NumPy array非常相似,但是tensor还可以在GPU上运算,而NumPy array则只能在CPU上运算。

  1. 导入PyTorch库
import torch
  1. 创建tensor的方法
# 创建一个未初始化的5x3矩阵,
x = torch.empty(5, 3)

# 创建一个随机初始化的5x3矩阵
x = torch.rand(5, 3)

# 创建一个5x3的零矩阵,类型为long
x = torch.zeros(5, 3, dtype=torch.long)

# 直接从数据创建tensor
x = torch.tensor([5.5, 3])

print(x)结果如下:

# 创建一个未初始化的5x3矩阵,
# x = torch.empty(5, 3)
tensor([[5.8615e-03, 1.7811e-42, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00]])

# 创建一个随机初始化的5x3矩阵
# x = torch.rand(5, 3)
tensor([[0.4907, 0.0131, 0.7226],
        [0.7092, 0.3426, 0.5230],
        [0.3096, 0.8168, 0.5885],
        [0.8925, 0.8080, 0.0763],
        [0.3721, 0.0415, 0.9458]])

# 创建一个5x3的零矩阵,类型为long
# x = torch.zeros(5, 3, dtype=torch.long)
tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])

# 直接从数据创建tensor
# x = torch.tensor([5.5, 3])
tensor([5.5000, 3.0000])
  1. 对已有的tensor进行操作
# 创建一个2行2列值全为1的tensor,并设置requires_grad=True,作用是让 backward可以追踪这个参数并且计算它的梯度,默认为False
x = torch.ones(2, 2, requires_grad=True)
print(x)

# 对tensor进行操作,每个数都加2,torch.add(x, y)也可以做加法
y = x + 2
print(y)

# y是操作x的结果且 x的requires_grad=True,所以它有grad_fn属性 TODO
print(y.grad_fn)

# 对y进行更多操作,mean()为求平均
z = y * y * 3
out = z.mean()
print(out)

# 定义a, b, 重新定义x的大小和值,b的行列和a相同,值随机
a = x.new_ones(3, 2, dtype = torch.float64)
b = torch.randn_like(a, dtype = torch.float64)
# 将a变成一个1行6列的tensor
c = a.view(6)
# 将a变成一个3行2列的tensor,-1为自动计算列
d = a.view(3, -1)
print(a)
print(b)
print(c)
print(d)

运行结果如下:

# x = torch.ones(2, 2, requires_grad=True)
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

# y = x + 2
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)

# print(y.grad_fn)
<AddBackward0 object at 0x000001E9336B4A00>

# z = y * y * 3
# out = z.mean()
tensor(27., grad_fn=<MeanBackward0>)

# a = x.new_ones(3, 2, dtype = torch.float64)
# b = torch.randn_like(a, dtype = torch.float64)
# c = a.view(6)
# d = a.view(3, -1)
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]], dtype=torch.float64)
tensor([[ 0.7927,  0.0316],
        [-1.1589, -0.9528],
        [-1.7619, -0.5105]], dtype=torch.float64)
tensor([1., 1., 1., 1., 1., 1.], dtype=torch.float64)
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]], dtype=torch.float64)    

Pytorch自动求导机制

  1. 使用.backward()来进行反向传播,计算梯度
import torch

x = torch.ones(2, 2, requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()

# 调用反向传播
out.backward()
# 对x求偏导,输出梯度d(out)/dx
print(x.grad)

反向传播的图:
在这里插入图片描述

  1. 反向传播相关性质
  • .requires_grad:如果a为True,b为False,则c = a + b为True,如果a和b都为False,则c为False,即看c如果是关于requires_grad = True的运算,那么它应该也为True
  • .is_leaf:判断是否为叶子结点,是的话返回True(a和b),只有叶子结点的梯度会被直接计算和存储,非叶子节点(c)的梯度不会直接存储,因为它们通常是作为计算过程中的中间结果。
  • out.backward(retain_graph = True):等于True,表示不清零,每个节点的梯度会累加,所以在反向传播前需要清零

线性回归Demo

  • 一个简单的线性回归神经网络模型构建步骤:
  1. 用一个类构建模型,包括输入输出、有多少层、以及forward前向传播函数(激活函数等)
  2. 构建类的实例,也就是具体的网络模型
  3. 优化器、loss函数
  4. 开始训练:将数据输入到模型中得到预测数据、将预测数据与真实数据输入到loss函数中得到loss值、梯度清零、反向传递、优化器优化
  5. 最后可以将数据输入到训练好的模型,进行预测
  • 具体代码:
import torch
import torch.nn as nn
import numpy as np

x_values = [i for i in range(11)]
x_train = np.array(x_values, dtype = np.float32)
x_train = x_train.reshape(-1, 1)

y_values = [2 * i + 1 for i in x_values]
y_train = np.array(y_values, dtype= np.float32)
y_train = y_train.reshape(-1, 1)

# 构建线性回归模型
# 线性回归就是一个不加激活函数的全连接层
class Net(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(Net, self).__init__()
        self.linear = nn.Linear(input_dim, output_dim)  # 写出需要用到哪些层

    def forward(self, x):  # 前向传播
        out = self.linear(x)  # 写对当前的层是怎么走的,走一个全连接层
        return out 
    
model = Net(1, 1)  # 模型

epochs = 1000
learning_rate = 0.01

optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate) # 优化器,model.parameters()为参数,lr为学习率
loss_func = nn.MSELoss()  # loss函数,MSELoss为均方差

for t in range(epochs):  # 迭代多少次
    inputs = torch.from_numpy(x_train)  # 将numpy数据转为tensor
    y = torch.from_numpy(y_train)   

    prediction = model(inputs) # 前向传播,将数据输入进去
    loss = loss_func(prediction, y) # 计算损失,预测值和真实值对比,计算误差

    # 优化步骤
    optimizer.zero_grad()   # 首先将所有参数的梯度降为0(因为每次计算梯度后这个值都会保留,不清零就会导致不正确),梯度下降
    loss.backward()         # 进行反向传递,计算出计算图中所有节点的梯度
    optimizer.step()        # 计算完成后,使用optimizer优化这些梯度

模型保存和加载

  1. 模型保存
torch.save(net1, 'net.pkl')  # 保存整个神网络,第二个参数为神经网络的名字
torch.save(net1.state_dict(), 'net_paramspkl')   # 保存神经网络的节点参数
  1. 模型加载
net3.load_state_dict(torch.load('net_params.pkl'))

使用GPU进行训练

只需添加:一行代码+模型输入到GPU+数据输入到GPU

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")  # GPU存在使用它,不存在用CPU
model.to(device)  # 将模型输入到GPU

inputs = torch.from_numpy(x_train).to(device)  # 数据放到GPU,之后的数据不需要了
y = torch.from_numpy(y_train).to(device) 

tensor常见的形式

  • 0: scalar:通常是一个数值
  • 1: vector: 通常指特征
  • 2: matrix: 一般计算的都是矩阵,通常是多维的
  • 3: n-dimensional tensor:高维的
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值