Pytorch 搭建神经网络(1)Tensor 张量数据结构
基于《深度学习框架 Pytorch 入门与实践》陈云
参考 Github 的 pytorch-book 项目
参考 GitHub 的 pytorch-handbook 项目
参考 DeepSeek 整理补充
笔记和代码存储在我的 GitHub 库中 github.com/isKage/pytorch-notes。
首先,检查 Pytorch
是否安装
1 2 3
| import torch print(torch.__version__) >>> 2.2.2
|
Tensor
是可以理解为一个类似 Numpy
中的高维数组。
1 创建
生成维度2x3的张量,并未赋值
1 2 3 4 5
| x = torch.Tensor(2, 3) print(x)
|
torch.tensor()
需要具体的值进行创建
输入具体的值,直接生成
1 2 3 4 5
| y = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float) print(y)
|
1 2 3 4 5
| z = torch.rand(2, 3) print(z)
|
2 查看形状
- 调用方法
.shape
或 .size()
查看张量形状/维度
1 2 3
| print(x.size()[1]) print(x.size(1)) print(x.shape[1])
|
3 加法
1 2 3 4 5 6
| x = torch.tensor([[1, 1, 1], [1, 1, 1]], dtype=torch.float) y = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float) print(x + y)
|
这种加法不改变 x, y
的值
1 2 3 4 5 6
| z = torch.Tensor(2, 3) torch.add(x, y, out=z) print(z)
|
这种加法不改变 x, y
的值
1 2 3 4 5
| print(y.add(x)) print(y)
print(y.add_(x)) print(y)
|
增加了 _
的方法会进行替换操作
4 索引
Tensor 的索引操作与 NumPy 类似
1 2 3 4 5 6 7 8
| x = torch.rand(2, 3) print(x)
print(x[:, 1]) print(x[1, :])
|
5 和 Numpy
的转换
torch.Tensor -> numpy.ndarray
使用 .numpy()
方法从Tensor变为numpy.ndarray
1 2 3 4 5 6 7 8
| x = torch.ones(1, 3) y = x.numpy()
print(x) print(type(x)) print(y) print(type(y))
|
numpy.ndarray -> torch.Tensor
使用 torch.from_numpy()
函数从numpy.ndarray变为Tensor
1 2 3 4 5 6 7
| import numpy as np y = np.ones((1, 3)) x = torch.from_numpy(y) print(y) print(type(y)) print(x) print(type(x))
|
- 共享内存,通过上面方式转换后,
x, y
是共享内存的,tenor改变,numpy.ndarray也改变
1 2 3 4 5 6
| print(x) print(y) temp = torch.rand(1, 3) x.add_(temp) print(x) print(y)
|
6 零维度张量/标量
Tensor 数据类型中维度为 0
称为标量(注意,虽然维度为0,但仍然不是 int
或是 float
这些一般 Python 数据类型)
1 2 3
| scaler = torch.tensor(9) print(scaler) print(scaler.shape)
|
如果想获得一般 Python 数据类型,可以使用方法 .item()
1 2
| print(scaler.item()) print(type(scaler.item()))
|
注意区分 0 维度标量和 1 维度张量
但是针对 1 维度张量,也可以使用 .item()
方法
1 2 3 4 5 6 7 8 9 10
| vector = torch.tensor([9]) scaler = torch.tensor(9) print(vector) print(vector.shape) print(scaler) print(scaler.shape)
print(vector.item()) print(type(vector.item()))
|
7 张量间的复制 .detach()
.clone()
1 2 3 4 5 6 7 8 9 10 11
| old = torch.tensor([[1, 2, 3], [4, 5, 6]]) new = old.clone() new[0] = 233
print(old)
print(new)
|
1 2 3 4 5 6 7 8 9 10 11
| old = torch.tensor([[1, 2, 3], [4, 5, 6]]) new = old.detach() new[0] = 233
print(old)
print(new)
|
8 维度转变
PyTorch提供了许多维度变换方式:view, reshape, permute, transpose
8.1 维度交换 permute
transpose
使用 permute
transpose
对张量维度进行交换,例如维度为 2x3x4x5 ,希望变为 3x2x5x4,可以
1 2 3 4 5 6 7 8 9 10 11
| previous = torch.randn(2, 3, 4, 5)
new1 = previous.permute((1, 0, 3, 2))
new2 = previous.transpose(0, 1) new2 = new2.transpose(2, 3)
print(new1.shape) print(new2.shape)
|
8.2 维度变换 view
reshape
reshape
无要求,可直接使用
view
只能用于内存中连续存储的 Tensor
1 2 3 4 5 6 7 8
| previous = torch.randn(2, 3, 4, 5)
new1 = previous.reshape(-1, 10) new2 = previous.view(6, 20)
print(new1.shape) print(new2.shape)
|
如果经过了 permute
transpose
维度交换,则需要先连续化内存,使用 .contiguous()
1 2 3 4 5 6 7 8 9 10
| previous = torch.randn(2, 3, 4, 5)
new = previous.permute((1, 0, 3, 2))
current = new.contiguous().view(6, 20)
print(current.shape)
|
8.3 维度压缩、扩展、拼接 squeeze
unsqueeze
cat
torch.squeeze(input, dim=None)
用于移除张量中大小为1的维度。如果不指定 dim
,则会移除所有大小为1的维度;如果指定了 dim
,则只会移除该维度(如果该维度大小为1)
1 2 3 4 5 6 7 8 9 10
| x = torch.randn(1, 3, 1, 2)
y = torch.squeeze(x) print(y.shape)
z = torch.squeeze(x, dim=2) print(z.shape)
|
torch.unsqueeze(input, dim)
用于在指定的位置插入一个大小为1的维度。dim
参数指定了新维度插入的位置
1 2 3 4 5 6 7 8 9
| x = torch.randn(3, 2)
y = torch.unsqueeze(x, dim=0) print(y.shape)
z = torch.unsqueeze(x, dim=1) print(z.shape)
|
torch.cat(tensors, dim=d)
用于在指定的维度上拼接多个张量。所有张量在除了 dim=d
维度之外的其它维度上必须具有相同的形状
1 2 3 4 5 6
| x = torch.randn(1, 4) y = torch.randn(2, 4)
z = torch.cat((x, y), dim=0) print(z.shape)
|
9 GPU 加速
利用 GPU 的并行计算能力能加速模型的计算。Pytorch提供了2种将tensor推至GPU的方法。
1 2
| device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") x = x.to(device)
|
1 2 3 4 5 6 7 8 9 10 11 12
| >>> import torch >>> print(torch.cuda.is_available) <function is_available at 0x0000024B63F50720>
>>> device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") >>> device device(type='cuda', index=0)
>>> x = torch.randn(2, 3) >>> x.to(device) tensor([[-0.1888, 0.0827, -1.2929], [ 2.1295, 1.6174, -1.4917]], device='cuda:0')
|