张量

  1. 张量
  2. 相同点 / 不同点
  3. 零索引
  4. 不需要驼峰命名
  5. Numpy转换
  6. CUDA传感器

张量

TensorsPyTorch中的运行方式与Torch几乎完全相同。

创建一个初始化内存大小 (5 x 7) 的张量:

import torch
a = torch.FloatTensor(5, 7)

初始化用正态分布随机化的mean = 0,var = 1

a = torch.randn(5, 7)
print(a)
print(a.size())

输出:

0.7727  1.6337 -1.1285  0.8936  0.1883  0.4983  1.3766
 1.0733  1.0271  0.6200  0.9735 -0.1027  0.0464  0.4400
 0.5090 -1.4429  1.0649  0.1695 -0.3629 -0.1729  1.3668
-0.2333 -0.9960 -0.1005 -1.2377  0.5271 -2.9070 -0.8906
-0.2037 -0.8548  0.0339 -0.2636 -1.4015 -2.0643 -0.3636
[torch.FloatTensor of size 5x7]

torch.Size([5, 7])

注意

torch.Size 实际上是一个元组,所以它支持相同的操作

相同点 / 不同点

第一个区别是,所有的操作在张量操作需要有_后缀。例如,add在此处无用,使用add_是可用的。

a.fill_(3.5)
# 将a填充值3.5。

b = a.add(4.0)
# a 依然是填充3.5
# 新张量b的返回值为3.5 + 4=7.5。

print(a, b)

输出:

3.5000  3.5000  3.5000  3.5000  3.5000  3.5000  3.5000
 3.5000  3.5000  3.5000  3.5000  3.5000  3.5000  3.5000
 3.5000  3.5000  3.5000  3.5000  3.5000  3.5000  3.5000
 3.5000  3.5000  3.5000  3.5000  3.5000  3.5000  3.5000
 3.5000  3.5000  3.5000  3.5000  3.5000  3.5000  3.5000
[torch.FloatTensor of size 5x7]

 7.5000  7.5000  7.5000  7.5000  7.5000  7.5000  7.5000
 7.5000  7.5000  7.5000  7.5000  7.5000  7.5000  7.5000
 7.5000  7.5000  7.5000  7.5000  7.5000  7.5000  7.5000
 7.5000  7.5000  7.5000  7.5000  7.5000  7.5000  7.5000
 7.5000  7.5000  7.5000  7.5000  7.5000  7.5000  7.5000
[torch.FloatTensor of size 5x7]

一些操作如narrow没有相同版本,因此.narrow_不存在。类似地,一些操作如 fill_没有不同的版本,因此.fill不存在。

零索引

另一个区别是传感器零索引。(在lua中,张量是单索引的)

b = a[0, 3]  # 选择a中的1行4列

也可以使用Python的切片索引传感器

b = a[:, 3:5]  # 从a中选择所以行的4到5列
不需要驼峰命名

下一个小的区别是所有的功能现在都不是驼峰命名了。例如indexAdd现在调用index_add_

x = torch.ones(5, 5)
print(x)

输出:

1  1  1  1  1
 1  1  1  1  1
 1  1  1  1  1
 1  1  1  1  1
 1  1  1  1  1
[torch.FloatTensor of size 5x5]
z = torch.Tensor(5, 2)
z[:, 0] = 10
z[:, 1] = 100
print(z)

输出:

10  100
  10  100
  10  100
  10  100
  10  100
[torch.FloatTensor of size 5x2]
x.index_add_(1, torch.LongTensor([4, 0]), z)
print(x)

输出:

101    1    1    1   11
 101    1    1    1   11
 101    1    1    1   11
 101    1    1    1   11
 101    1    1    1   11
[torch.FloatTensor of size 5x5]

Numpy

将Torch传感器转换为numpy array,反之亦然。torch Tensor和numpy阵列将共享它们的底层内存位置,而改变一个将改变另一个。

把 torch Tensor 转变成 numpy Array

a = torch.ones(5)
print(a)

输出:

1
 1
 1
 1
 1
[torch.FloatTensor of size 5]
b = a.numpy()
print(b)

输出:

[ 1.  1.  1.  1.  1.]
a.add_(1)
print(a)
print(b)    # see how the numpy array changed in value

输出:

2
 2
 2
 2
 2
[torch.FloatTensor of size 5]

[ 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)  # see how changing the np array changed the torch Tensor automatically

输出:

[ 2.  2.  2.  2.  2.]

 2
 2
 2
 2
 2
[torch.DoubleTensor of size 5]

除了CharTensor之外,CPU上的所有CharTensor都支持转换为NumPy并返回。

CUDA传感器

CUDA传感器在pytorch中很好并且很容易,并将CUDA张量从CPU转移到GPU将保留其基础类型。

# 查看电脑是否支持CUDA
if torch.cuda.is_available():
    # 创建一个LongTensor并且把它全部转换为3
    # to GPU as torch.cuda.LongTensor
    a = torch.LongTensor(10).fill_(3).cuda()
    print(type(a))
    b = a.cpu()
    # transfers it to CPU, back to
    # being a torch.LongTensor

输出:

<class 'torch.cuda.LongTensor'>

脚本的总运行时间:(0分0.004秒)

  1. 下载Python资源: tensor_tutorial.py
  2. 下载学习笔记: tensor_tutorial.ipynb