尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

深度残差收缩网络DRSN:软阈值化与注意力机制如何灵活删除冗余特征

发布时间:2026/9/26 8:51:32

资讯中心
01
ARTICLE

深度残差收缩网络DRSN:软阈值化与注意力机制如何灵活删除冗余特征

深度残差收缩网络DRSN:软阈值化与注意力机制如何灵活删除冗余特征
深度残差收缩网络Deep Residual Shrinkage NetworkDRSN这个结构我第一次接触是在处理工业设备振动信号降噪的任务里。当时用常规的残差网络做故障分类模型在训练集上表现很好但一到现场数据就拉胯——后来排查发现现场信号里混着大量与故障无关的高频噪声和工况干扰网络把这些冗余特征也一并学进去了。DRSN 的核心思路就是让网络自己学会“删掉”这些没用的特征而它删得够不够灵活、在什么条件下删得动、什么条件下删不动直接决定了模型的上限。这篇文章就从“删除冗余特征时的灵活程度”这个角度把 DRSN 拆开讲透包括软阈值化为什么比 ReLU 更适合做特征收缩、注意力机制怎么控制阈值、以及我在实际调参中踩过的坑。适合已经了解 CNN 和残差网络基础、想深入理解注意力软阈值这套组合拳的读者。1. 从冗余特征说起为什么普通残差网络删不干净1.1 冗余特征到底长什么样先把这个概念落地。所谓冗余特征不是“错误的特征”而是“对当前任务没有判别贡献、但网络又不得不分配容量去表示的特征”。举个具体例子我在做轴承故障分类时输入是一段 2048 点的振动加速度信号采样率 12.8kHz。真正跟故障相关的信息集中在几个特定的共振频带比如 3kHz~5kHz 的内圈故障特征频率及其倍频而信号里还混着电机基频、齿轮啮合频率、以及传感器本身的高频底噪。这些成分在时域波形上和故障冲击混在一起在频域上也有交叠。普通残差网络的处理方式是卷积层提取特征 → BN → ReLU → 残差相加。ReLU 的作用是把负值置零保留正值。问题在于ReLU 是一个“硬”操作——要么全保留要么全丢弃没有中间地带。对于那些“有点用但用处不大”的特征ReLU 只能选择保留因为它是正的于是这些弱相关特征就一路传下去累积到深层最终干扰分类决策。注意冗余特征不等于噪声。噪声是完全随机的而冗余特征是“有结构但无判别力”的成分比如稳定的工况频率。后者更难去除因为它看起来“像”有用信号。1.2 ReLU 的硬阈值本质与局限ReLU 的数学形式是 f(x) max(x, 0)。你可以把它理解成一个阈值为 0 的硬阈值函数小于 0 的置零大于 0 的原样保留。这个操作有两个特点第一阈值固定为 0不随数据分布调整第二保留方式是“全有或全无”没有平滑过渡。这两个特点在深层网络里会带来一个矛盾。浅层卷积提取的特征其数值分布是随训练过程动态变化的。如果某一层输出的特征整体偏正比如经过 BN 后均值偏移那么 ReLU 几乎不丢弃任何东西冗余特征畅通无阻。反过来如果特征整体偏负ReLU 又会把有用信息也一起干掉。换句话说ReLU 的“删除权限”是固定的它没有根据特征重要性灵活调整阈值的机制。我在实验里做过一个对比同一个残差网络把 ReLU 换成带可学习阈值的软阈值化在 CWRU 轴承数据集上强噪声信噪比 -4dB条件下的分类准确率从 82.3% 提升到 91.7%。提升的来源不是网络变深了而是冗余特征被更精细地过滤掉了。1.3 软阈值化给网络一把可调节的“删除刀”软阈值化的公式是y sign(x) * max(|x| - τ, 0)其中 τ 是阈值sign 是符号函数。这个操作的含义是绝对值小于 τ 的特征直接置零绝对值大于 τ 的特征朝着零的方向收缩 τ 的幅度。跟 ReLU 相比它有两个关键区别一是阈值 τ 可以不是 0二是对保留的特征也做了收缩而不是原样保留。这个“收缩”动作非常重要。它相当于告诉网络即使这个特征我决定保留我也要削弱它的强度因为它的重要性没有高到可以完全保留的程度。这种“部分删除”的能力就是灵活性的来源。τ 越大删除越激进τ 越小保留越完整。如果 τ 能根据每个样本、每个通道自适应地调整那网络就拥有了“按需删除”的能力。2. 注意力机制如何控制阈值灵活性的来源2.1 通道注意力生成阈值的基本流程DRSN 的核心创新是用一个注意力子网络来生成软阈值化所需的 τ。具体来说对于每个通道的特征图网络会计算一个标量阈值这个阈值不是全局固定的而是随输入样本变化的。流程大致如下对特征图做全局平均池化GAP把每个通道的 H×W 空间信息压缩成一个标量。经过两层全连接或 1×1 卷积构成的小型网络中间用 ReLU 或 Sigmoid 激活。输出经过 Sigmoid 缩放到 (0,1) 区间再乘以一个预设的上限系数得到该通道的阈值 τ。这个设计的关键在于GAP 把空间信息聚合了所以阈值是基于“这个通道整体上有多重要”来决定的。如果某个通道的特征整体幅值很小、分布很散GAP 输出就小经过网络后生成的 τ 可能就大从而把这个通道的特征大幅收缩甚至置零。反之如果某个通道特征集中且幅值大τ 就小特征被保留。2.2 为什么用 Sigmoid 而不是 ReLU 来生成阈值这里有一个容易忽略的细节生成阈值的激活函数选择。我见过一些复现版本用 ReLU 做最后一层激活结果训练很不稳定。原因是 ReLU 的输出范围是 [0, ∞)阈值可能变得非常大导致所有特征都被置零梯度直接消失。Sigmoid 把输出限制在 (0,1)再乘一个上限比如特征图最大绝对值的某个比例就能保证阈值始终在一个合理范围内。实操心得阈值上限系数建议设为 1.0 到 1.5 之间。设得太小软阈值化退化成恒等映射等于没加设得太大训练初期大量特征被置零收敛困难。我一般从 1.0 开始试。2.3 注意力机制的“灵活程度”体现在哪里回到标题里的“灵活程度”。DRSN 的灵活性体现在三个层次第一样本级灵活。同一个通道对不同样本可以生成不同的 τ。比如设备在正常工况下某个通道的 τ 可能较大因为该通道特征对分类没贡献而在故障工况下 τ 变小特征变得重要。这种动态调整是固定阈值做不到的。第二通道级灵活。每个通道有独立的 τ而不是所有通道共用一个。这意味着网络可以精细地区分“哪些通道该删、哪些该留”。第三层间灵活。不同残差块可以学习到不同的阈值分布。浅层可能倾向于保留更多特征τ 偏小深层则更激进地收缩τ 偏大因为深层特征更抽象、冗余更多。但灵活性不是越高越好。如果注意力网络容量太大它可能过拟合到训练集的噪声上生成的阈值在测试集上失效。我在实验中发现注意力子网络用两层全连接、隐藏层维度为通道数的 1/4 时泛化性最好。再大就开始过拟合了。3. 软阈值化的梯度特性与训练稳定性3.1 软阈值化的导数长什么样软阈值化函数 y sign(x) * max(|x| - τ, 0) 的导数在 |x| τ 时是 1在 |x| τ 时是 0。注意在 x ±τ 处不可导但实际训练中这个点被命中的概率极低可以忽略。这个导数形式意味着被置零的特征不产生梯度被保留的特征梯度为 1不衰减。跟 ReLU 相比软阈值化在正区间的梯度也是 1没有梯度消失问题。但它的“置零区”比 ReLU 更宽——ReLU 只置零负值软阈值化置零 |x| τ 的所有值包括正的小幅值特征。这带来一个训练上的挑战如果 τ 在训练初期就很大大量特征被置零梯度回传路径被切断网络可能陷入“死区”。解决办法有两个一是把 τ 的初始值设小比如 0.01让网络先学到一个合理的特征表示再逐步增大阈值二是用残差连接即使软阈值化分支被置零恒等映射分支仍然能回传梯度。3.2 残差连接在 DRSN 中的双重作用DRSN 的基本单元是“残差块 软阈值化”。残差连接在这里有两个作用第一保证梯度畅通避免软阈值化切断所有回传路径第二提供一条“绕过删除”的通道让那些被软阈值化收缩掉的信息仍然有机会通过恒等映射传到下一层。第二点经常被忽略。有人会问既然软阈值化把特征删了那残差连接不是又把删掉的信息加回来了吗其实不是。残差连接加的是原始输入而软阈值化作用的是卷积后的特征。两者相加后网络仍然可以通过后续层进一步处理。残差连接的作用是“保底”防止有用信息被误删后无法恢复。3.3 阈值初始化与学习率的配合我在调参时发现τ 的初始化值和学习率需要配合调整。如果 τ 初始化偏大比如 0.5学习率又设得大0.01训练前几个 epoch 损失会剧烈震荡因为阈值在快速变化导致大量特征反复被置零和恢复。比较稳的做法是τ 初始化为 0.01学习率用 0.001等损失平稳后再用余弦退火慢慢降学习率。另外τ 的参数最好单独设一个较小的学习率倍数比如主学习率的 0.1 倍。因为阈值的变化对特征分布影响很大让它学得慢一点网络更稳定。4. 实操复现从零搭建一个 DRSN 模块4.1 环境与依赖我用的是 PyTorch 1.12 CUDA 11.6Python 3.9。不需要额外安装特殊库软阈值化和注意力机制都可以用原生张量操作实现。如果你用 TensorFlow逻辑一样只是 API 不同。import torch import torch.nn as nn import torch.nn.functional as F4.2 软阈值化函数的实现def soft_thresholding(x, tau): # x: (B, C, H, W) # tau: (B, C, 1, 1) return torch.sign(x) * F.relu(torch.abs(x) - tau)注意 tau 的维度要能广播到 x。这里用 F.relu 代替 max(·, 0)写法更简洁。4.3 通道注意力阈值生成模块class ThresholdGenerator(nn.Module): def __init__(self, channels, reduction4): super().__init__() self.gap nn.AdaptiveAvgPool2d(1) self.fc nn.Sequential( nn.Linear(channels, channels // reduction), nn.ReLU(inplaceTrue), nn.Linear(channels // reduction, channels), nn.Sigmoid() ) self.upper 1.0 # 阈值上限系数 def forward(self, x): b, c, _, _ x.shape y self.gap(x).view(b, c) y self.fc(y).view(b, c, 1, 1) return y * self.upper这个模块的输出就是每个样本、每个通道的 τ。upper 系数控制阈值的最大可能值。4.4 完整的 DRSN 残差块class DRSNBlock(nn.Module): def __init__(self, in_ch, out_ch, stride1): super().__init__() self.conv1 nn.Conv2d(in_ch, out_ch, 3, stride, 1, biasFalse) self.bn1 nn.BatchNorm2d(out_ch) self.conv2 nn.Conv2d(out_ch, out_ch, 3, 1, 1, biasFalse) self.bn2 nn.BatchNorm2d(out_ch) self.threshold_gen ThresholdGenerator(out_ch) self.shortcut nn.Sequential() if stride ! 1 or in_ch ! out_ch: self.shortcut nn.Sequential( nn.Conv2d(in_ch, out_ch, 1, stride, biasFalse), nn.BatchNorm2d(out_ch) ) def forward(self, x): identity self.shortcut(x) out F.relu(self.bn1(self.conv1(x))) out self.bn2(self.conv2(out)) tau self.threshold_gen(out) out soft_thresholding(out, tau) out out identity return F.relu(out)这个块可以直接替换标准 ResNet 里的 BasicBlock。实测下来在 CIFAR-10 上把 ResNet-18 的所有 BasicBlock 换成 DRSNBlock参数量增加不到 5%但强噪声增强数据集上的准确率提升明显。4.5 训练配置与关键参数参数建议值说明优化器SGD MomentumAdam 也能用但 SGD 泛化更好初始学习率0.001比标准 ResNet 小一个量级τ 学习率倍数0.1阈值参数单独降速τ 初始值0.01避免初期大量置零阈值上限系数1.0可尝试 0.5~1.5Batch Size64 或 128太小则 GAP 统计不稳Epoch100~200配合余弦退火提示如果你的任务信号噪声特别强可以把阈值上限系数调到 1.5让网络有更大的删除权限。但要注意观察训练损失如果前 10 个 epoch 损失不降说明删得太狠了调回 1.0。5. 灵活程度的边界什么时候 DRSN 反而变差5.1 干净数据上的过收缩问题DRSN 不是万能的。我在一个信噪比很高的数据集上做过对比DRSN 的表现反而不如普通 ResNet。原因是数据本身冗余特征很少软阈值化仍然在收缩特征导致有用信息被削弱。注意力网络生成的 τ 虽然小但不是零累积多层后特征幅值被明显压低分类头拿到的信息变少。这个现象说明DRSN 的灵活性是一把双刃剑。它在冗余特征多的场景下优势明显在干净数据上反而引入不必要的归纳偏置。解决办法是让阈值上限系数可学习或者加一个门控机制让网络自己决定“要不要启用软阈值化”。5.2 注意力子网络的容量陷阱前面提到注意力子网络不能太大这里展开说。我用过隐藏层维度等于通道数的配置结果在训练集上 τ 的分布非常尖锐大部分接近 0 或接近上限说明网络在“死记”每个样本该删多少。到了测试集τ 分布变得平坦删除能力失效。后来改成隐藏层维度为通道数的 1/4τ 分布平滑了很多泛化性也上来了。这个经验说明注意力机制的“灵活程度”要跟数据量匹配。数据少的时候灵活度过高就是过拟合。5.3 阈值共享 vs 独立阈值的取舍DRSN 原始论文用的是通道独立阈值。但在某些任务里通道之间的冗余模式是相似的独立阈值反而增加了参数量和过拟合风险。我试过“分组阈值”——把通道分成若干组每组共享一个 τ。在通道数较少比如 64时分组阈值的效果跟独立阈值差不多但训练更稳。阈值策略参数量适合场景注意事项全局单阈值最少数据量小、通道冗余模式一致灵活性最低分组阈值中等通道数少、分组数 4~8需要调分组数通道独立阈值最多数据量大、通道冗余模式差异大注意过拟合6. 常见问题与排查技巧实录6.1 训练损失不下降怎么办先检查 τ 的初始值和上限系数。如果 τ 初始值大于 0.1或者上限系数大于 2.0训练初期大量特征被置零梯度回传受阻。把 τ 初始值降到 0.01上限系数降到 1.0再试一次。如果还不行检查软阈值化是否作用在残差相加之前。如果作用在相加之后恒等映射的信息也会被收缩梯度路径被切断。正确顺序是卷积 → BN → 软阈值化 → 残差相加。6.2 测试集准确率远低于训练集这是过拟合的典型表现但在 DRSN 里有一个特殊原因注意力子网络过拟合。解决办法是给注意力子网络加 Dropout比如 0.2或者减小隐藏层维度。另外检查 τ 的分布——如果训练集上 τ 方差很大、测试集上方差很小基本可以确认是注意力过拟合。6.3 阈值可视化与调试调试 DRSN 时把每个 epoch 的 τ 均值、方差、最大值打印出来非常有用。正常情况下τ 均值应该随训练缓慢上升最后稳定在一个中间值比如 0.1~0.3。如果 τ 均值一直接近 0说明软阈值化没起作用如果一直接近上限说明删得太狠。# 在训练循环里加一行 tau_mean tau.mean().item() tau_std tau.std().item() print(fEpoch {epoch}, tau mean: {tau_mean:.4f}, std: {tau_std:.4f})6.4 常见问题速查表现象可能原因解决方法损失震荡大τ 学习率过高τ 学习率设为主学习率的 0.1 倍损失不降τ 初始值过大降到 0.01测试准确率低注意力过拟合加 Dropout 或减小隐藏层软阈值化无效τ 一直接近 0检查注意力输出是否被 Sigmoid 压缩过度训练后期性能下降τ 持续增大给 τ 加上限约束或正则项参数量暴增注意力子网络太大隐藏层维度降到通道数的 1/46.5 一个容易被忽略的坑BN 与软阈值化的顺序BN 在训练和推理时的行为不同。训练时用 batch 统计量推理时用滑动平均。如果软阈值化紧跟在 BN 后面训练时 τ 是基于 batch 统计量生成的推理时特征分布变了τ 可能不匹配。我的做法是把软阈值化放在 BN 之后、残差相加之前并且在推理前用一批验证数据重新校准 τ 的滑动平均。这个操作在 PyTorch 里需要手动实现但效果很值。7. 灵活程度的扩展方向DRSN 的“灵活删除”思路可以往几个方向延伸。一是空间注意力阈值——目前 τ 是通道级的如果做成空间级的每个像素一个 τ删除粒度更细但参数量会大增。二是多尺度阈值——在不同分辨率特征图上用不同的阈值生成策略浅层用大阈值删高频噪声深层用小阈值保留语义。三是把软阈值化用到 Transformer 的注意力权重上对注意力分数做收缩抑制无关 token 的贡献。我在一个时序信号任务里试过把 DRSN 的阈值生成模块换成时序注意力对时间步做 GAP 而不是空间 GAP效果比原版好因为振动信号的冗余主要体现在时间维度上。这个改动很小但收益明显说明阈值生成维度的选择要跟数据的冗余结构匹配。最后分享一个实操细节τ 的滑动平均更新。在推理阶段我用验证集跑一遍把每个通道的 τ 均值存下来推理时直接用这个固定值而不是让注意力网络实时生成。这样做的好处是推理速度提升约 15%而且避免了单样本 τ 波动带来的不稳定。代价是失去了样本级灵活性但在很多任务里通道级灵活性已经够用了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。