还是先认错啊 只为自己好加标签 自己看方便~~
向量化计算是一种特殊的并行计算方式。程序在同一时间内只执行一个操作,而并行计算可以在同一时间内执行多个操作。向量化计算是指对不同的数据执行同样的一个或一批指令,或者把指令应用到一个数组或向量上,从而将多次循环操作变成一次计算。
向量化操作可以极大地提高科学运算的效率。尽管Python本身使用简便,但是其中存在着许多低效的操作,例如for循环等。因此,在科学计算中应当极力避免使用Python原生的for循环,尽量使用向量化数值运算,下面举例说明:
In: import torch as t
# 定义for循环完成加法操作
def for_loop_add(x, y):
result = []
for i, j in zip(x, y):
result.append(i + j)
return t.tensor(result)
x = t.zeros(100)
y = t.ones(100)
%timeit -n 100 for_loop_add(x, y)
%timeit -n 100 (x + y) # +是向量化计算Out:100 loops, best of 3: 786 µs per loop
100 loops, best of 3: 2.57 µs per loop
从上面的例子中可以看出,for循环和向量化计算之间存在数百倍的速度差距,在实际使用中应该尽量调用内建函数(buildin-function)。这些函数底层由C/C++实现,在实现中使用了向量化计算的思想,通过底层优化实现了高效计算。在日常编程中应该养成向量化的编程习惯,避免对较大的Tensor进行逐元素的遍历操作,从而提高程序的运行效率。
这里主要从广播法则、高级索引两个方面介绍PyTorch中的向量化计算。 whaosoft aiot http://143ai.com
01
广播法则
广播法则(broadcast)是科学计算中经常使用的一个技巧,它在快速执行向量化计算的同时不会占用额外的内存/显存。NumPy中的广播法则定义如下。
-
所有输入数组都与形状(shape)最大的数组看齐,形状不足的部分在前面加1补齐。
-
两个数组要么在某一个维度的尺寸一致,要么其中一个数组在该维度的尺寸为1,否则不符合广播法则的要求。
-
如果输入数组的某个维度的尺寸为1,那么计算时沿此维度复制扩充成目标的形状大小。
虽然PyTorch已经支持了自动广播法则,但是建议通过以下两种方式的组合手动实现广播法则,这样更加直观,也更不容易出错。
-
unsqueeze、view或者tensor[None] :为数据某一维度补1,实现第一个广播法则。
-
expand或者expand_as,重复数组,实现第三个广播法则;该操作不会复制整个数组,因此不会占用额外的空间。
注意:repeat可以实现与expand类似的功能,expand是在已经存在的Tensor上创建一个新的视图(view),repeat会将相同的数据复制多份,因此会占用额外的空间。
首先来看自动广播法则:
In: # 自动广播法则
# 第一步:a是2维的,b是3维的,所以先在较小的a前面补1个维度,
# 即:a.unsqueeze(0),a的形状变成(1,3,2),b的形状是(2,3,1),
# 第二步:a和b在第一和第三个维度的形状不一样,同时其中一个为1,
# 利用广播法则扩展,两个形状都变成了(2,3,2)
a = t.ones(3, 2)
b = t.zeros(2, 3, 1)
(a + b).shapeOut:torch.Size([2, 3, 2])
再来看如何手动实现以上广播过程:
In: # 手动广播法则,下面两行操作是等效的,推荐使用None的方法
# a.view(1, 3, 2).expand(2, 3, 2) + b.expand(2, 3, 2)
a[None,:,:].expand(2, 3, 2) + b.expand(2, 3, 2)Out:tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
02
索引操作
索引和切片是NumPy和PyTorch中的两种常用操作,本节将从基本索引入手,对比介绍高级索引的相关用法,帮助建立向量化思想。
2.1 基本索引
PyTorch中Tensor的索引和NumPy数组的索引类似,通过索引操作可以定位到数据的具体位置,也可以进行切片操作。基本索引有以下几种形式。
-
元组序列:在索引中直接使用一个元组序列对Tensor中数据的具体位置进行定位,也可以直接使用多个整数(等价于元组序列省略括号的形式)代替。
-
切片对象(Slice Object):在索引中常见的切片对象形如sta