Pytorch
PyTorch
是基于 Python
的科学计算包,目标是两类人群:
使用 GPU 强大的算力对 NumPy
的替代
深度学习研究平台提供了最大化的灵活性和速度
Tensors
Tensors
是类似于 NumPy
的 ndarrays
,除此之外, Tensors
还可以被用在 GPU
上用来加快计算。
from __future__ import print_function
import torch
一个未初始化的矩阵被定义,但是在使用之前未包含确定的已知值。当一个未初始化的矩阵被创建时,不管被分配的内存中原来的值是什么都将作为初始值。
构建一个 (5 imes 3) 的未初始化的矩阵:
x = torch.empty(5, 3)
print(x)
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
构建一个随机值的矩阵:
x = torch.rand(5, 3)
print(x)
tensor([[0.8347, 0.6374, 0.3601],
[0.5775, 0.6665, 0.5684],
[0.5200, 0.1861, 0.0146],
[0.5582, 0.4759, 0.5131],
[0.9387, 0.2958, 0.1055]])
构建一个数据类型为 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]])
构建一个指定值的张量:
x = torch.tensor([5.5, 3])
print(x)
tensor([5.5000, 3.0000])
或者是创建一个基于已经存在的张量的张量。这个方法将使用输入张量的属性,例如数据类型,但是除非新的值被用户指定
x = x.new_ones(5, 3, dtype=torch.double) # new_* 方法输入大小
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.9017, 1.0312, -1.5354],
[ 0.2251, 1.0089, 0.0822],
[-2.0803, -0.0471, 0.3718],
[ 0.6297, 0.5046, -0.5284],
[ 0.4292, -0.8012, -0.4899]])
获取它的大小:
print(x.size())
torch.Size([5, 3])
torch.Size
是一个元组,所以它支持元组的所有操作
运算符
有很多的运算符语法。在下面的例子中,我们将看一看加法运算符。
加法:语法 1
y = torch.rand(5, 3)
print(x + y)
tensor([[-0.2456, 1.9013, -0.8082],
[ 0.9232, 1.2636, 0.7853],
[-1.0976, 0.6851, 0.7701],
[ 0.9949, 1.0428, 0.4364],
[ 0.8808, 0.0351, -0.3826]])
加法:语法 2
print(torch.add(x, y))
tensor([[-0.2456, 1.9013, -0.8082],
[ 0.9232, 1.2636, 0.7853],
[-1.0976, 0.6851, 0.7701],
[ 0.9949, 1.0428, 0.4364],
[ 0.8808, 0.0351, -0.3826]])
加法:提供一个输出张量作为参数
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
tensor([[-0.2456, 1.9013, -0.8082],
[ 0.9232, 1.2636, 0.7853],
[-1.0976, 0.6851, 0.7701],
[ 0.9949, 1.0428, 0.4364],
[ 0.8808, 0.0351, -0.3826]])
加法:in-place
# 将 x 加到 y 上
y.add_(x)
print(y)
tensor([[-0.2456, 1.9013, -0.8082],
[ 0.9232, 1.2636, 0.7853],
[-1.0976, 0.6851, 0.7701],
[ 0.9949, 1.0428, 0.4364],
[ 0.8808, 0.0351, -0.3826]])
任何一个在原张量的内存上修改(in-place)的运算符都有一个后缀
_
。举个例子,x.copy_()
,x.t_()
都将修改在x
上。
你可以使用标准类 NumPy 的花里胡哨的索引。
print(x[:, 1])
tensor([ 1.0312, 1.0089, -0.0471, 0.5046, -0.8012])
修改维度:如果你想重新修改张量的大小或形状,可以使用 torch.view
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) # -1 表示根据其它维度自动推断
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
如果你只有一个元素的张量,使用 .item()
可以获得 Python 的数值。
x = torch.randn(1)
print(x)
print(x.item())
tensor([0.9397])
0.9397323131561279
稍后阅读:还有一百多种运算符,包括转置、索引、切片、数学运算符、线性代数、随机数等等,都可以在官方文档中查看。
NumPy 桥
将 Torch 的张量转换成 NumPy 的数组是很容易的,反之亦然。
Torch 的张量和 NumPy 的数组将会共享内存(Torch 的张量在 CPU),改变其中的一个就会改变另一个。
将 Torch 的 Tensor 转换成 NumPy 数组
a = torch.ones(5)
print(a)
tensor([1., 1., 1., 1., 1.])
b = a.numpy()
print(b)
[1. 1. 1. 1. 1.]
观察 NumPy 数组如何改变值。
a.add_(1)
print(a)
print(b)
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
将 NumPy 数组转换成 Torch 张量
观察 NumPy 数组的改变,Torch 的 张量自动地随之改变。
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)
所有在 CPU 上的张量除了 CharTensor 都支持和 NumPy 的来回转换。
CUDA Tensors
张量可以使用 .to
方法移动到任何一块设备上。
# 将使用 torch.device 对象移动张量在 GPU 上来回进入
if torch.cuda.is_available():
device = torch.device("cuda") # 一个 CUDA 设备对象
y = torch.ones_like(x, device=device) # 直接创建在 GPU 上
x = x.to(device) # 也可以直接使用字符串 .to("cuda")
z = x + y
print(z)
print(z.to("cpu", torch.double)) # .to 方法也可以修改数据类型