卷积操作的全面解析与实践
1. 一维卷积基础
在一维卷积中,输入集合 $S$ 中的每个点都关联着一个值 $X_x$,这些值共同构成输入 $X$。我们在输入点网格上定义输出点子网格 $S_o$,它是通过对输入应用基于步长的步进操作从 $S$ 得到的。假设步长 $s = [s_W]$,第一个滑动停止位置是核(类似砖块)的左上角位于 $(x = 0)$ 处,下一个是 $(x = s_W)$,再下一个是 $(x = 2s_W)$,到达右端时停止。输出网格由核在扫过输入体积时左上角停留的滑动停止点组成,即 $S_o = {(x = 0), (x = s_W) \cdots }$,$S_o$ 中的每个点都有一个输出。
一维卷积中单个输出值的生成公式如下:
[Y_x = \sum_{j = 0}^{k_W} X_{x + j}W_j, \forall(x) \in S_o]
这里,$X$ 表示输入,$Y$ 表示输出,$W$ 表示核权重。当核的原点位于 $x$ 处,其维度为 $k_W$,它覆盖了定义域 $[x \cdots (x + k_W)]$ 内的所有输入像素,这些像素参与上述公式的计算,每个输入像素与覆盖它的核元素相乘。
2. 一维卷积的应用
2.1 曲线平滑
使用权重向量为 $\vec{w} = [\frac{1}{3}, \frac{1}{3}, \frac{1}{3}]$ 的一维核进行卷积,本质上是对连续的 3 个输入值取移动平均值,这是一种局部平均(即平滑)操作。卷积后的输出是输入的平滑(局部平均)版本,它通过消除高频(短期)噪声来捕捉函数的低频(长期)宽泛趋势。从物理意义上讲,这类似于一个低通滤波器,去除短期的高频噪声,捕捉输入数据数组中的长期低频变化。
2.2 曲线边缘检测
边缘定义为输入数组中值的急剧变化。例如,若输入数组中两个连续元素的值有较大绝对差值,这就是一个边缘。使用具有反对称归一化权重(如 $\vec{w} = [\frac{1}{2}, -\frac{1}{2}]$)的核进行卷积,会在输入的边缘处产生高响应(输出值),而在其他位置产生低响应。边缘检测对于图像理解很重要,因为信号快速变化的位置比平坦均匀区域提供更多语义线索,人类视觉皮层的实验也表明,人们会更多地关注颜色或阴影快速变化的位置。
3. 一维卷积与矩阵乘法
代数上,大小为 3、步长为 1、有效填充的卷积可以表示为矩阵乘法。设输入数组为 $\vec{x} = [x_0, x_1, x_2, x_3, x_4, \cdots, x_{n - 3}, x_{n - 2}, x_{n - 1}]$,卷积核为 $\vec{w} = [w_0, w_1, w_2]$。
在卷积的第 0 步,将核放在输入的第 0 个元素 $x_0$ 上,$w_0$ 落在 $x_0$ 上,$w_1$ 落在 $x_1$ 上,$w_2$ 落在 $x_2$ 上,将对应位置的元素相乘并求和,得到输出的第 0 个元素 $y_0 = w_0x_0 + w_1x_1 + w_2x_2$。然后将核向右移动 1 位(步长为 1),重复上述操作得到 $y_1$,以此类推。
对于有效填充,卷积的输出可以表示为:
[\vec{y} = \vec{w} \circledast \vec{x} =
\begin{bmatrix}
w_0x_0 + w_1x_1 + w_2x_2 \
w_0x_1 + w_1x_2 + w_2x_2 \
\cdots
\end{bmatrix}]
卷积的权重矩阵具有稀疏的块对角结构,例如,步长为 1、大小为 3 的卷积权重矩阵 $W$ 与输入向量 $\vec{x}$ 的乘法表示如下:
[\vec{w} \circledast \vec{x} = W\vec{x} =
\begin{bmatrix}
w_0x_0 + w_1x_1 + w_2x_2 \
w_0x_1 + w_1x_2 + w_2x_2 \
\cdots
\end{bmatrix} =
\begin{bmatrix}
w_0 & w_1 & w_2 & 0 & 0 & 0 & \cdots & 0 & 0 & 0 \
0 & w_0 & w_1 & w_2 & 0 & 0 & \cdots & 0 & 0 & 0 \
0 & 0 & w_0 & w_1 & w_2 & 0 & \cdots & 0 & 0 & 0 \
0 & 0 & 0 & w_0 & w_1 & w_2 & \cdots & 0 & 0 & 0 \
0 & 0 & 0 & 0 & w_0 & w_1 & \cdots & 0 & 0 & 0 \
\cdots \
0 & 0 & 0 & 0 & 0 & 0 & \cdots & w_0 & w_1 & w_2
\end{bmatrix}
\begin{bmatrix}
x_0 \
x_1 \
x_2 \
x_3 \
x_4 \
\cdots \
x_{n - 1}
\end{bmatrix}]
如果步长为 2,核权重在连续行中会移动 2 个位置。不过,虽然上述矩阵乘法提供了卷积的概念性视图,但它不是实现卷积的最有效方式,PyTorch 等深度学习软件有更高效的实现方法。
4. PyTorch 中的一维卷积
在 PyTorch 中,可以使用自定义权重进行一维卷积。以下是具体的代码示例:
4.1 一维局部平均卷积
import torch
x = torch.tensor([-1., 4., 11., 14., 21., 25., 30.])
w = torch.tensor([0.33, 0.33, 0.33])
x = x.unsqueeze(0).unsqueeze(0)
w = w.unsqueeze(0).unsqueeze(0)
conv1d = torch.nn.Conv1d(1, 1, kernel_size=3, stride=1, padding=[0], bias=False)
conv1d.weight = torch.nn.Parameter(w, requires_grad=False)
with torch.no_grad():
y = conv1d(x)
4.2 一维边缘检测
import torch
x = torch.tensor([10., 11., 9., 10., 101., 99., 100., 101., 9., 10., 11., 10.])
w = torch.tensor([0.5, -0.5])
x = x.unsqueeze(0).unsqueeze(0)
w = w.unsqueeze(0).unsqueeze(0)
conv1d = torch.nn.Conv1d(1, 1, kernel_size=3, stride=1, padding=[0], bias=False)
conv1d.weight = torch.nn.Parameter(w, requires_grad=False)
with torch.no_grad():
y = conv1d(x)
也可以直接使用 torch.nn.functional.conv1d 来调用数学卷积操作:
import torch
x = torch.tensor([10., 11., 9., 10., 101., 99., 100., 101., 9., 10., 11., 10.])
w = torch.tensor([0.5, -0.5])
x = x.unsqueeze(0).unsqueeze(0)
w = w.unsqueeze(0).unsqueeze(0)
y = torch.nn.functional.conv1d(x, w, stride=1)
5. 卷积输出大小
考虑一个大小为 $k$ 的核以步长 $s$ 滑过大小为 $n$ 的输入。对于有效填充,卷积输出大小 $o$ 的计算公式如下:
[o = \lfloor\frac{n - k}{s}\rfloor + 1]
如果在输入的每一侧进行 $p$ 个零填充,输入大小变为 $n + 2p$,相应的输出大小为:
[o = \lfloor\frac{n + 2p - k}{s}\rfloor + 1]
这些公式可以通过对每个维度重复计算扩展到任意维度。
6. 二维卷积
在深度学习中,图像可以看作是一个离散的二维实体,即描述某个固定时间场景的二维像素值数组。使用卷积从图像中提取局部模式时,不能简单地将图像光栅化为向量并应用一维卷积,因为二维邻域关系在光栅化过程中会丢失。
二维卷积可以想象成一个瓷砖(核)在墙壁(输入图像)上滑动。在滑动过程中,瓷砖的不同位置对应不同的滑动停止点,每个滑动停止点会产生一个输出元素。随着瓷砖从左到右、从上到下扫过整个墙壁,会生成一个二维输出数组。
二维卷积中的输入数组、核大小、步长都是二维向量。相关定义如下:
- 输入 :二维数组,通常用 $[H, W]$ 表示其大小,分别代表数组的高度和宽度。
- 输出 :二维数组,用 $\vec{o} = [o_H, o_W]$ 表示其维度。
- 核 :一个小的二维权重数组,用 $\vec{k} = [k_H, k_W]$ 表示其大小(高度、宽度)。
- 步长 :用 $\vec{s} = [s_H, s_W]$ 表示,控制核每次滑动的输入元素数量。步长会影响输出大小,例如,步长为 $[1, 1]$ 时,输出元素数量与输入大致相同;步长为 $[2, 2]$ 时,输出大小大约是输入的四分之一。
- 填充 :分为有效填充和相同(零)填充。有效填充是指当核的任何元素超出输入数组时停止滑动;相同(零)填充是指只要核的左上角落在有效输入位置就继续滑动,当步长为 $[1, 1]$ 时,输出大小与输入大小相同,超出输入数组边界的幽灵输入值用零代替。
综上所述,卷积操作在深度学习中具有重要作用,无论是一维卷积还是二维卷积,都可以通过不同的核权重实现各种功能,如曲线平滑、边缘检测和图像特征提取等。在实际应用中,我们可以根据具体需求选择合适的卷积参数和填充策略,并利用深度学习框架(如 PyTorch)高效地实现卷积操作。
卷积操作的全面解析与实践(续)
7. 二维卷积的可视化与计算流程
二维卷积的可视化可以借助下面的 mermaid 流程图来理解:
graph LR
A[输入图像] --> B[核开始滑动]
B --> C{是否超出边界}
C -- 否 --> D[计算加权和]
D --> E[生成输出元素]
E --> F{是否滑完整个图像}
F -- 否 --> B
C -- 是 --> G{是否为有效填充}
G -- 是 --> H[停止滑动]
G -- 否 --> I[零填充继续滑动]
I --> B
F -- 是 --> J[生成二维输出数组]
在这个流程中,核从输入图像的左上角开始滑动,每到一个滑动停止点,就将核元素与覆盖的输入元素相乘并求和,得到一个输出元素。当核的部分超出输入图像时,根据填充策略决定是停止滑动(有效填充)还是进行零填充后继续滑动(相同零填充)。
为了更清晰地展示二维卷积的参数和操作过程,我们可以通过一个表格来总结:
| 参数 | 含义 | 示例 |
| ---- | ---- | ---- |
| 输入 $[H, W]$ | 二维输入数组的高度和宽度 | $[5, 5]$ |
| 输出 $\vec{o} = [o_H, o_W]$ | 二维输出数组的维度 | $[3, 3]$ |
| 核 $\vec{k} = [k_H, k_W]$ | 二维核的高度和宽度 | $[3, 3]$ |
| 步长 $\vec{s} = [s_H, s_W]$ | 核每次滑动的元素数量 | $[1, 1]$ 或 $[2, 2]$ |
| 填充 | 处理核超出输入边界的策略 | 有效填充、相同(零)填充 |
8. 二维卷积的应用场景
二维卷积在图像分析领域有着广泛的应用,以下是一些常见的应用场景:
- 图像模糊 :使用具有均匀权重的核进行二维卷积,可以对图像进行模糊处理,去除图像中的噪声,使图像看起来更加平滑。例如,使用一个 $3\times3$ 的平均核:
[
\begin{bmatrix}
\frac{1}{9} & \frac{1}{9} & \frac{1}{9} \
\frac{1}{9} & \frac{1}{9} & \frac{1}{9} \
\frac{1}{9} & \frac{1}{9} & \frac{1}{9}
\end{bmatrix}
]
- 边缘检测 :类似于一维卷积中的边缘检测,二维卷积可以使用具有反对称权重的核来检测图像中的边缘。例如,Sobel 算子是一种常用的边缘检测核,它可以分别检测水平和垂直方向的边缘。水平 Sobel 核为:
[
\begin{bmatrix}
-1 & 0 & 1 \
-2 & 0 & 2 \
-1 & 0 & 1
\end{bmatrix}
]
垂直 Sobel 核为:
[
\begin{bmatrix}
-1 & -2 & -1 \
0 & 0 & 0 \
1 & 2 & 1
\end{bmatrix}
]
- 特征提取 :在深度学习中,卷积神经网络(CNN)通过多个卷积层来提取图像的不同层次特征。不同的卷积核可以学习到图像中的不同特征,如纹理、形状等。
9. 二维卷积在 PyTorch 中的实现
在 PyTorch 中实现二维卷积与一维卷积类似,以下是一个简单的示例代码:
import torch
import torch.nn as nn
# 定义输入图像
x = torch.randn(1, 1, 5, 5) # 批量大小为 1,通道数为 1,高度为 5,宽度为 5
# 定义卷积核
w = torch.tensor([[[[0.1, 0.2, 0.1],
[0.2, 0.4, 0.2],
[0.1, 0.2, 0.1]]]], dtype=torch.float32)
# 创建卷积层
conv2d = nn.Conv2d(1, 1, kernel_size=3, stride=1, padding=1, bias=False)
# 设置卷积核权重
conv2d.weight = nn.Parameter(w, requires_grad=False)
# 进行卷积操作
with torch.no_grad():
y = conv2d(x)
print("输入图像形状:", x.shape)
print("输出图像形状:", y.shape)
在这个代码中,我们首先定义了一个随机的输入图像和一个卷积核,然后创建了一个二维卷积层,并将卷积核权重设置为我们定义的权重。最后,进行卷积操作并输出输入和输出图像的形状。
10. 卷积操作的总结与拓展思考
卷积操作是深度学习中非常重要的基础操作,它通过核在输入数据上的滑动和加权求和,实现了对数据的特征提取和处理。一维卷积适用于处理序列数据,如时间序列、音频信号等;二维卷积则广泛应用于图像分析领域。
在实际应用中,我们可以根据具体任务选择合适的卷积参数,如核大小、步长和填充策略。同时,还可以通过堆叠多个卷积层来构建更复杂的卷积神经网络,以学习更高级的特征。
此外,卷积操作还有一些拓展形式,如三维卷积,可用于处理视频数据;分组卷积和深度可分离卷积等,这些拓展形式可以在减少计算量的同时保持较好的性能。未来,随着深度学习的不断发展,卷积操作可能会在更多领域得到应用和创新。
通过对卷积操作的深入理解和实践,我们可以更好地掌握深度学习的核心技术,为解决各种实际问题提供有力的工具。
超级会员免费看
11万+

被折叠的 条评论
为什么被折叠?



