PyTorch基础语法
Pytorch是Facebook主导开发的,基于Python的科学计算包,主要有一下两个特点:
比NumPy更灵活,可以使用GPU的强大计算能力
开源高效的深度学习研究平台
张量
PyTorch中的Tensors可以使用GPU计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import torch
torch.empty(5, 3)
torch.rand(5, 3)
torch.zeros(5, 3, dtype=torch.long)
x = torch.tensor([5.5, 3]) x
x = x.new_ones(5, 3, dtype=torch.double) x
x = torch.randn_like(x, dtype=torch.float) x
x.size()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| y = torch.rand(5, 3) x + y
torch.add(x, y)
result = torch.empty(5, 3) torch.add(x, y, out=result) result
y.add_(x) y
|
任何以下划线结尾的操作都会用结果替换原变量
可以使用与Numpy索引方式相同的操作来对张量进行操作
1 2 3 4 5 6 7 8 9 10 11
| x = torch.randn(4, 4) y = x.view(16) z = x.view(-1, 8)
x.size(), y.size(), z.size()
x = torch.randn(1)
x, x.item()
|
官方文档:torch — PyTorch 1.12 documentation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| a = torch.ones(5) a b = a.numpy() b
a.add_(1) a, b
import numpy as np
a = np.ones(5) b = torch.from_numpy(a) np.add(a, 1, out=a) a, b
|
所有的 Tensor 类型默认都是基于 CPU, CharTensor 类型不支持到 NumPy 的转换
CUDA张量是能够再GPU设备在运算的张量。使用.to方法可以将Tensor移动到GPU设备中去
1 2 3 4 5 6 7 8
| if torch.cuda.is_available(): device = torch.device("cuda") y = torch.ones_like(x, device=device) x = x.to(device) z = x + y print(z) print(z.to("cpu", torch.double))
|
Autograd自动求导
PyTorch中所有神经网络的核心是autograd
autograd
为张量上的所有操作提供了自动求导。它是一个在运行时定义的框架,这意味着反向传播是根据你的代码来确定如何运行。
torch.Tensor
是这个包的核心类。如果设置.requires_grad
为True
,那么将会追踪所有对于该张量的操作。当完成计算后通过调用.backward()
会自动计算所有的梯度,这个张量的所有梯度将自动积累到.grad
属性。这也就完成了自动求导的过程。
要组织张量追踪历史记录,可以调用.detach()
方法将其与计算历史记录分离。为了防止跟踪历史记录(和使用内存),可以将代码块包装在with tirch.no_grad():
语句中。这一点在评估模型时特别有用,因为模型可能具有requires_grad=True
的可训练参数,但是并不需要计算梯度。
自动求导还有另一个重要的类Function
。Tensor
和Function
互相连接并生成一个非循环图,存储了完整的计算历史。
如果需要计算导数,可以在Tensor
上调用.backward()
。如果Tensor
是一个标量(即它只包含一个元素数据)则不需要为backward()
指定任何参数。但是如果他又多个元素,则需要指定一个gradient
参数来匹配张量的形状。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| x = torch.ones(2, 2, requires_grad=True) x
y = x + 2 y
y.grad_fn
z = y * y * 3 out = z.mean()
z, out
a = torch.randn(2, 2) a = ((a * 3) / (a - 1)) print(a.requires_grad) a.requires_grad_(True) print(a.requires_grad) b = (a * a).sum() print(b.grad_fn)
|
通过反向传播打印对应结点的梯度,因为out
是一个纯量Scalar,out.backward()
等于out.backward(torch.tensor(1))
关于Autograd的更多操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| x = torch.randn(3, requires_grad=True)
y = x * 2 while y.data.norm() < 1000: y = y * 2
y
gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float) y.backward(gradients)
x.grad
print(x.requires_grad) print((x ** 2).requires_grad)
with torch.no_grad(): print((x ** 2).requires_grad)
|
autograd
和Function
的官方文档:Automatic differentiation package - torch.autograd — PyTorch 1.12 documentation
神经网络
PyTorch中,我们可以使用torch.nn
来构建神经网络
torch.nn
依赖autograd
来定义模型并求导。nn.Module
中包含了构建神经网络所需的各个层和forward(input)
方法,该方法返回神经网络的输出。
神经网络的典型训练过程如下
1、定义包含可学习参数(权重)的神经网络模型
2、在数据集上迭代
3、通过神经网络处理输入
4、计算损失
5、将梯度反向传播回网络结点
6、更新网络的参数,一般可以使用梯度下降等最优化方法
PyTorch的nn.Conv2d()
详解,该类作为二维卷积的实现
1 2 3 4 5
| in_channels out_channels kernel_size stride=1 padding=0
|