1

假设我有两个表示图片中像素的数组。

我想在“扫描”后者时构建一个较小图片和较大图片的像素的张量积数组。“扫描”是指在使用原始图片创建叠加层时对行和列进行迭代。

例如,可以以四种不同的方式将 2x2 图片叠加在 3x3 之上,因此我想生成一个包含匹配像素张量积的四元素数组。

Tensordot 是通过将 a[i,j] 与 b[i,j] 逐元素相乘并将各项求和来计算的。

请检查此代码:

import numpy as np

a = np.array([[0,1,2],
              [3,4,5],
              [6,7,8]])
              
b = np.array([[0,1],
              [2,3]])

shape_diff = (a.shape[0] - b.shape[0] + 1,
              a.shape[1] - b.shape[1] + 1)

def compute_pixel(x,y):
    sub_matrix = a[x : x + b.shape[0],
                   y : y + b.shape[1]]
    return np.tensordot(sub_matrix, b, axes=2)
    
def process():
    arr = np.zeros(shape_diff)
    for i in range(shape_diff[0]):
        for j in range(shape_diff[1]):
            arr[i,j]=compute_pixel(i,j)
    return arr

print(process())

计算单个像素非常容易,我所需要的只是 a 中的起始位置坐标。从那里我匹配b的大小并做一个 tensordot 产品。

但是,因为在迭代行和列时我需要对每个x 和 y位置重新执行此操作,所以我不得不使用循环,这当然不是最佳的。

在下一段代码中,我尝试利用 tensordot 的一个方便的特性,它也接受张量作为参数。换句话说,我可以为 a 的不同组合提供一个数组数组同时保持b相同。

尽管为了创建一个上述组合的数组,我想不出比使用另一个循环更好的方法,在这种情况下听起来很傻。

def try_vector():
    tensor = np.zeros(shape_diff + b.shape)
    for i in range(shape_diff[0]):
        for j in range(shape_diff[1]):
            tensor[i,j]=a[i: i + b.shape[0],
                          j: j + b.shape[1]]
    
    return np.tensordot(tensor, b, axes=2)

print(try_vector())

注意:张量大小是两个元组的总和,在这种情况下给出 (2, 2, 2, 2)

然而无论如何,即使我制作了这样的阵列,它的尺寸也太大了,无法实际使用。对于 1000x1000 的图片执行此操作,可能会消耗所有可用内存。

那么,还有其他方法可以避免这个问题中的循环吗?

4

1 回答 1

0
In [111]: process()
Out[111]: 
array([[19., 25.],
       [37., 43.]])

tensordot与 2 与元素相乘和相加相同:

In [116]: np.tensordot(a[0:2,0:2],b, axes=2)
Out[116]: array(19)
In [126]: (a[0:2,0:2]*b).sum()
Out[126]: 19

生成您的内存较低的方法tensor是:

In [121]: np.lib.stride_tricks.sliding_window_view(a,(2,2))
Out[121]: 
array([[[[0, 1],
         [3, 4]],

        [[1, 2],
         [4, 5]]],


       [[[3, 4],
         [6, 7]],

        [[4, 5],
         [7, 8]]]])

我们可以在最后两个轴上进行广播乘法和求和:

In [129]: (Out[121]*b).sum((2,3))
Out[129]: 
array([[19, 25],
       [37, 43]])
于 2021-12-21T19:57:13.783 回答