34、卷积操作的全面解析与实践

卷积操作的全面解析与实践

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. 卷积操作的总结与拓展思考

卷积操作是深度学习中非常重要的基础操作,它通过核在输入数据上的滑动和加权求和,实现了对数据的特征提取和处理。一维卷积适用于处理序列数据,如时间序列、音频信号等;二维卷积则广泛应用于图像分析领域。

在实际应用中,我们可以根据具体任务选择合适的卷积参数,如核大小、步长和填充策略。同时,还可以通过堆叠多个卷积层来构建更复杂的卷积神经网络,以学习更高级的特征。

此外,卷积操作还有一些拓展形式,如三维卷积,可用于处理视频数据;分组卷积和深度可分离卷积等,这些拓展形式可以在减少计算量的同时保持较好的性能。未来,随着深度学习的不断发展,卷积操作可能会在更多领域得到应用和创新。

通过对卷积操作的深入理解和实践,我们可以更好地掌握深度学习的核心技术,为解决各种实际问题提供有力的工具。

内容概要:本文围绕六自由度机械臂的人工神经网络(ANN)设计展开,重点研究了正向逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程,并通过Matlab代码实现相关算法。文章结合理论推导仿真实践,利用人工神经网络对复杂的非线性关系进行建模逼近,提升机械臂运动控制的精度效率。同时涵盖了路径规划中的RRT算法B样条优化方法,形成从运动学到动力学再到轨迹优化的完整技术链条。; 适合人群:具备一定机器人学、自动控制理论基础,熟悉Matlab编程,从事智能控制、机器人控制、运动学六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)建模等相关方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握机械臂正/逆运动学的数学建模ANN求解方法;②理解拉格朗日-欧拉法在动力学建模中的应用;③实现基于神经网络的动力学补偿高精度轨迹跟踪控制;④结合RRTB样条完成平滑路径规划优化。; 阅读建议:建议读者结合Matlab代码动手实践,先从运动学建模入手,逐步深入动力学分析神经网络训练,注重理论推导仿真实验的结合,以充分理解机械臂控制系统的设计流程优化策略。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值