【深度学习知识】卷积当中的补零操作

本文详细探讨了卷积神经网络中输入输出尺寸的计算公式,包括TensorFlow和PyTorch的不同实现。重点讲解了如何通过padding实现SAME模式,确保输出尺寸不变或按步长缩小。建议使用奇数卷积核并设置padding=(k-1)/2以匹配TensorFlow的SAME模式。同时,文章指出在实际应用中,SAME模式的使用较为常见。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1. 卷积输入输出尺寸公式

在这里插入图片描述
这是一条比较完整的输出尺寸公式,考虑到了stride, padding, dilation, 这里的括号表示的是向下取整,这实际上是卷积图的边边剩下的部分比卷积核小,所以抛弃了这次卷积的结果。
其实,若用另一种视角看,可以把空洞卷积当成更改了卷积核尺寸K的值,K -> d × (K-1) +1,因此该公式可以更简洁的被表示为
Out = floor((In + 2P − K)/S+1)

1.1 tensorflow 版本

tensorflow 版本的padding是通过直接选模式参数进行的,可选’SAME’,’VALID’.前者是通过padding在前后左右补零,使得输出尺寸保持不变(或以步长倍数缩小),非常常用,后者则是不进行padding,实际上应该是等价于上边总公式P=0的情况。
SAME: Out = ceil(In/S)
VALID: Out = ceil((In − K + 1)/S)

1.2 pytorch 版本

>>> m = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
>>> input = torch.randn(20,3,24,24)
>>> m(input).shape
torch.Size([20, 64, 12, 12])
>>> input = torch.randn(20,3,25,25)
>>> m(input).shape
torch.Size([20, 64, 13, 13])
>>> input = torch.randn(20,3,24,24)
>>> m = nn.Conv2d(3, 64, kernel_size=6, stride=2, padding=3)
>>> m(input).shape
torch.Size([20, 64, 13, 13])
>>> m = nn.Conv2d(3, 64, kernel_size=6, stride=2, padding=2)
>>> m(input).shape
torch.Size([20, 64, 12, 12])

>>> input = torch.randn(20,3,25,25)
>>> m = nn.Conv2d(3, 64, kernel_size=6, stride=2, padding=3)
>>> m(input).shape
torch.Size([20, 64, 13, 13])
>>> m = nn.Conv2d(3, 64, kernel_size=6, stride=2, padding=2)
>>> m(input).shape
torch.Size([20, 64, 12, 12])

这里可以观察到:

  • 若是需要保持
  • 对于奇数卷积核,通过让padding=(k-1)/2,即可实现SAME的效果。即输出尺寸保持不变或以步长倍数缩小(对于奇数输入尺寸则向上取整)
  • 对于偶数卷积核,若是偶数输入尺寸,则padding=floor((k-1)/2)可实现SAME的效果
  • 对于偶数卷积核,若是奇数输入尺寸,则padding=ceil((k-1)/2)可实现SAME的效果

因此,建议不要用偶数卷积核。。。然后记住padding=(k-1)/2,即可实现tf中SAME的效果了。把padding带入一开始的总公式,可以得到Out = floor((In − 1)/S+1),这实际上与SAME公式等效,可以看下边代码的暴力验证。

>>> a = lambda x:np.ceil(x/5)
>>> b = lambda x:np.floor((x-1)/5+1)
>>> c = [np.random.randint(6,100) for i in range(10)]
>>> [a(rand)==b(rand) for rand in c]
[True, True, True, True, True, True, True, True, True, True]

2. 总结

虽然想了半天这个公式,但实际使用时好像也就SAME功能用得比较多,因此记住核心:

  • 用奇数卷积核 padding=(k-1)/2
  • 若是空洞卷积,则代入K -> d × (K-1) +1
### 深度学习中的卷积操作原理 #### 卷积操作的核心概念 卷积是一种数学运算,在深度学习中被广泛应用于处理图像数据。其核心思想是对输入数据施加一种局部化的线性变换,从而提取空间上的特征[^1]。具体来说,卷积操作涉及一个称为卷积核的小型矩阵与输入数据的滑动窗口相乘并求和。 #### 卷积操作流程 卷积操作通常遵循以下几个步骤: 1. **定义卷积核**:卷积核是一个小型矩阵,用于扫描整个输入数据。它的尺寸通常是奇数(如 \(3 \times 3\) 或 \(5 \times 5\))。 2. **滑窗计算**:将卷积核放置在输入数据的一个位置上,执行逐元素乘法并将结果相加得到单个输出值。 3. **移动卷积核**:按照设定的步幅(stride)移动卷积核至下一个位置重复上述操作。 4. **填充边界**:为了保持输出维度不变或者增加边缘信息,可以在输入周围添加零值像素(padding)。如果未使用填充,则输出会缩小。 #### 输出大小计算公式 假设输入张量的宽度为 \(W_{in}\),高度为 \(H_{in}\),卷积核大小为 \(K_w \times K_h\),步幅为 \(S\),以及填充数量为 \(P\),则输出的高度和宽度可以通过以下公式计算得出: \[ W_{out} = \frac{W_{in} + 2P - K_w}{S} + 1 \] \[ H_{out} = \frac{H_{in} + 2P - K_h}{S} + 1 \] #### 数学特性 需要注意的是,在实际实现过程中,卷积核并不是直接与输入矩阵对应位置相乘,而是先将其旋转180°后再进行点乘操作[^4]。这一细节对于理解卷积层如何捕捉不同方向的信息至关重要。 #### 特殊类型的卷积 除了标准卷积外,还有几种变体形式值得关注: - **转置卷积 (Transposed Convolution)**: 尽管有时被称为“反卷积”,但实际上它并不能完全恢复由正向卷积压缩掉的数据内容;仅能调整形状尺寸匹配需求[^2]。 - **深度可分离卷积 (Depthwise Separable Convolutions)**: 这种方法首先单独对每个通道应用普通二维卷积,随后再利用逐点卷积融合这些独立的结果来减少参数总量及提升效率[^3]. #### Python 实现示例 下面给出一段简单的Python代码演示基本的一维离散卷积过程: ```python import numpy as np def convolve(input_signal, kernel): input_len = len(input_signal) kernel_len = len(kernel) output_length = input_len - kernel_len + 1 result = np.zeros(output_length) for i in range(output_length): result[i] += sum([input_signal[j]*kernel[k-j] for j,k in zip(range(i,i+kernel_len),range(kernel_len))]) return result # Example usage: signal = [1, 2, 3, 4, 5] kernel = [-1, 0, 1] output = convolve(signal, kernel) print("Convolved Output:", list(output)) ``` 此脚本展示了手动构建一维数组间简单卷积的方式,并打印最终结果作为验证手段之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值