4、深度学习基础回顾:CNN、ResNet、Transformer在ISP中的应用
各位同学,今天我们聊聊深度学习在ISP里的几个核心模型。说实话,我刚入行那会儿,ISP还全是传统算法的天下,什么3A、去噪、锐化,都是手工调参。后来深度学习一进来,整个行业都变了。我个人习惯是,不管模型多花哨,先搞懂它为什么能用在ISP里。
这一章,我们重点回顾三个架构:CNN、ResNet、Transformer。它们不是凭空冒出来的,每一步演进都解决了实际痛点。你想想看,手机拍照为什么越来越强?背后就是这些模型在默默干活。
4.1 CNN:ISP的基石
CNN,卷积神经网络,说白了就是用一个滑动窗口(卷积核)在图像上扫来扫去,提取局部特征。为什么它适合ISP?因为图像处理本身就是局部的——一个像素的噪点,看它周围几个像素就能判断。
我在项目中遇到过一个问题:用传统BM3D去噪,效果虽好但速度太慢。换成CNN后,一个简单的U-Net结构,速度提升了几十倍,效果还更好。嗯,这里要注意,CNN的感受野有限,如果图像有全局性的亮度不均,它可能处理不好。
CNN在ISP中的典型应用:
- 去噪:DnCNN、FFDNet,直接学习噪声到干净图像的映射
- 去马赛克:用CNN插值Bayer模式,比传统双线性插值好太多
- 超分辨率:SRCNN、ESPCN,把低分辨率图变高分辨率
一个简单的CNN去噪代码片段,大家感受一下:
import torch.nn as nn
class SimpleDenoiser(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3, 64, 3, padding=1)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(64, 64, 3, padding=1)
self.conv3 = nn.Conv2d(64, 3, 3, padding=1)
def forward(self, x):
# 残差学习:预测噪声,而不是直接预测干净图像
noise = self.relu(self.conv1(x))
noise = self.relu(self.conv2(noise))
noise = self.conv3(noise)
return x - noise # 干净图像 = 输入 - 噪声
我的经验:CNN做ISP任务时,输入输出最好都是RAW域数据,避免sRGB域的非线性损失。我曾经在sRGB域训练去噪模型,结果RAW域测试时效果大打折扣。
4.2 ResNet:让网络深下去
CNN虽然好,但一深就出问题——梯度消失。你想想看,一个50层的网络,梯度从最后一层传到第一层,早就衰减没了。ResNet的解决方案简单粗暴:加一条“高速公路”,让梯度可以直接跳过。
这个思想在ISP里特别有用。比如做超分辨率,浅层网络学不到高频细节,深层网络又难训练。ResNet的残差连接,让我可以放心地堆到100层以上。
ResNet的核心公式:
输出 = F(x) + x
其中F(x)是卷积层学到的残差,x是输入。如果F(x)=0,网络至少不会比输入差。
我曾经在HDR合成任务里,用ResNet-50代替普通CNN。效果立竿见影——高光区域的细节保留得更完整,暗部噪点也更少。说白了,残差连接让网络可以“选择性遗忘”不重要的信息,专注于学习难的部分。
class ResidualBlock(nn.Module):
def __init__(self, channels):
super().__init__()
self.conv1 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn1 = nn.BatchNorm2d(channels)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn2 = nn.BatchNorm2d(channels)
def forward(self, x):
residual = x
out = self.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
return self.relu(out + residual) # 残差连接
避坑指南:ResNet不是越深越好。我在一个去噪项目里试过152层,结果过拟合了,反而比50层差。对于ISP任务,50层左右通常就够用了,再深收益递减。
4.3 Transformer:全局视野
Transformer原本是NLP的产物,但这两年杀进CV领域,势不可挡。它和CNN最大的区别是什么?CNN看局部,Transformer看全局。你想想看,一张照片的白平衡,需要参考整个画面的颜色分布,这就是全局问题。
在ISP里,Transformer特别适合做色彩重建和HDR合成。我记得有一次做RAW域的色彩校正,用CNN总是偏色,换成Transformer后,颜色一下子就准了。为什么?因为Transformer的自注意力机制,可以捕捉到远处像素之间的颜色关系。
Transformer在ISP中的优势:
- 全局感受野:一次看到整张图,适合白平衡、色调映射
- 动态权重:根据内容自适应调整,比CNN的固定卷积核灵活
- 多尺度融合:可以同时处理不同分辨率的特征
不过Transformer也有缺点——计算量大。一张4K图像,直接做自注意力,显存直接爆炸。所以实际应用中,我们通常用窗口注意力(Window Attention)或者和CNN混合使用。
# 简化的自注意力机制(单头)
def self_attention(query, key, value):
# query, key, value: [batch, seq_len, dim]
scores = torch.matmul(query, key.transpose(-2, -1)) # 计算相似度
scores = scores / (key.size(-1) ** 0.5) # 缩放
attention = torch.softmax(scores, dim=-1) # 归一化
output = torch.matmul(attention, value) # 加权求和
return output
我的建议:如果你刚开始做ISP的Transformer,别一上来就用纯Transformer。试试CNN + Transformer的混合架构,比如前面几层用CNN提取局部特征,后面用Transformer做全局建模。这样既快又好。
4.4 三者的对比与选择
说了这么多,到底什么时候用CNN,什么时候用ResNet,什么时候用Transformer?我整理了一个表格,方便大家参考:
| 模型 | 核心优势 | 适合的ISP任务 | 注意事项 |
|---|---|---|---|
| CNN | 局部特征提取,计算快 | 去噪、去马赛克、超分辨率 | 感受野有限,深了难训练 |
| ResNet | 解决梯度消失,支持深层网络 | 超分辨率、HDR合成、图像增强 | 注意过拟合,50层左右够用 |
| Transformer | 全局建模,动态权重 | 色彩重建、白平衡、HDR合成 | 计算量大,需要窗口优化 |
我个人习惯是,先分析任务需求。如果是像素级的局部处理,比如去噪,CNN就够了。如果需要全局色彩信息,比如白平衡,那就上Transformer。如果网络要很深,比如超分辨率,ResNet是首选。当然,现在的主流做法是混合使用——用CNN提取特征,用Transformer做融合,用ResNet保证深度。
总结一下:CNN是基础,ResNet是深度保障,Transformer是全局视野。三者不是互斥的,而是互补的。在ISP的AI改造中,理解它们的原理和适用场景,比盲目堆叠模型重要得多。