Python PyTorch中张量到切片的矢量化赋值
我正在尝试对表单的切片赋值进行矢量化Python PyTorch中张量到切片的矢量化赋值,python,arrays,vectorization,pytorch,tensor,Python,Arrays,Vectorization,Pytorch,Tensor,我正在尝试对表单的切片赋值进行矢量化 for i in range(a.shape[1]): for j in range(a.shape[2]): a[:,i,j,:,i:i+b.shape[2],j:j+b.shape[3]] = b 其中b本身是一个数组。这是因为嵌套Python循环效率太低,占用了大部分运行时。有办法做到这一点吗 对于一个简单的例子,考虑如下: for i in range(a.shape[1]): a[:,i,:,i:i+b.shape
for i in range(a.shape[1]):
for j in range(a.shape[2]):
a[:,i,j,:,i:i+b.shape[2],j:j+b.shape[3]] = b
其中b
本身是一个数组。这是因为嵌套Python循环效率太低,占用了大部分运行时。有办法做到这一点吗
对于一个简单的例子,考虑如下:
for i in range(a.shape[1]):
a[:,i,:,i:i+b.shape[2]] = b
这就是b
和a
可能的样子:
您可以看到结果矩阵的对角线“滑动”结构。假设
b
具有形状(2,3,x1)
,而a
具有形状(2,x2-x1+1,3,x2)
。在您的屏幕截图中,我们可以推断x1=4
,x2=6
将numpy导入为np
b_形=(2,3,4)
a_形=(2,3,3,6)
b=np.arange(1,25)。重塑(b_形)
#数组([[1,2,3,4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12]],
#
# [[13, 14, 15, 16],
# [17, 18, 19, 20],
# [21, 22, 23, 24]]])
c=np.pad(b,(*[(0,0)表示范围内的u(len(b_形[:-1]))],(0,a_形[-1]-b_形[-1]),“常数”)
#数组([[1,2,3,4,0,0],
# [ 5, 6, 7, 8, 0, 0],
# [ 9, 10, 11, 12, 0, 0]],
#
# [[13, 14, 15, 16, 0, 0],
# [17, 18, 19, 20, 0, 0],
# [21, 22, 23, 24, 0, 0]]])
a=np.堆栈([np.滚动(c,移位=i)表示范围内的i(a_形[-1]-b_形[-1]+1)],轴=1)
#数组([[1,2,3,4,0,0],
# [ 5, 6, 7, 8, 0, 0],
# [ 9, 10, 11, 12, 0, 0]],
# [[ 0, 1, 2, 3, 4, 0],
# [ 0, 5, 6, 7, 8, 0],
# [ 0, 9, 10, 11, 12, 0]],
# [[ 0, 0, 1, 2, 3, 4],
# [ 0, 0, 5, 6, 7, 8],
# [ 0, 0, 9, 10, 11, 12]]],
# [[[13, 14, 15, 16, 0, 0],
# [17, 18, 19, 20, 0, 0],
# [21, 22, 23, 24, 0, 0]],
# [[ 0, 13, 14, 15, 16, 0],
# [ 0, 17, 18, 19, 20, 0],
# [ 0, 21, 22, 23, 24, 0]],
# [[ 0, 0, 13, 14, 15, 16],
# [ 0, 0, 17, 18, 19, 20],
# [ 0, 0, 21, 22, 23, 24]]]])
我们可以利用based将滑动窗口视图转换为0s
填充版本的输入,并且作为一个视图将在内存和性能方面非常有效
因此,对于更简单的情况,它将是-
from skimage.util.shape import view_as_windows
def sliding_2D_windows(b, outshp_axis1):
# outshp_axis1 is desired output's shape along axis=1
n = outshp_axis1-1
b1 = np.pad(b,((0,0),(0,0),(n,n)),'constant')
w_shp = (1,b1.shape[1],b.shape[2]+n)
return view_as_windows(b1,w_shp)[...,0,::-1,0,:,:]
样本运行-
In [192]: b
Out[192]:
array([[[54, 57, 74, 77],
[77, 19, 93, 31],
[46, 97, 80, 98]],
[[98, 22, 68, 75],
[49, 97, 56, 98],
[91, 47, 35, 87]]])
In [193]: sliding_2D_windows(b, outshp_axis1=3)
Out[193]:
array([[[[54, 57, 74, 77, 0, 0],
[77, 19, 93, 31, 0, 0],
[46, 97, 80, 98, 0, 0]],
[[ 0, 54, 57, 74, 77, 0],
[ 0, 77, 19, 93, 31, 0],
[ 0, 46, 97, 80, 98, 0]],
[[ 0, 0, 54, 57, 74, 77],
[ 0, 0, 77, 19, 93, 31],
[ 0, 0, 46, 97, 80, 98]]],
[[[98, 22, 68, 75, 0, 0],
[49, 97, 56, 98, 0, 0],
[91, 47, 35, 87, 0, 0]],
....
[[ 0, 0, 98, 22, 68, 75],
[ 0, 0, 49, 97, 56, 98],
[ 0, 0, 91, 47, 35, 87]]]])
你能告诉我
a
和b
@techytushar忘了提到n
和m
只是a.shape[1]
和a.shape[2]
(也就是说,它们所索引的维度的大小)。我已经编辑了这个问题。使用其中一个,而不是对一系列单元格进行(Python)赋值,这样会比较慢。例如,研究如下方法。如果您告诉我们更多有关您试图创建的阵列的信息,这会有所帮助:它有什么结构?三角形的稀疏的半稀疏?一块一块的矩形块?它有多大?@smci我添加了一个简单的单循环示例。通常b
和a
有多大?请给我们发一个使用随机数据的实际代码示例。不是截图,谢谢。不过,这不是仍然用于循环吗?是的,唯一的for循环用于np.roll的不同移位。可能还有其他更好的方法。:)有没有一个版本可以适用于PyTorch张量?@user76284我对PyTorch区域不是很熟悉。所以,我不确定。@user76284 PyTorch是否有类似于NumPy的东西?如果是这样的话,那么应该是直截了当的。