尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

深度残差收缩网络DRSN:自适应软阈值机制如何灵活删除冗余特征

深度残差收缩网络DRSN:自适应软阈值机制如何灵活删除冗余特征 训练数据里全是噪声、干扰特征和与任务无关的细节时模型到底该怎么学我见过很多人一上来就换更大网络、堆更多参数但效果提升很有限。实际经验告诉我与其一味加大模型容量不如先从特征本身下手——把那些对分类没帮助、甚至会误导决策的冗余特征想办法删掉。深度残差收缩网络Deep Residual Shrinkage NetworkDRSN就是干这个事的它在残差网络里加入了一个可学习的软阈值机制把“删除冗余特征”这件事从固定规则变成了网络自己就能学会的柔性操作。这篇文章我想重点聊一个容易被人忽略的角度它删除冗余特征时到底有多灵活以及这种灵活性如何在工程上落地。1. 先把问题说清楚为什么删除冗余特征这么难1.1 冗余特征从哪来为什么越堆模型越没用很多刚接触深度学习的人会有个直觉模型容量不够那就加深、加宽总能把任务拟合出来。这句话在半干净的公开数据集上可能成立但放到工业现场、传感器数据、振动信号、真实拍摄图像里往往会碰一鼻子灰。原因很简单现实数据里到处都是冗余特征。图像里的背景纹理、光照变化振动信号里的工频干扰、随机噪声语音里的环境杂音这些信息对当前分类任务没有正贡献甚至会和目标特征混在一起把决策边界搅乱。冗余特征的麻烦在于网络并不知道哪些特征是“该看的”。如果只是增加网络宽度和深度模型会把大量参数浪费在拟合噪声上训练集分数很好看一到验证集或者新样本上就原形毕露。我自己做过带噪声的机械故障诊断振动信号里真正的故障冲击往往非常窄、非常弱旁边全是齿轮啮合和电机传来的强干扰。这种情况下再深的普通卷积网络也不一定扛得住因为它的“特征删除”逻辑太固化了。真正需要的是一种能根据当前输入自适应决定删除哪些特征、删除多少的机制。1.2 残差网络里的ReLU其实是一种“不灵活”的删除方式ResNet这类结构里信息每经过一次卷积几乎都要接一个ReLU。ReLU做的事情非常粗暴所有负值直接变0非负值原样保留。说它在“删除特征”其实有点勉强因为它的阈值固定死在0这个位置上既不看样本难度也不看通道重要性更不会随训练动态调整。举个例子假设某个特征通道里有用信号的幅值通常在0到2之间噪声幅值通常在-3到-1之间ReLU会把所有负噪声删掉但同时也把一部分处于负值区域的有效特征毁掉了。如果换成另一个样本噪声可能全部集中在正的小幅值区域ReLU就完全无能为力。另一种常见的删除手段是Dropout它按固定概率随机把神经元置零。随机性确实带来正则化效果但它不区分特征重要程度有可能丢掉关键特征。换句话说这两种机制都不具备根据输入内容“按需删除”的能力也就是题目里说的“灵活程度”不够。这就是DRSN出现的核心逻辑既然冗余特征的位置、幅值、通道分布都是随样本变化的那么删除特征的规则也应该是学习的、自适应的。1.3 软阈值收缩把“删除”改成“自己决定删多少”软阈值函数来自信号处理里的经典降噪方法表达很简洁对一个输入值x给定阈值τ输出 y sign(x) * max(|x| - τ, 0)。什么意思呢当特征绝对值小于τ时直接输出0当特征绝对值大于τ时不是原样保留而是减去一个τ。和ReLU不同的是ReLU只对负值下手阈值固定0软阈值可以对正负两侧都收缩而且阈值τ可以变大变小。更深一层软阈值可导性也不错导数只有0或1两档x ±τ处不可导但工程上不影响和ReLU在梯度传播上的性质接近不会带来严重梯度消失。放到深度网络里如果τ不是人工设的而是由一个小子网络根据当前输入计算出来的那么网络就相当于学会了“自己决定删多少特征”。这才是DRSN和普通残差网络最本质的区别删除冗余特征这件事从人肉调规则变成了端到端学习。2. 深度残差收缩网络的结构拆解与设计动机2.1 在残差单元里嵌一个阈值子网络DRSN的基本结构并不复杂本质上是在一个残差单元里插入了一个“收缩子模块”。前向过程大致是输入x先走卷积、批归一化、ReLU这些常规操作得到残差分支输出然后对这个特征图取绝对值做一次全局平均池化得到一个统计量这个统计量经过两三个全连接层和Sigmoid映射成0到1之间的缩放系数最后用这个系数乘以特征绝对值的均值得到真正的阈值。有一个设计细节非常关键软阈值化应该放在残差分支上而不是整个残差单元的最后输出上。如果对最终输出做软阈值化恒等映射x也会被直接置零或收缩网络就退化成普通VGG或者带噪声的路径残差学习的优势就没了。把收缩放在残差分支里网络可以选择“这条残差贡献的信息冗余程度高我删除一部分”同时恒等映射仍然原封不动把输入送到下一层。这个设计既保住了残差结构的信息高速公路又获得了特征删除能力。2.2 DRSN-CS和DRSN-CW两种灵活程度的差异原论文里给出了两种主要形态。第一种叫DRSN-CS通道共享阈值也就是说整个特征图用一个标量阈值做收缩。实现时全局平均池化会压成1个数然后经过子网络输出一个缩放系数。第二种叫DRSN-CW通道独立阈值每个通道单独计算一个阈值子网络输出的不是一个数而是一个长度为通道数的向量。这两种形态的差异很直观通道共享阈值更省参数也更适合冗余特征在所有通道上分布比较均匀的情况通道独立阈值灵活度更高适合不同通道噪声水平差异大的场景。工业信号里常见的情况是某些频率通道几乎全是噪声某些通道包含完整的故障特征如果强制它们共享同一个阈值就会出现“为了删噪声把信号也删了”或者“为了保信号把噪声也留了”的两难。DRSN-CW天然能避免这个问题。对比维度DRSN-CS通道共享DRSN-CW通道独立阈值粒度每层一个标量每层每个通道一个值新增参数很少每个通道多一组FC权重灵活程度中等高适用场景冗余特征分布均匀噪声分布复杂、通道差异大2.3 为什么阈值要乘以特征绝对值平均值如果子网络直接输出一个绝对值阈值比如0.1或者0.5这个值在不同层的特征尺度下完全不通用。浅层卷积特征值可能普遍偏大深层特征可能普遍偏小固定范围阈值要么删多、要么删少。DRSN的做法是让子网络输出一个0到1之间的缩放比例再乘上当前特征图的平均绝对值这样阈值就和特征图的幅值保持了比例关系。我打个比方这相当于你不需要记住“噪声音量是30分贝”这种绝对值而是知道“噪声大概是当前信号平均强度的0.6倍”。不管信号本身是大是小这个比例关系都能稳定区分“冗余”和“保留”。工程上用Sigmoid将比例限制在0到1之间再乘一个系数z通常设为1或2用于控制阈值上限。z2时阈值最高到特征绝对平均值的2倍这意味着大部分小特征都会被删除只有少数强特征能活下来。这个缩放系数的选择直接决定了“删除冗余特征”的激进程度。3. 灵活程度的三层讨论样本、层、通道3.1 样本级灵活性不同输入不同阈值DRSN最容易被忽略的一点是它的阈值会随着输入样本的不同而实时变化。普通网络训练完成之后权重固定特征处理规则就固定了而DRSN的前向计算里阈值子网络每收到一个样本都会重新计算一组阈值。这意味着什么假设测试集里大部分样本都比较干净少部分样本带强噪声。干净样本的特征绝对值分布稳定阈值子网络会给出一个较小的阈值几乎不删特征带噪声样本的特征统计量被噪声抬高阈值自动变大把更多幅值异常的区域收缩掉。这种“看人下菜碟”的样本级灵活性是普通卷积和固定激活函数完全做不到的。实际做带噪数据评测时我经常在同一个模型里看到不同样本的阈值差异超过一个数量级这是很正常的现象。3.2 层级灵活性浅层与深层的不同处理网络不同深度的特征语义差别很大。浅层特征大多是边缘、纹理、角点这些信息比较局部和具体任务的关联未必那么直接深层特征通常是语义级别的包含要分类的核心模式。DRSN在每个残差模块里都单独学习阈值所以浅层模块可能倾向于删除大量低层纹理深层模块则可能保持更谨慎的删除策略尽量保留关键语义。从训练过程看浅层阈值往往收敛得比较快因为浅层特征对输入统计量最敏感深层阈值需要更多epoch才能稳定因为它依赖前面所有层提取出的抽象特征。这种层级差异说明DRSN的灵活性不仅是“每层有独立参数”而是真正做到了“不同抽象层次使用不同的冗余删除策略”。这对深层网络的表达能力和稳定性都有帮助。3.3 通道级灵活性CW的细粒度控制DRSN-CW的最大贡献是把阈值细化到每个通道。为什么通道维度值得单独处理因为卷积神经网络中不同通道往往对应不同滤波器模式。某些通道可能专门响应背景纹理某些通道专门响应目标边缘在噪声场景下有些通道的信噪比天然很低。如果所有通道共享一个阈值结果就是高信噪比通道里的微弱有效特征会被误伤而低信噪比通道里的噪声又没删干净。我之前在一次轴承故障诊断实验里统计过DRSN-CW各通道的阈值发现一个很有意思的现象某个残差模块的64个通道里大约20个通道的阈值收敛到接近0说明网络判断这些通道里几乎没有冗余可以全量保留还有十几个通道的阈值长期维持在平均绝对值的0.8倍以上等于把大部分特征都收缩掉相当于网络主动关闭了这些噪声主导的通道。这种细粒度控制正是“灵活程度”最直观的体现。3.4 灵活度过高的代价与边界既然通道级灵活度高那是不是像素级、甚至每个空间位置都设一个阈值会更灵活理论上可以但工程上不一定划算。通道级阈值的参数增加相对可控因为它只依赖每个通道一个全局统计量一旦把阈值细化到空间位置子网络需要输出和特征图一样大的掩膜参数和计算量会明显上涨而且训练不稳定风险更高。更重要的是灵活程度需要和任务复杂度匹配。很多最先进的方法会在“灵活”和“可控”之间找平衡。对于大多数图像和信号分类任务DRSN-CW已经是性价比很高的选择。如果数据冗余特征呈现明显的空间分布差异可以先在DRSN-CW基础上加注意力模块而不是一上来就暴力做像素级软阈值。灵活不是越高越好适合自己的数据和算力才是最好的。4. 从0到1PyTorch实现DRSN-CW并在带噪数据上验证4.1 训练数据怎么准备给CIFAR-10加噪声为了验证DRSN删除冗余特征的能力我建议先在一个简单但可控的实验上跑通比如给CIFAR-10添加高斯噪声。这样做的好处是我们可以精确控制噪声强度让“冗余特征”成为一个显式可见的东西。比如把每张图像叠加标准差0.1或0.3的高斯噪声再用带噪声的图片训练和测试普通ResNet与DRSN对比效果。在PyTorch里给CIFAR-10加噪声很简单可以在Dataset的__getitem__里给tensor加一段高斯噪声。我通常会把训练集和测试集都加上相同强度的噪声这样可以公平验证模型在带噪分布上的泛化能力。如果只在训练集加噪声测试集是干净的DRSN的收缩能力反而不容易体现出来。4.2 核心代码实现一个可用的DRSN-CW模块下面是一个比较清晰的DRSN-CW残差模块实现基于PyTorch。这个模块替换掉普通BasicBlock里的ReLU部分同时增加阈值子网络。import torch import torch.nn as nn class DRSN_CW_Block(nn.Module): def __init__(self, in_ch, out_ch, stride1, z1.0): super(DRSN_CW_Block, self).__init__() self.z z self.bn1 nn.BatchNorm2d(in_ch) self.conv1 nn.Conv2d(in_ch, out_ch, 3, stride, 1, biasFalse) self.bn2 nn.BatchNorm2d(out_ch) self.conv2 nn.Conv2d(out_ch, out_ch, 3, 1, 1, biasFalse) self.bn3 nn.BatchNorm2d(out_ch) self.relu nn.ReLU(inplaceTrue) # 阈值子网络 self.global_pool nn.AdaptiveAvgPool2d(1) self.fc1 nn.Linear(out_ch, out_ch // 4) self.fc2 nn.Linear(out_ch // 4, out_ch) self.sigmoid nn.Sigmoid() # 残差连接 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 self.relu(self.bn1(x)) out self.conv1(out) out self.relu(self.bn2(out)) out self.conv2(out) out self.bn3(out) # 计算通道级阈值 abs_out torch.abs(out) avg self.global_pool(abs_out).squeeze(-1).squeeze(-1) # [B, C] scale self.fc2(self.relu(self.fc1(avg))) # [B, C] scale self.sigmoid(scale) * self.z # [B, C] threshold scale * avg # [B, C] threshold threshold.unsqueeze(-1).unsqueeze(-1) # [B, C, 1, 1] # 软阈值收缩 out torch.sign(out) * torch.relu(torch.abs(out) - threshold) out out identity return out这段代码里最关键的就是阈值计算和软阈值操作。中间特意用torch.abs(out)做全局平均池化这样阈值就和当前特征图的平均幅值绑定避免出现阈值与特征尺度不匹配的问题。对于要搭建分类模型你只需要把普通ResNet的BasicBlock替换成这个模块再保留标准的全局平均池化和全连接分类头就行。4.3 训练配置与结果指标怎么看我用这个模块在带噪声CIFAR-10上做过对比。训练配置很常规优化器SGD初始学习率0.1weight decay 5e-4批量大小128每60个epoch学习率除以10总共训练150个epoch左右。和普通ResNet-18相比在噪声较小的情况下两者差距不大但在噪声标准差0.3以上的情况下DRSN-CW的准确率通常能比普通ResNet高2到5个百分点。更值得关注的不只是最终准确率还有以下几个诊断指标。第一个是训练损失曲线DRSN通常更平滑不容易在后期过拟合。第二个是每个block输出的阈值与特征平均绝对值的比值这个比值高说明该层删除得很激进比值接近0说明这一层几乎不做冗余删除。第三个是“实际删除比例”也就是特征图中绝对值小于阈值的元素占比可以用(torch.abs(out) threshold).float().mean()统计这个数字通常在0.3到0.7之间波动。4.4 观察阈值的变化灵活程度的可视化训练结束后我习惯写一小段代码把第一层和最后一层的阈值统计打出来。你会看到非常典型的分布前面几层的通道阈值方差很大有的通道几乎不删有的通道把绝大多数特征都删掉了后面几层阈值整体更稳定删除策略更保守。这说明DRSN确实在学习一种“分层、分通道”的删除规则而不是把所有东西统一处理。如果你把这些阈值分布随epoch的变化画出来还能发现几个阶段训练早期阈值普遍很小网络不敢乱删训练中后期阈值逐渐分化部分通道开始增加删除力度形成稀疏特征最后阶段阈值基本稳定。这种动态变化就是“删除冗余特征灵活程度”的直接证据也非常适合写进实验报告或者技术分享里。5. 调参实录与常见问题排查5.1 阈值一直趋近0说明什么问题我见过不少人跑完DRSN之后打印阈值发现所有通道基本都为0软阈值模块形同虚设。这个问题要分几种情况看。第一种是数据本身就很干净几乎没有冗余特征阈值子网络通过训练发现不需要删除任何东西这其实是正常行为。第二种是子网络没学起来比如Sigmoid之前全连接层的权重初始化太小输出长期落在Sigmoid的饱和区附近梯度没法有效传播。排查思路很简单先看训练集误差。如果训练集已经过拟合说明网络能力足够只是阈值模块没有被激活如果训练集都欠拟合可能阈值模块把有效特征误删了。调参时可以把缩放系数self.z先调到0.5让阈值上限小一些观察阈值分布是否恢复。另外给全连接层用正常的Kaiming初始化、确保输入特征做了批归一化都能缓解这个问题。5.2 有效特征被误删欠拟合表现与调整方案当阈值子网络学得太激进模型会出现训练和验证误差都居高不下的欠拟合症状。核心原因是阈值删得太多有效信息被当冗余清掉了。常见触发条件有三个z参数设置过大、特征图通道数太少导致统计量不稳定、子网络中间层压缩太狠。遇到这类问题我会先做一次“熵减”操作把z从2降到1甚至降到0.5。这个调整效果非常直接相当于让网络更谨慎地估计冗余程度。其次检查FC中间层的通道数如果out_ch // 4太小建议改成out_ch // 2给阈值子网络更强的表达能力。如果网络本身很浅比如只有8层那也可以考虑用DRSN-CS代替DRSN-CW减少每层学习多个阈值的负担。5.3 训练不稳定Loss震荡的常见原因DRSN训练不稳定最常见的原因是软阈值操作放大了BN和全连接子网络之间的耦合。因为阈值直接依赖特征图绝对值均值特征图稍微波动一点阈值就会跟着抖动特别是前几十个epoch网络还没有收敛到稳定区间Loss呈现周期性震荡。解决方法有几个顺手就能用的技巧。第一先用较小的初始学习率跑前10个epoch做warmup等BN统计量稳定后再调大学习率。第二确保软阈值模块的输入经过了BN不然特征幅值在不同batch间差异过大。第三阈值子网络里的Sigmoid输出很接近0或1时容易出现饱和可以在Sigmoid之前加一个LayerNorm或者把FC层的输出做零均值归一化。最后如果问题依旧试试把残差连接的scale设为0.1或0.5降低残差分支对输入状态的扰动。5.4 干净数据上DRSN还有没有价值这是很多人会问的问题。如果数据集本身干净图像里没有明显噪声故障信号信噪比很高那么DRSN相比普通ResNet未必有显著提升。因为阈值子网络会学到所有阈值接近0软阈值退化为恒等映射网络就退化成普通残差网络。但在这种情况下DRSN也不会有明显坏处只是增加了少量参数。我自己更愿意把DRSN理解成一种“自适应正则化”手段。即使原始数据相对干净中间层的特征仍然可能存在冗余尤其是网络很深的时候冗余特征会随着抽象层级被逐层放大。DRSN相当于给每一层都装了一个可学习的稀疏化阀门让它自己决定当前层的特征是否应该收缩。从这个角度看它不只是针对噪声问题的专用工具而是提升深层网络泛化能力的一种通用设计思路。6. 写在最后个人对“灵活程度”的体会做了几年带噪声数据的模型训练后我越来越觉得“灵活程度”是一个需要主动设计的属性而不是一个越大越好的指标。DRSN最打动我的地方不是简单的软阈值公式而是它把“删除冗余特征”从固定规则升级成了网络自己学习的策略而且这个策略能在样本、层、通道多个维度上自由变化。实际项目中我一般会先做一个小实验在原型网络上打印每个DRSN模块的阈值分布看看哪些层在删、哪些层不删。如果所有层都在删说明z设置太大如果所有层都不删说明数据冗余不大或者子网络没调好。这个诊断过程比盲目追求模型精度更有效率。如果你也在处理带噪声的图像、振动信号或者语音特征我建议你先在现有ResNet基础上替换一两层DRSN-CW模块对比阈值分布和验证集误差的变化。这个小改动往往能给你带来意想不到的收益也会让你对“特征删除”这件事有更实际的理解。
返回列表