一、概述
实现强大的GPU加速、支持动态神经网络
两个高级功能:
- 具有强大的GPU加速的张量计算(如Numpy)
- 包含自动求导系统的深度神经网络
缺点:
- 不支持快速傅里叶、沿维翻转张量和检查无穷与非数值张量;
- 针对移动端、嵌入式部署以及高性能服务器端的部署其性能表现有待提升
二、基础
张量创建
x=torch.empty(5,3) # 构造一个5x3不初始化的矩阵
'''
tensor([[2.6863e+20, 7.0368e+28, 1.1580e+27],
[7.2251e+28, 2.6099e+20, 2.8526e+20],
[2.8930e+12, 7.5338e+28, 1.8037e+28],
[3.4740e-12, 1.7743e+28, 2.0535e-19],
[1.6635e+22, 7.7781e+31, 3.4740e-12]])
'''
x=torch.rand(5,3) # 构造一个随机初始化的矩阵 均匀分布
'''
tensor([[0.3503, 0.2021, 0.7570],
[0.3480, 0.4150, 0.7948],
[0.7386, 0.0583, 0.2910],
[0.3405, 0.4210, 0.8954],
[0.6813, 0.2608, 0.9088]])
'''
x=x=torch.randn(5, 3) # 正态分布
'''
tensor([[ 0.4923, 0.1195, 0.0042],
[ 1.5152, -1.7146, -1.6457],
[-0.1062, 1.0163, 0.3063],
[-0.7901, -0.6235, -0.5819],
[-0.3534, 0.0600, -0.3388]])
'''
x=torch.zeros(5,3,dtype=torch.long) # 构造一个矩阵全为 0,而且数据类型是 long
'''
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
'''
x=torch.tensor([5.5,3]) # 直接使用数据构造一个张量
'''
tensor([5.5000, 3.0000])
'''
torch.rand和torch.randn的区别
均匀分布: torch.rand()
从区间[0, 1)
的均匀分布 (对称概率分布,在相同长度间隔的分布概率是等可能的) 中抽取的一组随机数。
标准正态分布: torch.randn()
从标准正态分布 ( 均值为0,方差为1
,即高斯白噪声) 中抽取的一组随机数。
torch.normal()
离散正态分布
基于已经存在的 tensor创建一个新tensor:
import torch
x=torch.rand(2,2)
print(x)
'''
tensor([[0.6825, 0.1973],
[0.2302, 0.6403]])
'''
x=x.new_ones(5, 3, dtype=torch.double) # ones创建的是全1的矩阵,注意全1的方阵才叫单位矩阵
# new_* methods take in sizes
print(x)
'''
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
'''
x=torch.randn_like(x,dtype=torch.float) # 随机生成一个和x维度一样的tensor
# override dtype!
print(x)
# result has the same size
'''
tensor([[-0.3891, -0.6876, -0.5642],
[-0.5763, -1.3508, -0.4681],
[ 1.1948, 0.9680, -1.2592],
[-0.1611, 1.1550, 0.2024],
[-0.9580, 0.1245, -0.9200]])
'''
x.size()
, x.shape
获取维度信息,torch.Size([5, 3])
是一个元组,所以它支持左右的元组操作。
张量操作
加法操作
x=torch.ones(5,3)
y=torch.rand(5,3)
# 方式一
print(x+y)
# 方式二
print(torch.add(x,y))
# 提供一个输出 tensor 作为参数
result=torch.empty(5,3)
torch.add(x,y,out=result)
print(result)
# in-place operation
y.add_(x)
print(y) # 用运算结果覆盖y
in-place operation 均以 _ 结尾
在pytorch中是指改变一个tensor的值的时候,不经过复制操作,而是直接在原来的内存上改变它的值。可以称之为“原地操作符”。
注意:1. PyTorch操作inplace版本都有后缀"_
", 例如 y.add_(x)
, x.copy_(y)
, x.t_()
2. python里面的+=
, *=
也是in-place operation
有两种情况不能使用in-place operation
1.对于 requires_grad=True
的叶子张量(leaf tensor) 不能使用 in-place operation
2.对于在 求梯度阶段需要用到的张量
不能使用 in-place operation
参考链接:pytorch之in-place operation
使用标准的 NumPy 类似的索引操作
x=torch.rand(5,3)
print(x)
'''
tensor([[0.7452, 0.9574, 0.2097],
[0.5201, 0.6421, 0.3684],
[0.0224, 0.6420, 0.8440],
[0.8011, 0.5456, 0.0069],
[0.9688, 0.8684, 0.6645]])
'''
print(x[:, 1])
'''
tensor([0.9574, 0.6421, 0.6420, 0.5456, 0.8684])
'''
改变大小 torch.view()
x=torch.rand(4,4)
y=x.view(16)
z=x.view(-1,8)
print(x)
'''
tensor([[0.4792, 0.9861, 0.2612, 0.2563],
[0.7621, 0.7714, 0.6972, 0.4983],
[0.2688, 0.3670, 0.8501, 0.1017],
[0.1909, 0.7189, 0.8126, 0.9513]])
'''
print(y)
'''
tensor([0.4792, 0.9861, 0.2612, 0.2563, 0.7621, 0.7714, 0.6972, 0.4983, 0.2688,
0.3670, 0.8501, 0.1017, 0.1909, 0.7189, 0.8126, 0.9513])
'''
print(z)
'''
tensor([[0.4792, 0.9861, 0.2612, 0.2563, 0.7621, 0.7714, 0.6972, 0.4983],
[0.2688, 0.3670, 0.8501, 0.1017, 0.1909, 0.7189, 0.8126, 0.9513]])
'''
print(x.size(), y.size(), z.size())
'''
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
'''
获取一个元素值的tensor的value
只有一个元素张量可以转换为 Python 标量
x=torch.randn(1)
print(x)
'''
tensor([0.1989])
'''
print(x.item())
'''
0.19890841841697693
'''
Tensor和Numpy的互换
Tensor转Numpy b=a.numpy()
a=torch.ones(5)
print(a)
'''
tensor([1., 1., 1., 1., 1.])
'''
b=a.numpy()
print(b)
'''
[1. 1. 1. 1. 1.]
'''
a.add_(1)
print(a)
'''
tensor([2., 2., 2., 2., 2.])
'''
print(b)
'''
[2. 2. 2. 2. 2.]
'''
# b和a共用一块内存,a发生变化时,b也会改变
Numpy转Tensor b=torch.from_numpy(a)
a=np.ones(5)
print(a)
'''
[1. 1. 1. 1. 1.]
'''
b=torch.from_numpy(a)
print(b)
'''
tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
'''
np.add(a,1,out=a)
print(a)
'''
[2. 2. 2. 2. 2.]
'''
print(b)
'''
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
'''
Cuda支持
print(torch.cuda.is_available()) # 查看是否支持cuda
if torch.cuda.is_available():
# 除了CharTensor之外,所有的tensor都可以在CPU运算和GPU运算之间相互转换
x=x.cuda() # 使用CUDA函数来将Tensor移动到GPU上
y=y.cuda()
x+y # 运算在GPU上进行