![7157442faab603f386b6296c5b9a7ca1.png](https://i-blog.csdnimg.cn/blog_migrate/fa93cf58c2de1dddc514d2cc2add25f9.jpeg)
Tensors张量: 张量的概念类似于Numpy中的ndarray数据结构, 最大的区别在于Tensor可以利用GPU的加速功能.
1. 创建张量
import torch
声明了一个未初始化的矩阵,创建矩阵时,所分配的内存中的任何值都将显示为初始值。
x = torch.empty(5, 3)
print(x)
输出:
tensor([[ 0.0000e+00, 0.0000e+00, 0.0000e+00],
[ 0.0000e+00, 2.8917e+38, 3.0868e-41],
[ 0.0000e+00, 0.0000e+00, -3.1718e-38],
[ 3.0868e-41, -3.1718e-38, 3.0868e-41],
[-3.1718e-38, 3.0868e-41, 0.0000e+00]])
构造一个随机初始化的矩阵(均匀分布):
x = torch.rand(5, 3)
print(x)
输出:
tensor([[0.5681, 0.8650, 0.8601],
[0.2493, 0.4788, 0.6302],
[0.8482, 0.6609, 0.6608],
[0.5056, 0.6278, 0.2869],
[0.9090, 0.5184, 0.0696]])
构造一个填充为零的矩阵:
x = torch.zeros(5, 3)
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])
通过已有的一个张量创建相同尺寸的新张量:
# 利用news_methods方法得到一个张量
x = x.new_ones(5, 3, dtype=torch.double)
print(x)
# 利用randn_like方法得到相同张量尺寸的一个新张量, 并且采用随机初始化来对其赋值
y = torch.randn_like(x, dtype=torch.float)
print(y)
输出:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-0.1497, -0.5832, -0.3805],
[ 0.9001, 2.0637, 1.3299],
[-0.8813, -0.6579, -0.9135],
[-0.1374, 0.1000, -0.9343],
[-1.1278, -0.9140, -1.5910]])
得到张量的尺寸:
print(x.size())
输出:
torch.Size([5, 3])
torch.Size实际上是一个元组,因此它支持所有元组操作。
2. 数据类型
在 PyTorch 里 Tensor 表示一个多维矩阵,相当于一个多维数组。
常用的不同数据类型的 Tensor:
- 32位浮点型:torch.FloatTensor
- 64位浮点型:torch.DoubleTensor
- 16位整型:torch.ShortTensor
- 32位整型:torch.IntTensor
- 64位整型:torch.LongTensor
注意:torch.Tensor 默认是 torch.FloatTensor 数据类型。
3. Pytorch的基本运算操作
加法操作
import torch
x = torch.rand(5, 3)
y = torch.rand(5, 3)
#第一种
print(x + y)
#第二种
print(torch.add(x, y))
#第三种
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
#第四种
y.add_(x)
print(y)
输出:
tensor([[0.8889, 1.8638, 1.8952],
[0.9510, 0.8178, 1.4992],
[1.3588, 1.0355, 0.5148],
[1.2394, 1.3530, 0.9226],
[0.5635, 1.5163, 0.4923]])
tensor([[0.8889, 1.8638, 1.8952],
[0.9510, 0.8178, 1.4992],
[1.3588, 1.0355, 0.5148],
[1.2394, 1.3530, 0.9226],
[0.5635, 1.5163, 0.4923]])
tensor([[0.8889, 1.8638, 1.8952],
[0.9510, 0.8178, 1.4992],
[1.3588, 1.0355, 0.5148],
[1.2394, 1.3530, 0.9226],
[0.5635, 1.5163, 0.4923]])
tensor([[0.8889, 1.8638, 1.8952],
[0.9510, 0.8178, 1.4992],
[1.3588, 1.0355, 0.5148],
[1.2394, 1.3530, 0.9226],
[0.5635, 1.5163, 0.4923]])
注意:
- 所有in-place的操作函数都有一个下划线的后缀.
- 比如x.copy_(y), x.add_(y), 都会直接改变x的值.
4. Tensor 与 numpy
Tensor(在CPU上) 与 numpy 数据共享基础内存位置, 因此改变其中一个的值, 另一个也会随之被改变.
a = torch.ones(5)
print(a)
b = a.numpy()
print(b)
输出:
tensor([1., 1., 1., 1., 1.])
[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 array转换为Torch 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上的所有张量都支持与 NumPy 相互转换。
用类似于Numpy的方式对张量进行操作, 可以像 numpy 一样 Tensor 切片 :
print(b[: 3])
输出:
tensor([2., 2., 2.], dtype=torch.float64)
可以像 numpy 一样通过索引获取其中元素,同时改变它的值。
a = torch.zeros((3, 2))
print(a)
a[0, 1] = 100
print(a)
输出:
tensor([[0., 0.],
[0., 0.],
[0., 0.]])
tensor([[ 0., 100.],
[ 0., 0.],
[ 0., 0.]])
改变张量的形状,可以使用torch.view():
x = torch.randn(4, 4) # 标准正态分布
# tensor.view()操作需要保证数据元素的总数量不变
y = x.view(16)
# -1代表自动匹配个数
z = x.view(-1, 8)
print(x.size(), y.size(), z.size())
输出:
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
如果张量中只有一个元素, 可以用.item()
将值取出, 作为一个python number
x = torch.randn(1)
print(x)
print(x.item())
x = torch.randn(2, 2)
print(x[1, 1])
print(x[1, 1].item())
输出:
tensor([0.5374])
0.5374473929405212
tensor(2.1489)
2.1488616466522217
注意这里的print(x)和print(x.item())值是不一样的,一个是打印张量,一个是打印元素
5. CUDA Tensor
如果电脑支持 GPU 加速, 可以将 Tensor 放到 GPU 上. Tensors可以用.to()方法来将其移动到任意设备上.
a = torch.Tensor([[2, 3], [4, 8], [7, 9]])
print(a)
if torch.cuda.is_available():
device = torch.device("cuda")
# a_cuda = a.cuda() # 方法1
a_cuda = a.to(device) # 方法2(建议)
print(a_cuda)