这篇文章想解决一个我自己一开始也很困惑的问题: ResNet、U-Net、ResUNet 到底分别在解决什么问题?它们为什么看起来很像,但本质又不一样?


一、为什么我总觉得 U-Net 和 ResNet 很像?

第一次看这几个网络的时候,我最强烈的感觉就是:

  • 它们都有很多卷积层
  • 它们都有“跳连接”(skip connection)
  • 它们都不是简单的从前到后堆叠

所以很容易产生一种印象:

它们是不是只是长得不一样,但本质差不多?

后来我才意识到,它们表面上都在“跨层传信息”,但目的完全不同

一句话先概括:

  • ResNet:核心是解决“深层网络难训练”
  • U-Net:核心是解决“分割任务中细节容易丢失”
  • ResUNet:核心是把前两者结合起来,既保留 U-Net 的分割能力,又借助 ResNet 的残差学习让网络更容易训练

二、ResNet:不是直接学输出,而是学“残差”

ResNet 的核心思想,可以浓缩成一句话:

不直接学习目标映射 $H(x)$,而改为学习残差 $F(x)=H(x)-x$。

于是输出就写成:

$$ y = F(x) + x $$

这一步看起来只是多了一条 shortcut,但它真正改变的是:

  • 网络不必从零开始学完整映射
  • 只需要学“在原输入基础上还要修正多少”

1. 为什么这有用?

因为在很多情况下,理想映射其实离恒等映射不远。

比如,如果某个 block 最好的行为其实是“尽量别改输入”,那么:

  • 普通网络要硬学一个“输出 $\approx$ 输入”的映射
  • ResNet 只需要让 $F(x) \approx 0$

这显然更容易。

2. ResNet 的 block 长什么样?

一个最经典的 residual block 可以画成这样:

输入 x
  ├───────────────┐
  │               │
  ▼               │
Conv → BN → ReLU  │
  │               │
Conv → BN         │
  │               │
  └───── add ◄────┘
       ReLU
        输出 y

它的重点在于:

  • 主分支负责学习变化量 $F(x)$
  • 旁路分支直接把输入 $x$ 传过去
  • 最后做逐元素相加

3. ResNet 真正解决的问题

ResNet 不是为分割而生的,它最早主要是为了解决:

  • 网络加深后训练误差反而上升
  • 梯度传播困难
  • plain network 堆深了不一定更好

所以 ResNet 的本质是:

一种更利于优化的深层网络构造方式。


三、U-Net:不是为了更深,而是为了“分得准”

如果说 ResNet 在意的是“怎么训练深网络”,那么 U-Net 在意的是另一件事:

怎么做像素级分割,并且边界还要准。

这就意味着,网络不仅要知道“这是什么”,还要知道“它具体在哪”。


四、U-Net:左边看语义,右边找位置

U-Net 的结构非常经典,是一个对称的 U 形结构:

  • 左边:编码器(contracting path)
  • 中间:瓶颈层
  • 右边:解码器(expanding path)

1. 左边在做什么?

左边不断做卷积和池化:

  • 尺寸越来越小
  • 通道越来越多
  • 特征越来越抽象

这部分的作用是:

把图像“看懂”。

也就是提取高层语义特征。

2. 右边在做什么?

右边不断做上采样:

  • 尺寸逐渐恢复
  • 特征重新变回高分辨率
  • 最终输出与输入同尺度的分割图

这部分的作用是:

把语义信息重新投影回像素空间。

也就是告诉我们:每个像素属于哪一类。

3. U-Net 最关键的地方:横向跳连接

U-Net 最大的灵魂不是“U 形”,而是左边和右边之间的跳连接。

也就是:

  • 左边某一层的高分辨率特征
  • 直接传到右边对应尺度
  • 与上采样后的特征做拼接(concat)

可以画成这样:

编码器某层特征 ──────────────┐
上采样后的解码器特征 → concat → Conv

这一步非常关键,因为:

  • 下采样虽然拿到了语义
  • 但也会丢失边缘、纹理、定位细节
  • 跳连接把这些细节重新补回来

4. U-Net 的核心不是 add,而是 concat

这点和 ResNet 非常不一样:

  • ResNet:通常是 add
  • U-Net:通常是 concat

这说明它们的意图不同:

  • ResNet:把输入作为“基础项”,学习修正量
  • U-Net:把两种不同来源的信息并排拼起来,再交给后续卷积融合

五、我怎么理解 U-Net 的图?

我现在看 U-Net 图,脑子里只保留一句话:

左边负责“理解是什么”,右边负责“恢复在哪里”,中间的横向连接负责“别把细节弄丢”。

这比背结构更重要。

一个极简 U-Net 示意:

输入
[Conv Block] → 下采样
[Conv Block] → 下采样
[Conv Block] → 下采样
[Bridge]
上采样 → concat(来自左侧同尺度特征) → [Conv Block]
上采样 → concat(来自左侧同尺度特征) → [Conv Block]
上采样 → concat(来自左侧同尺度特征) → [Conv Block]
输出分割图

六、为什么我会把 ResNet 和 U-Net 混在一起?

因为它们都用了 skip connection。

但它们的 skip connection 根本不是一回事。

1. ResNet 的 skip 是“短跳连接”

位置:

  • 在一个 residual block 内部

作用:

  • 帮助梯度传播
  • 改善优化
  • 让 block 学残差

典型形式:

$$ y = F(x) + x $$

2. U-Net 的 skip 是“长跳连接”

位置:

  • 从编码器直接跨到解码器

作用:

  • 把高分辨率细节补给解码器
  • 提升定位精度
  • 改善边界恢复

典型形式:

$$ \text{decoder feature} = \text{Concat}(\text{upsampled feature}, \text{encoder feature}) $$

3. 一句话区分

  • ResNet 的 skip:为了“更好训练”
  • U-Net 的 skip:为了“更好分割”

七、ResUNet:把 U-Net 的 block 换成 residual unit

当我理解了 ResNet 和 U-Net 分别在干嘛之后,ResUNet 就突然变得非常自然。

它本质上就是:

保留 U-Net 的整体结构,但把里面的普通卷积块换成 ResNet 风格的残差单元。

也就是说:

  • 大框架还是 U-Net
  • 局部单元换成 residual unit

八、什么叫“把 U-Net block 换成 residual unit”?

先看原始 U-Net 的一个典型 block:

输入
3×3 Conv + ReLU
3×3 Conv + ReLU
输出

这个 block 的特点是:

它直接从输入算出一个新的输出表示。

再看 residual unit:

输入 x
  ├───────────────┐
  │               │
  ▼               │
3×3 Conv + BN + ReLU
  │               │
3×3 Conv + BN     │
  │               │
  └───── add ◄────┘
       ReLU
        输出

这个 unit 的特点是:

不直接“重写”特征,而是在原特征基础上做修正。

所以所谓“把 U-Net block 换成 residual unit”,精确意思就是:

  • U-Net 每一层原来是普通卷积块
  • 现在改成残差块
  • 编码器和解码器都可以这样替换

九、ResUNet 的结构应该怎么理解?

最重要的是:U 形不变,block 变了。

一个典型 ResUNet 示意:

输入
[Residual Unit] → 下采样
[Residual Unit] → 下采样
[Residual Unit] → 下采样
[Bridge / Residual Unit]
上采样 → concat(编码器同尺度特征) → [Residual Unit]
上采样 → concat(编码器同尺度特征) → [Residual Unit]
上采样 → concat(编码器同尺度特征) → [Residual Unit]
1×1 Conv
输出分割图

这里有两种 skip connection:

1. U-Net 风格的长跳连接

  • 编码器到解码器
  • 通常做 concat
  • 用来补细节

2. ResNet 风格的短跳连接

  • residual unit 内部
  • 通常做 add
  • 用来好训练

这两种 skip 同时存在,就是 ResUNet 的关键。


十、为什么 ResUNet 很自然?

因为它恰好把两个问题接上了。

U-Net 的优势:

  • 适合分割
  • 多尺度信息利用充分
  • 边界和细节恢复好

ResNet 的优势:

  • 更容易优化
  • 更适合堆深
  • 梯度传播更稳定

所以 ResUNet 的逻辑就是:

  • 保留 U-Net 的“会分割”
  • 引入 ResNet 的“好训练”

它不是简单拼装,而是非常顺理成章的结合。


十一、三者最核心的区别

模型主要目标核心结构skip connection 的作用
ResNet让深网络更容易训练residual block学残差、帮助优化
U-Net做高精度分割encoder-decoder + long skip补细节、做定位
ResUNet更强的分割模型U-Net 框架 + residual unit同时兼顾定位与优化

十二、如果只允许我用一句话解释它们

ResNet

不直接学完整映射,而是学输入基础上的修正量。

U-Net

左边提语义,右边恢复分辨率,横向连接补回细节。

ResUNet

在 U-Net 的框架里,用 residual unit 替代普通卷积块。


十三、一个我觉得很有帮助的类比

ResNet 像什么?

像改稿。

  • 原文还在
  • 你不重写全文
  • 只在原文基础上修改一部分

所以它学的是“改动量”。

U-Net 像什么?

像先写提纲,再扩写全文。

  • 压缩时抓住主旨
  • 展开时恢复细节
  • 还把原文片段拿回来补细节

所以它更关注“语义 + 定位”。

ResUNet 像什么?

像一边按 U-Net 的方式组织全文,一边每一段又采用 ResNet 的“增量修改”方式来写。


十四、最后的总结

如果我重新用最朴素的话说这三者:

  • ResNet 关心的是:网络太深了,怎么训练?
  • U-Net 关心的是:做分割时,怎么既看懂图像又保留细节?
  • ResUNet 关心的是:既然 U-Net 很适合分割,ResNet 又很适合深层优化,那为什么不把两者结合起来?

于是就有了一个很自然的答案:

U-Net 负责整体结构,ResNet 负责局部单元,ResUNet 负责把这两者融在一起。