如何仅在特定位置进行2D卷积?

发布于 2025-02-13 21:52:56 字数 317 浏览 0 评论 0原文

这个问题已经多次问,但我仍然无法得到我想要的。想象一下,

data=np.random.rand(N,N)   #shape N x N
kernel=np.random.rand(3,3) #shape M x M

我知道卷积通常意味着将内核放在全部数据上。但是在我的情况下,nm是10000的订单。因此,我希望在数据中的特定位置获得卷积的价值,例如(10 ,37)在所有位置都没有进行不必要的计算。因此,输出将只是一个数字。主要目标是减少计算和内存费用。是否有最少的调整功能可以实现此功能?

This question has been asked multiple times but still I could not get what I was looking for. Imagine

data=np.random.rand(N,N)   #shape N x N
kernel=np.random.rand(3,3) #shape M x M

I know convolution typically means placing the kernel all over the data. But in my case N and M are of the orders of 10000. So I wish to get the value of the convolution at a specific location in the data, say at (10,37) without doing unnecessary calculations at all locations. So the output will be just a number. The main goal is to reduce the computation and memory expenses. Is there any inbuilt function that does this with minimal adjustments?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

左岸枫 2025-02-20 21:52:58

实际上,应用卷积为特定位置与仅在data floppipted kernel本身的(刻度)乘法的条目上的单纯总和相一致。这里是一个可再现的例子。

代码

N = 1000
M = 3

np.random.seed(777)
data  = np.random.rand(N,N)   #shape N x N
kernel= np.random.rand(M,M)   #shape M x M

# Pointwise convolution = pointwise product
data[10:10+M,37:37+M]*kernel[::-1, ::-1]
>array([[0.70980514, 0.37426475, 0.02392947],
       [0.24387766, 0.1985901 , 0.01103323],
       [0.06321042, 0.57352696, 0.25606805]])

输出

conv = np.sum(data[10:10+M,37:37+M]*kernel[::-1, ::-1])
conv
>2.45430578

内核正在通过卷积的定义进行翻转 - 横向滤波器填充的横向通行性神经网络>在这里,是善良的沃伦·韦克斯(Warren Weckesser)。谢谢!

关键是要理解您提供的索引。我假设它是指data中的子矩阵的左上角。但是,当m奇怪时,它也可以参考中点。

概念

n = 7m = 3的不同示例示例
并以

kernel = np.array([[3,0,-1], [2,0,1], [4,4,3]])

k[::-1,::-1]
> array([[ 3,  4,  4],
         [ 1,  0,  2],
         [-1,  0,  3]])

编辑1:

请注意,该视频中的讲师没有明确提及在点乘之前需要翻转内核才能遵守数学上适当的卷积定义。

编辑2

对于大型m和目标索引,靠近data的边界,valueerror:操作数无法与形状...可能会抛出。为了防止这种情况,请用零填充矩阵数据可以防止这种情况(尽管它炸毁了内存要求)。 IE

data   = np.pad(data, pad_width=M, mode='constant')

Indeed, applying the convolution for a particular position coincides with the mere sum over the entries of a (pointwise) multiplication of the submatrix in data and the flipped kernel itself. Here, is a reproducible example.

Code

N = 1000
M = 3

np.random.seed(777)
data  = np.random.rand(N,N)   #shape N x N
kernel= np.random.rand(M,M)   #shape M x M

# Pointwise convolution = pointwise product
data[10:10+M,37:37+M]*kernel[::-1, ::-1]
>array([[0.70980514, 0.37426475, 0.02392947],
       [0.24387766, 0.1985901 , 0.01103323],
       [0.06321042, 0.57352696, 0.25606805]])

with output

conv = np.sum(data[10:10+M,37:37+M]*kernel[::-1, ::-1])
conv
>2.45430578

The kernel is being flipped by definition of the convolution as explained in here and was kindly pointed Warren Weckesser. Thanks!

The key is to make sense of the index you provided. I assumed it refers to the upper left corner of the sub-matrix in data. However, it can refer to the midpoint as well when M is odd.

Concept

A different example with N=7 and M=3 exemplifies the idea
and is presented in here for the kernel

kernel = np.array([[3,0,-1], [2,0,1], [4,4,3]])

which, when flipped, yields

k[::-1,::-1]
> array([[ 3,  4,  4],
         [ 1,  0,  2],
         [-1,  0,  3]])

EDIT 1:

Please note that the lecturer in this video does not explicitly mention that flipping the kernel is required before the pointwise multiplication to adhere to the mathematically proper definition of convolution.

EDIT 2:

For large M and target index close to the boundary of data, a ValueError: operands could not be broadcast together with shapes ... might be thrown. To prevent this, padding the matrix data with zeros can prevent this (although it blows up the memory requirement). I.e.

data   = np.pad(data, pad_width=M, mode='constant')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文