从零开始学Pytorch(一)之常见数据操作

2022-08-24 16:04:25 浏览数 (1)

代码语言:javascript复制
import torch
 
torch.manual_seed()
 
torch.cuda.manual_seed()
 
print(torch.__version__)
 
输出pytorch的版本号

创建Tensor

创建一个5x3的未初始化的Tensor

代码语言:javascript复制
x = torch.empty(, )
 
print(x)
 
输出为:tensor([[0.0000e 00, 1.0842e-19, 1.6162e 22],
 
[2.8643e-42, 5.6052e-45, 0.0000e 00],
 
[0.0000e 00, 0.0000e 00, 0.0000e 00],
 
[0.0000e 00, 0.0000e 00, 0.0000e 00],
 
[0.0000e 00, 1.0842e-19, 1.3314e 22]])
 

创建一个5x3的随机初始化的Tensor:

代码语言:javascript复制
x = torch.rand(, )
 
print(x)
 
输出为:
 
tensor([[0.4963, 0.7682, 0.0885],
 
[0.1320, 0.3074, 0.6341],
 
[0.4901, 0.8964, 0.4556],
 
[0.6323, 0.3489, 0.4017],
 
[0.0223, 0.1689, 0.2939]])
 

创建一个5x3的long型全0的Tensor:

代码语言:javascript复制
x = torch.zeros(, , dtype=torch.long)
 
print(x)
 
输出为:
 
tensor([[, , ],
 
[, , ],
 
[, , ],
 
[, , ],
 
[, , ]])
 

直接根据数据创建:

代码语言:javascript复制
x = torch.tensor([5.5, ])
 
print(x)
 
输出为:
 
tensor([5.5000, 3.0000])
 

还可以通过现有的Tensor来创建,此方法会默认重用输入Tensor的一些属性。

代码语言:javascript复制
x = x.new_ones(, , dtype=torch.float64)      # 返回的tensor默认具有相同的torch.dtype和torch.device
 
print(x)
 
x = torch.randn_like(x, dtype=torch.float)    # 指定新的数据类型
 
print(x)
 
输出为:
 
tensor([[1., 1., 1.],
 
[1., 1., 1.],
 
[1., 1., 1.],
 
[1., 1., 1.],
 
[1., 1., 1.]], dtype=torch.float64)
 
tensor([[ 0.6035,  0.8110, -0.0451],
 
[ 0.8797,  1.0482, -0.0445],
 
[-0.7229,  2.8663, -0.5655],
 
[ 0.1604, -0.0254,  1.0739],
 
[ 2.2628, -0.9175, -0.2251]])
 

我们可以通过shape或者size()来获取Tensor的形状:

代码语言:javascript复制
print(x.size())
 
print(x.shape)
 
输出为:
 
torch.Size([, ])
 
torch.Size([, ])
 

注意:返回的torch.Size其实就是一个tuple, 支持所有tuple的操作。

操作

算术操作

  • 加法形式一
代码语言:javascript复制
y = torch.rand(, )
 
print(x   y)
 
输出为:
 
tensor([[ 1.3967,  1.0892,  0.4369],
 
[ 1.6995,  2.0453,  0.6539],
 
[-0.1553,  3.7016, -0.3599],
 
[ 0.7536,  0.0870,  1.2274],
 
[ 2.5046, -0.1913,  0.4760]])
 

  • 加法形式二
代码语言:javascript复制
print(torch.add(x, y))
 
输出为:
 
tensor([[ 1.3967,  1.0892,  0.4369],
 
[ 1.6995,  2.0453,  0.6539],
 
[-0.1553,  3.7016, -0.3599],
 
[ 0.7536,  0.0870,  1.2274],
 
[ 2.5046, -0.1913,  0.4760]])
 
result = torch.empty(, )
 
torch.add(x, y, out=result)
 
print(result)
 
输出为:
 
tensor([[ 1.3967,  1.0892,  0.4369],
 
[ 1.6995,  2.0453,  0.6539],
 
[-0.1553,  3.7016, -0.3599],
 
[ 0.7536,  0.0870,  1.2274],
 
[ 2.5046, -0.1913,  0.4760]])
 

  • 加法形式三、inplace
代码语言:javascript复制
# adds x to y
 
y.add_(x)
 
print(y)
 
输出为:
 
tensor([[ 1.3967,  1.0892,  0.4369],
 
[ 1.6995,  2.0453,  0.6539],
 
[-0.1553,  3.7016, -0.3599],
 
[ 0.7536,  0.0870,  1.2274],
 
[ 2.5046, -0.1913,  0.4760]])
 

注:PyTorch操作inplace版本都有后缀"_", 例如x.copy_(y), x.t_()

索引

代码语言:javascript复制
y = x[, :]
 
y  = 
 
print(y)
 
print(x[, :]) # 源tensor也被改了
 
输出为:
 
tensor([1.6035, 1.8110, 0.9549])
 
tensor([1.6035, 1.8110, 0.9549])
 

改变形状

view()来改变Tensor的形状:

代码语言:javascript复制
y = x.view()
 
z = x.view(-1, )  # -1所指的维度可以根据其他维度的值推出来
 
print(x.size(), y.size(), z.size())
 
输出为:
 
torch.Size([, ]) torch.Size([]) torch.Size([, ])
 

代码语言:javascript复制
x  = 
 
print(x)
 
print(y) # 也加了1
 
输出为:
 
tensor([[2.6035, 2.8110, 1.9549],
 
[1.8797, 2.0482, 0.9555],
 
[0.2771, 3.8663, 0.4345],
 
[1.1604, 0.9746, 2.0739],
 
[3.2628, 0.0825, 0.7749]])
 
tensor([2.6035, 2.8110, 1.9549, 1.8797, 2.0482, 0.9555, 0.2771, 3.8663, 0.4345,
 
1.1604, 0.9746, 2.0739, 3.2628, 0.0825, 0.7749])
 

 如果不想共享内存,推荐先用clone创造一个副本然后再使用view

代码语言:javascript复制
x_cp = x.clone().view()
 
x -= 
 
print(x)
 
print(x_cp)
 
输出为:
 
tensor([[ 1.6035,  1.8110,  0.9549],
 
[ 0.8797,  1.0482, -0.0445],
 
[-0.7229,  2.8663, -0.5655],
 
[ 0.1604, -0.0254,  1.0739],
 
[ 2.2628, -0.9175, -0.2251]])
 
tensor([2.6035, 2.8110, 1.9549, 1.8797, 2.0482, 0.9555, 0.2771, 3.8663, 0.4345,
 
1.1604, 0.9746, 2.0739, 3.2628, 0.0825, 0.7749])
 

另外一个常用的函数就是item(), 它可以将一个标量Tensor转换成一个Python number:

代码语言:javascript复制
x = torch.randn()
 
print(x)
 
print(x.item())
 
输出为:
 
tensor([2.3466])
 
2.3466382026672363
 

广播机制

代码语言:javascript复制
x = torch.arange(, ).view(, )
 
print(x)
 
y = torch.arange(, ).view(, )
 
print(y)
 
print(x   y)
 
输出为:
 
tensor([[, ]])
 
tensor([[],
 
[],
 
[]])
 
tensor([[, ],
 
[, ],
 
[, ]])
 

Tensor和NumPy相互转换

Tensor转NumPy

代码语言:javascript复制
a = torch.ones()
 
b = a.numpy()
 
print(a, b)
 
a  = 
 
print(a, b)
 
b  = 
 
print(a, b)
 
输出为:
 
tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]
 
tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]
 
tensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]
 

NumPy数组转Tensor

代码语言:javascript复制
import numpy as np
 
a = np.ones()
 
b = torch.from_numpy(a)
 
print(a, b)
 
a  = 
 
print(a, b)
 
b  = 
 
print(a, b)
 
输出为;
 
[1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
 
[2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
 
[3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)

代码语言:javascript复制
# 用torch.tensor()转换时不会共享内存
 
c = torch.tensor(a)
 
a  = 
 
print(a, c)
 
输出为:
 
[4. 4. 4. 4. 4.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)

Tensor on GPU

代码语言:javascript复制
# 以下代码只有在PyTorch GPU版本上才会执行
 
if torch.cuda.is_available():
 
device = torch.device("cuda")          # GPU
 
y = torch.ones_like(x, device=device)  # 直接创建一个在GPU上的Tensor
 
x = x.to(device)                       # 等价于 .to("cuda")
 
z = x   y
 
print(z)
 
print(z.to("cpu", torch.double))       # to()还可以同时更改数据类型

参考文献

[1]《动手深度学习》李沐

0 人点赞