3. 经典降噪网络架构(一):CNN基础与DNCNN

各位同学,今天咱们正式进入深度学习降噪的网络架构部分。说实话,很多做ISP的工程师一听到“神经网络”就头大,觉得那是算法团队的事。但你想,如果连卷积、池化、残差连接这些基本构件都搞不清楚,部署的时候遇到问题根本没法定位。

我个人习惯是:先理解每个组件“为什么存在”,再看它们“怎么组合”。这一章我们就从CNN最基础的三个操作讲起,然后拆解一个经典的去噪网络——DNCNN,看看残差学习和BN层到底在降噪任务里扮演什么角色。

3.1 CNN三大基础操作:卷积、池化、激活函数

先别急着看网络结构。咱们把砖块先认清楚。

3.1.1 卷积层——特征提取器

卷积说白了就是用一个小的“窗口”(卷积核)在图像上滑动,做点积运算。每个卷积核负责提取一种特征,比如边缘、纹理、颜色变化。

关键参数:
  • 卷积核大小(Kernel Size):常用3×3或5×5。3×3感受野小,计算量低,堆叠多层可以扩大感受野。
  • 步长(Stride):每次滑动的像素数。步长=2时,输出特征图尺寸减半。
  • 填充(Padding):保持输出尺寸与输入一致,常用“same”填充。
  • 输入/输出通道(Channels):输入通道数=上一层输出通道数,输出通道数=本层卷积核个数。

我在项目中遇到过一个问题:部署时发现模型推理速度比预期慢很多。查了半天,发现是卷积层用了5×5的大核,而硬件对3×3有专门的加速指令。所以,部署时优先选3×3卷积,这是经验之谈。

3.1.2 池化层——降采样与特征压缩

池化层的作用很直接:缩小特征图尺寸,减少参数量,同时保留主要特征。最常用的是最大池化(Max Pooling)和平均池化(Average Pooling)。

池化类型 操作方式 适用场景
最大池化 取窗口内最大值 保留最显著特征,常用于分类网络
平均池化 取窗口内平均值 平滑特征,常用于降噪网络

不过要注意,在降噪网络里,池化层用得并不多。因为降噪需要保留空间细节,池化会丢失位置信息。DNCNN就没有用池化层,而是用步长卷积或空洞卷积来控制感受野。

3.1.3 激活函数——引入非线性

没有激活函数,多层卷积就等价于一层线性变换,那深度网络就没有意义了。常用的激活函数有ReLU、Leaky ReLU、PReLU等。

我的建议: 降噪网络里,ReLU会把负值直接置0,导致丢失一些噪声信息。我个人更推荐用Leaky ReLU或PReLU,保留负半轴的小梯度,收敛更稳定。

3.2 经典去噪网络:DNCNN

DNCNN(Denoising Convolutional Neural Network)是2017年提出的,结构非常简洁,但效果在当时是SOTA。它证明了“深度+残差+BN”这个组合在降噪上的威力。

3.2.1 网络结构

DNCNN的结构可以概括为:输入→卷积+ReLU→(卷积+BN+ReLU)×若干层→卷积→输出。

具体来说:

  • 第一层:Conv(3×3, c) + ReLU
  • 中间层:Conv(3×3, c) + BN + ReLU,重复若干次(中深度为17层)
  • 最后一层:Conv(3×3, 1) 或 Conv(3×3, 3)(取决于输入通道数)

这里c是中间特征通道数,里取64。整个网络没有池化层,没有全连接层,全是卷积,所以可以处理任意尺寸的输入图像。

避坑指南: 我曾经在部署DNCNN时,发现输出图像有棋盘格伪影。排查后发现是反卷积(转置卷积)导致的。DNCNN原版用的是普通卷积,没有反卷积。如果你自己改结构,千万别在降噪网络里乱用反卷积,除非你清楚知道自己在做什么。

3.2.2 为什么DNCNN有效?

三个原因:

  1. 深度足够:17层卷积提供了足够的感受野,能捕捉大范围的噪声模式。
  2. 残差学习:网络学习的是“噪声图”,而不是“干净图”,降低了学习难度。
  3. BN层稳定训练:批量归一化让每层输入的分布更稳定,加速收敛。

3.3 残差学习策略

残差学习是DNCNN的核心思想。传统网络直接学习“输入→干净图像”的映射,而DNCNN学习的是“输入→噪声”的映射,然后通过输入减去噪声得到干净图像。

用公式表示就是:

干净图像 = 输入图像 - 网络输出的噪声图

为什么这样更好?

  • 梯度更容易传播:残差连接让梯度可以直接流到前面的层,缓解梯度消失。
  • 学习目标更简单:噪声通常是零均值的,分布相对简单,比学习复杂的自然图像容易得多。
  • 输出范围可控:噪声值通常很小(比如[-0.1, 0.1]),网络输出不需要很大的动态范围。
部署小技巧: 在量化部署时,残差学习有一个好处——网络输出(噪声图)的数值范围很小,量化误差对最终结果的影响也小。相比之下,直接输出干净图像的网络,量化误差会被放大。

3.4 BN层在降噪中的作用

BN层(Batch Normalization)在DNCNN里几乎是每层必带(除了第一层和最后一层)。它的作用有三:

  1. 加速训练收敛:归一化后每层输入的均值和方差稳定,可以用更大的学习率。
  2. 缓解过拟合:BN引入了轻微的噪声(mini-batch统计量的波动),有正则化效果。
  3. 允许更深的网络:没有BN,17层的卷积网络很难训练。

但是,BN在部署时有个坑:训练时BN的均值和方差是每个batch计算的,推理时用的是全局统计量。如果训练集和部署场景的数据分布不一致,BN层反而会引入误差。

我的经验: 在ISP场景下,不同传感器、不同光照条件的数据分布差异很大。我建议在部署前,用目标场景的数据对BN层的统计量做一次“校准”(calibration),效果会好很多。

3.5 本章知识结构图

下面这张图总结了本章的核心知识点和它们之间的关系:

CNN基础与DNCNN知识结构 三大基础操作 卷积层 池化层 激活函数 DNCNN网络 17层卷积 无池化层 残差学习 残差学习策略 学习噪声而非图像 输入 - 噪声 = 干净图 BN层在降噪中的作用 加速训练收敛 缓解过拟合 允许更深网络 核心思路:用残差学习+BN稳定训练,让深度卷积网络学会从噪声中分离出干净图像 部署要点:优先3×3卷积,注意BN校准,避免反卷积

3.6 小结

这一章我们拆解了CNN的三大基础操作,分析了DNCNN的结构设计,理解了残差学习为什么有效,也看到了BN层在降噪中的两面性。

说实话,DNCNN虽然已经是“老”网络了,但它的设计思想——深度+残差+BN——至今仍是很多降噪网络的基石。你把它吃透了,后面看DnCNN-B、FFDNet、CBDNet都会轻松很多。