PyTorch是什么?
它是一个基于Python的科学计算包,针对两类用户:
- 替代NumPy使用GPUs的功能
- 一个最大灵活性且快速的深度学习研究平台
入门
Tensors
Tensors与NumPy的ndarrays类似,不同点在于Tensors可以被用在GPU上来加速计算。
from __future__ import print_function
import torch
构造一个5x3的未初始化的矩阵:
x = torch.empty(5, 3)
print(x)
tensor([[9.2755e-39, 1.0561e-38, 4.5001e-39],
[4.5918e-39, 5.2347e-39, 4.2246e-39],
[1.0286e-38, 1.0653e-38, 1.0194e-38],
[8.4490e-39, 1.0469e-38, 9.3674e-39],
[9.9184e-39, 8.7245e-39, 9.2755e-39]])
构造一个随机初始化的矩阵:
x = torch.rand(5, 3) #从区间[0, 1)的均匀分布中抽取的一组随机数
print(x)
tensor([[0.4622, 0.6130, 0.3688],
[0.6646, 0.8553, 0.7672],
[0.7244, 0.9218, 0.9900],
[0.7845, 0.1664, 0.1185],
[0.5736, 0.8776, 0.7380]])
x = torch.randn(5, 3) #从标准正态分布(均值为0,方差为1,即高斯白噪声)中抽取的一组随机数
print(x)
tensor([[ 0.0867, 0.0768, 1.5253],
[ 1.9090, 1.0343, -0.9269],
[ 1.6954, -0.1689, 0.5888],
[-1.7752, 1.5916, -1.9801],
[-0.7347, 1.1672, -1.1405]])
构造dtype为long的全0矩阵:
x = torch.zeros(5, 3, dtype=torch.long)
print(x)
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
直接从数据中构造tensor:
x = torch.tensor([5.5, 3])
print(x)
tensor([5.5000, 3.0000])
基于一个已有的tensor来创建一个tensor。除非用户提高新的值,否则这些方法将复用输入tensor的属性,例如dtype。
x = x.new_ones(5, 3, dtype=torch.double) # new_* 方法,需输入sizes
print(x)
x = torch.randn_like(x, dtype=torch.float) # 覆盖 dtype!
print(x) # 结果有相同的size
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-0.1805, -2.2719, 0.1605],
[ 0.2035, -1.1823, 0.6890],
[-0.0636, -0.7252, -1.6976],
[ 0.8846, -0.0571, 0.5445],
[-0.6878, 2.1272, -0.7658]])
获取tensor的size:
print(x.size())
torch.Size([5, 3])
torch.Size
实际上是一个tuple(元组),所以它支持所有元组操作。
操作
PyTorch中的操作有多种语法。下面我们来看看加法操作。
加法: 语法 1
y = torch.rand(5, 3)
print(x + y)
tensor([[-0.1107, -1.3598, 0.2047],
[ 0.9173, -0.6006, 1.4937],
[ 0.2541, -0.5597, -0.9516],
[ 1.3623, 0.4293, 1.1828],
[-0.0404, 2.8328, -0.3035]])
加法: 语法 2
print(torch.add(x, y))
tensor([[-0.1107, -1.3598, 0.2047],
[ 0.9173, -0.6006, 1.4937],
[ 0.2541, -0.5597, -0.9516],
[ 1.3623, 0.4293, 1.1828],
[-0.0404, 2.8328, -0.3035]])
加法: 提供一个输出张量作为参数
result = torch.empty(5, 3) #需要先初始化
torch.add(x, y, out=result)
print(result)
tensor([[-0.1107, -1.3598, 0.2047],
[ 0.9173, -0.6006, 1.4937],
[ 0.2541, -0.5597, -0.9516],
[ 1.3623, 0.4293, 1.1828],
[-0.0404, 2.8328, -0.3035]])
加法: in-place
# 将x加给y
y.add_(x)
print(y)
tensor([[-0.1107, -1.3598, 0.2047],
[ 0.9173, -0.6006, 1.4937],
[ 0.2541, -0.5597, -0.9516],
[ 1.3623, 0.4293, 1.1828],
[-0.0404, 2.8328, -0.3035]])
任何对tensor进行in-place改变的操作,它后面都有一个
_
,例如:x.copy_(y)
,x.t_()
, 都会改变x
。
你可以随心所欲地使用标准的NumPy-like下标访问方法!
print(y[:, 1])
tensor([-1.3598, -0.6006, -0.5597, 0.4293, 2.8328])
print(y[:, -1])
tensor([ 0.2047, 1.4937, -0.9516, 1.1828, -0.3035])
放缩:如果想要resize/reshape一个tensor,可以使用torch.view
:
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) # size -1由其他维度推断出来
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
如果有一个单数据的tensor,使用.item()
来获取该数据,得到一个Python数字。
x = torch.randn(1)
print(x)
print(x.item())
tensor([-0.6330])
-0.6329890489578247
延展阅读
100多种Tensor操作,包括置换(transposing),检索(indexing),切片(slicing),数学运算(mathematical operations),线性代数(linear algebra),随机数(random numbers),等等,查看here。
NumPy Bridge
可以将一个Torch Tensor转为一个Numpy array,反之亦行。
Torch Tensor和Numpy array将共享它们的底层内存位置(如果Torch Tensor是在CPU上),改变其中一个,另一个也会改变。
The Torch Tensor and NumPy array will share their underlying memory
将Torch Tensor转为Numpy Array
a = torch.ones(5)
print(a)
tensor([1., 1., 1., 1., 1.])
b = a.numpy()
print(b)
[1. 1. 1. 1. 1.]
numpy array的值也会改变:
a.add_(1)
print(a)
print(b)
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
torch.add(a, 1, out=a)
print(a)
print(b)
tensor([3., 3., 3., 3., 3.])
[3. 3. 3. 3. 3.]
当使用非in-place操作时,numpy array不会随之改变:
a = torch.ones(5)
b = a.numpy()
a = torch.add(a, 1)
print(a)
print(b)
tensor([2., 2., 2., 2., 2.])
[1. 1. 1. 1. 1.]
将NumPy Array转为Torch Tensor
改变np array,tensor也会随之自动改变
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
除了CharTensor,所有CPU上的Tensor都支持转为Numpy与转回来。
CUDA Tensors
使用.to
方法,Tensors可以被移动到任何设备
# 只有当CUDA可用时,才运行这段代码
# 我们将使用"torch.device"对象来将tensors移入和移出GPU。
if torch.cuda.is_available():
device = torch.device("cuda") # CUDA device 对象
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"也可以一起改变dtyep
tensor([0.3670], device='cuda:0')
tensor([0.3670], dtype=torch.float64)