卷积的三种模式:full、same、valid + 卷积输出size的计算

转载自:https://blog.csdn.net/leviopku/article/details/80327478

通常用外部api进行卷积的时候,会面临mode选择。

这三种mode的不同点:对卷积核移动范围的不同限制。

设 image的大小是7x7(橙色部分),filter的大小是3x3(蓝色部分)

1. full mode

full mode:从filter和image刚相交开始做卷积,不足的部分padding 0。filter的运动范围如图所示。

 

2. same mode

same mode:same模式不代表完全输入输出尺寸一样(可通过代码验证),也跟卷积核的步长有关系。

same模式是最常见的模式,是指经过卷积的特征图和原图的size保持不变。

 

3.valid mode

filter全部在image里面的时候,进行卷积运算,可见filter的移动范围较same更小了。

 

 

4. 卷积输出图size的计算公式

先定义几个参数

  • 输入图片大小 W×W
  • Filter大小 F×F
  • 步长 S
  • padding的像素数 P

于是我们可以得出

N = (W − F + 2P )/S+1

输出图片大小为 N×N

<think>好的,用户想了解如何使用NumPy进行卷积运算,并且需要示例教程。首先,我需要回忆一下NumPy中是否有现成的卷积函数。记得NumPy确实有一个convolve函数,但它主要用于一维信号处理。而用户提到的卷积可能涉及到图像处理或神经网络中的二维卷积,这时候可能需要使用SciPy的convolve2d或者自己实现二维卷积。 接下来,根据用户提供的引用,特别是引用[2]和[4],他们提到了使用NumPy实现卷积运算的例子,甚至包括定义卷积函数。因此,我需要结合这些引用内容来构建回答。同时,用户可能希望看到具体的代码示例和分步说明,确保他们能够理解并自己实现。 需要确认用户的需求是基础的一维卷积还是更复杂的二维,比如图像处理中的情况。考虑到引用中提到的图像处理和神经网络,应该以二维卷积为例。不过,先解释一维作为基础,再扩展到二维可能更清晰。 然后,考虑如何正确使用NumPy的函数。比如numpy.convolve的参数,比如mode('valid', 'same', 'full'),需要解释清楚不同模式的区别。同时,二维卷积可能需要手动实现,或者使用SciPy,但用户特别提到使用NumPy,所以应该避免引入其他库。 查看引用中的代码示例,比如引用[2]中的convolution函数,是手动实现的二维卷积,使用双重循环。这可能效率不高,但适合教学目的。同时,引用[3]和[4]也涉及到了矩阵扩展和过滤器设置,这说明在实现时需要考虑边界填充(padding)和步长(stride)等因素,但可能用户只需要基础实现,所以先提供简单的版本,再提到优化方法。 另外,用户的问题是关于如何使用NumPy进行卷积运算,所以需要确保代码示例正确,并符合NumPy的最佳实践。例如,使用滑动窗口视图来优化性能,而不是手动循环,这可能更高效,但代码复杂度更高。但根据引用中的例子,用户可能更接受简单直观的实现方式,即使效率不高,但便于理解。 最后,生成相关问题需要考虑用户可能进一步想知道的内容,比如不同模式的区别、性能优化、在CNN中的应用等,参考提供的引用内容中的相关点来设计问题。</think>### 使用NumPy实现卷积运算的分步教程 卷积运算是图像处理和神经网络中的核心操作。以下是两种实现方式:**一维信号卷积**和**二维图像卷积**,均基于NumPy实现。 --- #### 一、一维信号卷积 NumPy内置函数 `numpy.convolve` 可直接实现一维卷积: ```python import numpy as np signal = np.array([1, 2, 3, 4]) # 输入信号 kernel = np.array([0.5, 1, 0.5]) # 卷积核 result = np.convolve(signal, kernel, mode='valid') # 模式可选'valid'/'same'/'full' print(result) # 输出: [4. 6.] ``` - **模式说明**: - `valid`:仅计算完全重叠区域,输出尺寸为 $n - m + 1$($n$为信号长度,$m$为核长度)[^2]。 - `same`:输出尺寸与输入信号相同,边缘部分自动填充0。 - `full`:计算所有可能重叠区域,输出尺寸为 $n + m - 1$。 --- #### 二、二维图像卷积(手动实现) 若需处理图像等二维数据,需手动实现卷积过程。以下是一个简化版本: ```python import numpy as np def convolution_2d(image, kernel): # 输入检查 if image.ndim != 2 or kernel.ndim != 2: raise ValueError("输入必须为二维数组") # 获取图像和卷积核尺寸 img_h, img_w = image.shape kernel_h, kernel_w = kernel.shape # 计算输出尺寸(valid模式) output_h = img_h - kernel_h + 1 output_w = img_w - kernel_w + 1 output = np.zeros((output_h, output_w)) # 滑动窗口计算卷积 for i in range(output_h): for j in range(output_w): window = image[i:i+kernel_h, j:j+kernel_w] output[i, j] = np.sum(window * kernel) # 逐元素相乘后求和 return output # 示例:边缘检测卷积核 image = np.array([[10, 10, 10, 0, 0], [10, 10, 10, 0, 0], [10, 10, 10, 0, 0], [10, 10, 10, 0, 0], [10, 10, 10, 0, 0]]) kernel = np.array([[1, 0, -1], # 水平梯度检测核 [1, 0, -1], [1, 0, -1]]) result = convolution_2d(image, kernel) print(result) ``` 输出结果将突出显示图像中垂直边缘的变化区域[^4]。 --- #### 三、性能优化技巧 1. **向量化操作**:用 `np.lib.stride_tricks.sliding_window_view` 替代手动循环: ```python def optimized_conv2d(image, kernel): windows = np.lib.stride_tricks.sliding_window_view(image, kernel.shape) return np.tensordot(windows, kernel, axes=((2,3), (0,1))) ``` 此方法利用NumPy广播机制,速度提升显著[^3]。 2. **边界填充**:通过 `np.pad` 实现边缘填充(如`zero-padding`): ```python padded_image = np.pad(image, ((1,1), (1,1)), mode='constant') # 上下左右各填充1行0 ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值