Pytorch使用pytorch进行张量计算自动求导和神经网络构建
Posted 阿润菜菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pytorch使用pytorch进行张量计算自动求导和神经网络构建相关的知识,希望对你有一定的参考价值。
本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052
首先,让我们介绍一下什么是pytorch,它是一个基于Python的开源深度学习框架,它提供了两个核心功能:张量计算和自动求导。
张量计算
张量计算是指使用多维数组(称为张量)来表示和处理数据,例如标量、向量、矩阵等。pytorch提供了一个torch.Tensor类来创建和操作张量,它支持各种数据类型和设备(CPU或GPU)。我们可以使用torch.tensor()
函数来创建一个张量,并指定它的形状、数据类型和是否需要梯度。
例如,我们可以创建一个2x3的浮点型张量,并设置requires_grad=True,表示我们想要跟踪这个张量的所有操作:
import torch
x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], requires_grad=True)
print(x)
输出结果为:
tensor([[1., 2., 3.],
[4., 5., 6.]], requires_grad=True)
自动求导
自动求导是指利用pytorch的autograd模块来自动计算张量的梯度,即导数。梯度是一个表示函数变化率的向量,它在深度学习中非常重要,因为它可以用来优化模型的参数。当我们对一个张量执行某些操作时,例如加法、乘法、指数等,pytorch会记录这些操作,并构建一个计算图。当我们调用.backward()方法时,pytorch会根据链式法则从后往前遍历这个计算图,并计算每个节点的梯度。我们可以通过.grad属性来访问这些梯度。
例如,我们可以定义一个简单的函数y = x ** 2,并对x = [2, 3]求导:
import torch
x = torch.tensor([2.0, 3.0], requires_grad=True)
y = x ** 2
print(y)
y.backward()
print(x.grad)
输出结果为:
tensor([4., 9.], grad_fn=<PowBackward0>)
tensor([4., 6.])
神经网络的构建
神经网络构建是指使用pytorch提供的nn模块来定义和训练复杂的神经网络模型。nn模块包含了各种预定义的层、损失函数、优化器等组件,可以方便地组合成不同类型的神经网络。我们可以使用nn.Module类来定义自己的神经网络层或模型,并实现forward()方法来定义前向传播逻辑。backward()方法会由autograd自动实现。
例如,我们可以定义一个简单的线性回归模型,并用随机数据进行训练:
import torch
import torch.nn as nn
# 定义线性回归模型 y = wx + b
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(1, 1) # 输入维度为1,输出维度为1
def forward(self, x):
y = self.linear(x) # 前向传播逻辑
return y
# 创建模型实例
model = LinearRegression()
print(model)
# 创建损失函数(均方误差)和优化器(随机梯度下降)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.
# 生成随机数据
x = torch.randn(100, 1) # 100个随机输入
y = 3 * x + 2 + torch.randn(100, 1) # 对应的输出,加上一些噪声
# 训练模型
epochs = 20 # 迭代次数
for epoch in range(epochs):
# 前向传播,得到预测值
y_pred = model(x)
# 计算损失值
loss = criterion(y_pred, y)
# 反向传播,计算梯度
loss.backward()
# 更新参数
optimizer.step()
# 清零梯度
optimizer.zero_grad()
# 打印损失值和参数值
print(f"Epoch epoch, loss: loss.item():.4f")
for name, param in model.named_parameters():
print(name, param.data)
# 测试模型
x_test = torch.tensor([[4.0]]) # 测试输入
y_test = model(x_test) # 预测输出
print(f"Predicted y for x = 4: y_test.item():.4f")
输出结果为:
Epoch 0, loss: 9.9758
linear.weight tensor([[2.8277]])
linear.bias tensor([0.0145])
Epoch 1, loss: 4.0609
linear.weight tensor([[2.9056]])
linear.bias tensor([0.2308])
...
Epoch 19, loss: 0.9866
linear.weight tensor([[2.9877]])
linear.bias tensor([1.9679])
Predicted y for x = 4: 13.9166
可以看到,经过训练,模型的参数接近真实值(w=3,b=2),并且能够对新的输入进行预测。
参考:) PyTorch官方网站
自动求梯度(pytorch版本)——2.20
一、Tensor用于自动求梯度
"tensor"这个单词?般可译作“张量”,张量可以看作是?个多维数组。标量可以看作是0维张量,向量可以看作1维张量,矩阵可以看作是?维张量。
????在深度学习中,我们经常需要对函数求梯度(gradient)。PyTorch提供的autograd
包能够根据输?和前向传播过程?动构建计算图,并执?反向传播。本节将介绍如何使?autograd包来进??动求梯度的有关操作。
概念
????Pytorch中的Tensor
是这个包的核?类,如果将其属性 .requires_grad
设置为 True
,它将开始追踪(track)在其上的所有操作(这样就可以利?链式法则进?梯度传播了)。完成计算后,可以调? .backward()
来完成所有梯度计算。此 Tensor
的梯度将累积到 .grad
属性中。
注意在
y.backward()
时,如果y
是标量,则不需要为backward()
传?任何参数;否则,需要传??个与y
同形的Tensor
。
????如果不想要被继续追踪,可以调? .detach()
将其从追踪记录中分离出来,这样就可以防?将来的计算被追踪,这样梯度就传不过去了。此外,还可以? with torch.no_grad()
将不想被追踪的操作代码块包裹起来,这种?法在评估模型的时候很常?,因为在评估模型时,我们并不需要计算可训练参数(requires_grad=True
)的梯度。
????Function
是另外?个很?要的类。 Tensor
和 Function
互相结合就可以构建?个记录有整个计算过程的有向?环图(DAG)。每个 Tensor 都有?个 .grad_fn
属性,该属性即创建该 Tensor
的Function
, 就是说该 Tensor
是不是通过某些运算得到的,若是,则 grad_fn
返回?个与这些运算相关的对象,否则是None。
import torch
# 通过设置`requires_grad=Ytue`,使得操作通过链式法则进行梯度传播
x = torch.ones(2, 2, requires_grad=True)
print(x)
print(x.grad_fn)
+的运算操作
y = x+2
print(y)
print(y.grad_fn)
print(x.is_leaf,y.is_leaf)
# 复杂一点的运算操作
z = y*y*2
print(z)
print(z.grad_fn)
out = z.mean()
print(z, out)
????输出结果:
以上是关于Pytorch使用pytorch进行张量计算自动求导和神经网络构建的主要内容,如果未能解决你的问题,请参考以下文章