API记录之杂类篇
API记录之杂类篇
模型
ResNet18
ResNet18是一种深度残差网络,它由18层组成。它的结构包括一个输入层、四个残差块和一个输出层。每个残差块包含两个3x3的卷积层,每个卷积层后面都跟着一个Batch Normalization和ReLU激活函数。此外,每个残差块还包含一条跨层的连接线,将输入直接连接到输出。这种设计使得网络能够更好地处理深层特征,并且可以避免梯度消失问题。ResNet18在图像分类任务中表现出色,可以用于训练大型数据集,如ImageNet。
Bert
pooler_output 的输出用于捕获整个句子的全局语义信息:

公式&定理
通用近似定理
以下内容来自: << 神经网络与深度学习 >> 4.3.1 通用近似定理
根据通用近似定理,对于具有线性输出层和至少一个使用“挤压”性质的激活函数的隐藏层组成的前馈神经网络,只要其隐藏层神经元的数量足够,它可以以任意的精度来近似任何一个定义在实数空间中的有界闭集函数.所谓“挤压”性质的函数是指像Sigmoid函数的有界函数,但神经网络的通用近似性质也被证明对于其他类型的激活函数,比如ReLU,也都是适用的.
个人对上述内容的理解
通用近似定理中“隐藏层神经元的数量足够”这一条件,与多项式逼近(如泰勒展开)中 '增加阶数提高精度' 的思想有深刻的相似性,但神经网络的非线性基函数组合比传统多项式逼近更灵活。以下是具体分析:
逼近方式 | 多项式逼近(泰勒展开) | 神经网络逼近 |
---|---|---|
基函数 | 单项式基 | 非线性激活后的基 |
组合方式 | 线性加权和 | 线性加权和 |
逼近原理 | 增加阶数 | 增加神经元数量 |
函数空间 | 多项式函数空间 | 自适应生成的非线性函数空间 |
关键共同点:
- 两者都通过增加基函数的数量(多项式阶数/神经元数量)来扩大逼近空间的容量,从而提升对目标函数的拟合精度。
神经网络的独特优势:
自适应基函数
多项式逼近的基函数是固定的(如
),而神经网络的基函数 的形状和位置(由权重 决定)可通过训练动态调整,更灵活适应目标函数。示例:拟合分段函数时,ReLU神经元可自动学习“转折点”,而多项式需极高阶数才能近似突变。
维度诅咒的缓解
- 在高维空间(
)中,多项式逼近需要 项(指数增长),而神经网络通过非线性激活和分层结构,可能以 神经元实现相同精度。
- 在高维空间(
对非平滑函数的适应性
- 泰勒展开要求函数无限可微,而神经网络(如使用ReLU)可逼近连续但不可微的函数(如
)。
- 泰勒展开要求函数无限可微,而神经网络(如使用ReLU)可逼近连续但不可微的函数(如
案例:逼近区间
多项式逼近: 需高阶泰勒展开
,且高次项易导致震荡(龙格现象)。神经网络逼近: 仅需4个Tanh神经元即可高精度拟合,因基函数
能自适应频率和相位。
理论限制的相似性:
逼近精度与代价的权衡
多项式:高阶项导致数值不稳定(如大数相减损失精度)。
神经网络:神经元过多易过拟合,且训练难度增加(梯度消失/爆炸)。
全局逼近 vs 局部逼近
多项式:调整某一系数会影响全局拟合。
神经网络:可通过局部神经元(如ReLU)实现分段逼近,更适应局部特征。
现代深度学习的延伸: 深层神经网络通过函数复合(Function Composition)能够以指数级减少所需的神经元数量,核心原因在于层次化的函数构造方式比单层网络的线性组合更高效。这与多项式逼近等传统方法有本质区别,具体可以从以下几个方面理解:
1. 函数复合 vs. 线性组合:数学本质对比
单层网络(线性组合):
单隐藏层神经网络的输出形式为:
它通过一组非线性基函数((\sigma))的加权和逼近目标函数,类似于多项式逼近中的基函数组合。要逼近复杂函数,可能需要大量神经元((N) 极大)。
深层网络(函数复合):
层网络的输出是多次复合的结果:每一层
都是一个非线性变换(如 )。通过逐层抽象,深层网络可以逐步构造出更复杂的函数。
关键区别:
单层网络依赖基函数的数量(宽度)来增加表达能力。
深层网络依赖函数的嵌套深度,通过分层组合简单函数,实现复杂功能。
2. 为什么函数复合更高效?
(1) 分治策略(Divide-and-Conquer)
深层网络将复杂函数分解为多个简单步骤,每一层只需学习局部特征,最后组合成全局解。例如:
目标函数:拟合一个“锯齿波”
单层网络:需要大量神经元构造多个“转折点”。
深层网络:每层学习一个转折点,通过复合实现指数级增长的分段线性区域(如
层ReLU网络可生成 个分段)。
(2) 指数级表达能力
理论结果:
Telgarsky (2016) 证明:用深度
的ReLU网络可以构造具有 个线性区域的函数,而单层网络需要 个神经元才能达到相同效果。直观理解:每一层的非线性变换(如ReLU)相当于对输入空间进行一次“折叠”,深度叠加导致表达能力爆炸式增长。
网络类型 | 所需神经元/层数 | 表达能力增长方式 |
---|---|---|
单层宽网络 | 线性增长(基函数叠加) | |
深层网络 | 指数增长(函数复合) |
(3) 参数复用与模块化
深层网络通过共享参数(如卷积核)和模块化设计(如残差块),进一步减少冗余:
- 示例:CNN中,同一卷积核在不同位置重复使用,避免为每个像素单独建模。
3. 与多项式逼近的对比
多项式逼近通过增加阶数(如泰勒展开)提升精度,但存在两大局限:
全局性:调整某一系数会影响整个函数,难以局部修正。
维度灾难:高维输入时,多项式项数
爆炸式增长。
而神经网络的函数复合:
局部性:每层聚焦不同抽象层次(如边缘→纹理→物体)。
维度友好:通过分层降维(如池化)逐步压缩信息。
4. 实例说明
案例1:逼近“多次折叠”的函数
目标函数:
单层网络:需数百个神经元拟合嵌套正弦波。
深层网络:3层即可,每层对应一个
操作。
案例2:图像分类
单层网络:需直接建模像素到类别的复杂映射,参数量极大。
深层CNN:逐层提取边缘→纹理→部件→物体,参数量更少。
5. 理论支持
深度分离定理(Depth Separation Theorem): 存在某些函数,用浅层网络逼近需要指数级神经元,而深层网络只需多项式数量(如 Eldan & Shamir, 2016)。
电路理论类比: 深层网络类似布尔电路中的分层设计(如AND-OR门组合),比单层电路更高效。
6. 深层网络的代价
虽然深度减少了神经元数量,但带来了:
优化难度:梯度消失/爆炸问题。
过拟合风险:需正则化(如Dropout)。
计算开销:并行化要求更高。
总结:
神经网络通过非线性激活函数生成的动态基函数组合,实现了比多项式逼近更高效的函数近似。虽然“增加神经元数量”与“提高多项式阶数”在思想上都体现了用更多自由度提升精度,但神经网络的自适应基函数和分层结构使其:
对高维和非平滑函数更鲁棒
避免了手工设计基函数的局限性
在实践中通过梯度下降自动学习逼近策略
ROI Pooling
在目标检测任务中,比如 Faster R-CNN,我们会从一张图片中生成多个候选区域(ROI),这些区域的大小各不相同。而神经网络的全连接层只能接受固定大小的输入,这就产生了一个问题:
- 如何将不同尺寸的ROI特征,统一变为相同尺寸?
ROI Pooling 的目标就是: 从不同大小的 ROI 区域中提取固定大小的特征(例如 7×7),同时保留最有代表性的空间信息。

ROI Pooling 的操作流程可以分为三个步骤:
- 映射 ROI 到特征图空间
假设输入图像经过卷积得到一个特征图(例如从 ResNet 输出的特征图),而我们检测到一个 ROI(例如在原图上坐标为
由于特征图的尺寸比原图小(通常是原图的 1/16),我们需要先将 ROI 坐标 映射到特征图上:
其中 stride 是特征图相对于原图的缩放比例。

- 将该 ROI 划分成固定数量的网格区域
例如我们希望将每个 ROI 转换成 7×7 的特征图,那么就把该 ROI 分成 7 行 × 7 列的 小块(每一小块大小不同,但数目固定)。

- 每个小块做 max pooling
对每个小块区域做 最大池化(Max Pooling),取出该区域内的最大值,这样就将原本不定尺寸的 ROI 转换成一个固定大小的特征图(例如 7×7)。

假设某个 ROI 映射到特征图上之后是一个大小为 14×14 的区域,我们希望输出一个 7×7 的固定大小特征图。
- 将 14×14 区域划分为 7×7 的网格(每个网格是 2×2 大小)
- 对每个 2×2 的小格子做最大池化 → 输出一个 7×7 特征图
⚠️ ROI Pooling 有一个问题:量化误差。
ROI Pooling 的划分方式中涉及到了取整(floor/ceil),这在某些场景下会导致位置偏差、信息丢失。
为了更精确,Mask R-CNN 提出了更先进的方法:ROI Align,它使用双线性插值来避免量化误差,使得检测/分割性能更好。
ROI Align
ROIAlign 是 Mask R-CNN 中为了解决 RoIPooling 引起的对齐误差问题而提出的关键组件。
RoIPool(Region of Interest Pooling) 是 Faster R-CNN 中的标准组件,用于将任意大小的候选框(RoI)转换为固定大小(例如 7×7)的特征图,以便送入全连接层进行分类和回归。
问题: RoIPool 在处理浮点型的 RoI 坐标时进行了两次量化(quantization)操作:
RoI 边界坐标的量化(例如将 x/16 向下取整);
池化 bin 分割时的量化(每个 bin 的边界坐标再取整)。
这会导致特征图上的空间对齐误差(misalignment),尤其对 像素级别任务如分割 影响显著。
RoIAlign目标:消除量化误差,实现精确的像素级对齐。
实现步骤如下:
- 不进行任何量化
- 保留浮点型的 RoI 坐标值(例如 x/16 而不是 [x/16]),也不对 bin 边界进行离散化。
- 对每个 bin 采样多个点(如 2×2)
将 RoI 分成固定数量的 bin(例如 7×7)。
每个 bin 中选定若干个浮点坐标点(通常为4个采样点,中心或等距分布)。
+----------+
| * * |
| |
| |
| * * |
+----------+
每个 * 就是一个采样点,它们分布在 4 个角的中间位置,平均对称。
- 使用双线性插值(Bilinear Interpolation)提取特征值
- 由于坐标是浮点数,不对应实际的 feature map 网格点,因此使用四邻域双线性插值从特征图中获取精确的 feature 值。
你要在 (3.6, 5.2) 点上取值:
- 它离 (3,5) 的距离是 (1 - 0.6) * (1 - 0.2) = 0.4 * 0.8 = 0.32
- 它离 (4,5) 的距离是 0.6 * 0.8 = 0.48
- 它离 (3,6) 的距离是 0.4 * 0.2 = 0.08
- 它离 (4,6) 的距离是 0.6 * 0.2 = 0.12
于是你把这 4 个点的值按这个比例加起来,就得到了 (3.6, 5.2) 的值。
就像你在地图上两个村庄中间估算温度时,不会只看一个村,而是综合周围村子的情况加权得出。
每个撒下去的小数点都用周围的4个整数点去“平均估计”(双线性插值);
- 对采样点的值进行聚合
可以采用 max 或 average(论文推荐 average)。
每个 bin 的最终输出为这些采样点值的聚合结果。
图示(见论文 Figure 3):
- 实线为 RoI,虚线为 feature map 网格,黑点为采样点,通过插值获得值后聚合。
RoIAlign 就是:
先把目标区域平均切成小格子(比如 7×7);
在每个小格子里撒几个点(比如 2×2);
每个撒下去的小数点都用周围的4个整数点去“平均估计”(双线性插值);
最后把所有点的值求平均,就得到了这个格子的特征。
上采样
torch.nn.functional.interpolate(
input,
size=None,
scale_factor=None,
mode='nearest',
align_corners=None,
recompute_scale_factor=None
)
参数 | 说明 |
---|---|
input | 输入张量,形状 [N, C, H, W] (2D)或 [N, C, D, H, W] (3D) |
size | 输出的目标尺寸 (H_out, W_out) ,与 scale_factor 互斥 |
scale_factor | 缩放因子 (fH, fW) ,用于等比例放大或缩小 |
mode | 插值方式: 'nearest' , 'bilinear' , 'bicubic' , 'trilinear' , 'area' |
align_corners | 对双线性或双三次插值是否对齐角点,默认 None |
recompute_scale_factor | 是否重新计算缩放因子,默认 None |
最近邻 (nearest) 插值
最近邻插值是最简单的一种上采样方法:
对于要插值的每个输出像素点,找到它在输入中的 最近的一个像素,直接把这个像素的值赋给输出像素。
不会对像素值进行加权平均或平滑处理,所以原本的格子边界保持得很清晰。
适合用于 离散格子 或 掩码、标签图,因为不会引入新的中间值。
公式描述:
假设输入特征图大小为 (H_in, W_in)
,输出大小为 (H_out, W_out)
:
其中 round
表示取最接近的整数索引。
一个简单的例子如下所示:
输入 X:
[[10, 20],
[30, 40]]
--放大两倍-->
输出 Y:
[[10, 10, 20, 20],
[10, 10, 20, 20],
[30, 30, 40, 40],
[30, 30, 40, 40]]
双线性 (bilinear) 插值
双线性插值是一种常用的图像放大/缩小方法,它的核心思想是 对输出像素使用周围四个输入像素的加权平均,从而获得平滑的过渡效果。
输入:一幅图像
H_in × W_in
输出:目标大小
H_out × W_out
对输出图像中的每个像素,找到它在输入图像对应的浮点坐标
(x, y)
,并使用其周围的 2×2 像素进行插值。
假设输出坐标映射到输入坐标 (x, y)
,周围四个像素为:
(x0, y0) ---- (x1, y0)
| |
| |
(x0, y1) ---- (x1, y1)
对应的像素值分别为
Q11, Q21, Q12, Q22
插值公式:
直观理解:x方向和y方向的线性插值的叠加 → 因此叫“双线性”
特点 | 说明 |
---|---|
平滑 | 输出图像像素值是周围四个输入像素加权平均,边界过渡自然 |
精度高于最近邻 | 不会产生块状感,适合图像缩放 |
适合连续值 | 对热力图、注意力图、彩色图像非常友好 |
较慢 | 需要计算权重和加权平均,比最近邻计算量大 |
余弦相似度
余弦相似度(Cosine Similarity)是一种常用的衡量两个向量相似度的方法,特别常用于文本向量、推荐系统、信息检索等场景。
公式如下:
其中:
:两个向量(维度相同)。 :向量的点积。 :向量 的欧几里得范数(长度)。 。 :向量 和 之间的夹角。
取值范围:
,其中:越接近 1 表示两个向量方向越接近(相似度高)。
越接近 0 表示两个向量几乎正交(不相似)。
越接近 -1 表示两个向量方向相反。
L1 归一化(L1 Normalization)
定义:把向量中每个元素除以向量元素的绝对值之和,使得归一化后的向量的 L1 范数 = 1。
公式:
特点:
保留向量的方向信息,但缩放到总和为 1。
常用于特征和概率分布处理,比如文本的 TF-IDF 向量。
L2 归一化(L2 Normalization)
定义:把向量中每个元素除以向量的欧几里得长度,使得归一化后的向量的 L2 范数 = 1。
公式:
特点:
保留向量方向,但长度固定为 1。
在计算余弦相似度、梯度下降等场景中非常常用。
L1 归一化 → 保证绝对值之和 = 1(稀疏向量处理好)。
L2 归一化 → 保证长度 = 1(方向为主,长度固定)。