语义分割与FCN:从原理到实践
语义分割是计算机视觉领域的核心技术之一,旨在为图像中的每个像素分配语义标签(如“天空”“汽车”“行人”等)。它在自动驾驶、医学影像分析、遥感图像解译等领域有广泛应用。本文基于课程内容,结合经典模型FCN(Fully Convolutional Networks)和现代方法DeepLab,系统介绍语义分割的核心思想、技术演进及实践方法。
一、语义分割基础
1. 什么是语义分割?
目标:对输入图像的每个像素进行分类,输出像素级语义标签。
区别:
目标检测:用矩形框标出目标位置。
实例分割:区分同一类别的不同实例(如“猫A”和“猫B”)。
语义分割:仅关注类别,不区分实例。
2. 核心挑战
计算效率:传统滑动窗口法(逐像素分类)计算冗余大。
上下文信息:需结合局部特征与全局语义。
分辨率恢复:卷积网络下采样导致特征图尺寸缩小,需恢复原图分辨率。
二、FCN:全卷积网络
1. 为什么选择FCN?
FCN是首个端到端的全卷积语义分割模型(2015 CVPR),核心创新在于:
全卷积化:将传统CNN的全连接层替换为卷积层,支持任意尺寸输入。
跳级结构(Skip Connections):融合浅层细节与深层语义,提升分割精度。
2. FCN网络结构
编码器(卷积部分):
基于VGG16等经典CNN提取特征,生成低分辨率热图(heatmap)。
通过1×1卷积调整通道数,匹配类别数。
解码器(反卷积部分):
使用转置卷积(Transposed Convolution)逐步上采样,恢复原图尺寸。
通过跳级结构融合不同层特征(如FCN-8s融合pool3、pool4、conv7层)。
3. 关键技术点
转置卷积:通过反向传播学习上采样参数,优于简单的双线性插值。
反池化(Unpooling):记录池化时最大值位置,上采样时还原(如SegNet)。
三、语义分割的演进与优化
1. 经典模型发展
2015:FCN(全卷积网络)开启端到端分割时代。
2017:DeepLab系列引入空洞卷积(Dilated Convolution)扩大感受野。
2018:U-Net在医学影像中通过对称编码-解码结构提升精度。
2020:Transformer(如Segmenter)与CNN结合,利用全局注意力优化分割结果。
2. 关键技术改进
空洞卷积:在不增加参数量的前提下扩大感受野。
多尺度融合:通过金字塔结构(如PSPNet、FPN)整合不同分辨率特征。
条件随机场(CRF):后处理优化边界细节(如DeepLab v1/v2)。
四、DeepLab v3实战示例
1. 模型特点
主干网络:ResNet101 + 空洞卷积。
空洞空间金字塔池化(ASPP):多尺度捕获上下文信息。
2. 代码实现(PyTorch)
```python
import torch
from torchvision import models
# 加载预训练模型
model = models.segmentation.deeplabv3_resnet101(pretrained=True)
model.eval()
# 图像预处理
preprocess = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# 预测与可视化
input_tensor = preprocess(image)
output = model(input_tensor.unsqueeze(0))['out']
pred_mask = output.argmax(dim=1).squeeze().cpu().numpy()
```
五、评价指标与工具
1. 常用指标
全局精度(Pixel Accuracy):正确像素占比,但可能忽略小目标。
平均交并比(mIoU):各类别IoU的均值,最常用指标。
平均精度(mAcc):各类别精度的均值。
2. 标注工具
Labelme:轻量级多边形标注工具,适合小规模数据。
EISeg:基于飞桨的高效交互式标注工具,支持实时分割结果预览。
六、语义分割的应用
自动驾驶:道路、行人、车辆实时分割。
医学影像:肿瘤区域定位(如U-Net在MRI中的应用)。
农业遥感:农田与作物类型识别。
循环神经网络(RNN)与自然语言处理(NLP):从序列建模到实战
循环神经网络(RNN)是处理序列数据的核心模型之一,尤其在自然语言处理(NLP)中具有里程碑意义。从文本分类到机器翻译,RNN通过其“记忆”能力捕捉序列中的时序依赖关系。基于课程内容,结合经典应用场景(如IMDB评论分类),系统介绍RNN的核心原理、实现细节及实践方法。
一、序列模型基础
1. 序列建模的意义
分类问题:当前输入 → 当前输出(如图像分类)。
预测问题:当前及历史输入 → 当前输出(如股票价格预测)。
2. 自回归模型
假设当前状态ht是历史信息的总结,通过以下方式建模时序依赖:
马尔可夫假设:若仅依赖前 ττ 步历史,则模型复杂度显著降低。
二、数据预处理与词嵌入
1. 特征编码
数值特征:直接标准化(如年龄)。
类别特征:独热编码(如性别、国籍)。
# 示例:国籍编码(197维向量)
nationality = [0, 1, 0, ..., 0] # US对应位置为1
2. 文本处理流程
分词:按单词或字符切分文本。
构建词表:统计高频词并分配索引。
序列对齐:填充(Padding)或截断(Truncation)使文本长度统一。
# 示例:IMDB评论对齐(固定长度50)
padded_sequence = pad_sequences(sequences, maxlen=50)
3. 词嵌入(Word Embedding)
核心思想:将高维独热向量映射为低维稠密向量(如100维)。
优势:
降维减少计算量。
捕捉语义相似性(如“king - man + woman ≈ queen”)。
实现:通过嵌入层(Embedding Layer)学习映射矩阵。
三、RNN模型详解
1. RNN结构与前向传播
核心公式:
时序展开:每个时间步共享参数,依次处理序列元素。
2. RNN的局限性
梯度消失/爆炸:长序列导致梯度难以传递到早期时间步。
遗忘问题:早期输入信息随时间衰减。
3. 改进方案:LSTM与GRU
LSTM:引入门控机制(输入门、遗忘门、输出门)控制信息流。
GRU:简化版LSTM,合并门控单元以减少参数。
四、实战:RNN实现IMDB评论分类
1. 数据集与预处理
MDB数据集:5万条电影评论(2.5万训练/测试),标签为正面(1)或负面(0)。
预处理代码:
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 文本转索引序列
tokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(train_texts)
sequences = tokenizer.texts_to_sequences(train_texts)
# 对齐序列(固定长度100)
padded_sequences = pad_sequences(sequences, maxlen=100)
2. 模型构建与训练
下载
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, SimpleRNN, Dense
model = Sequential([
Embedding(input_dim=10000, output_dim=128), # 词嵌入层
SimpleRNN(units=64, return_sequences=False), # RNN层(仅输出最后状态)
Dense(1, activation='sigmoid') # 二分类输出
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(padded_sequences, train_labels, epochs=10, validation_split=0.2)
3. 结果分析
训练精度:89.2% → 过拟合时可达96%。
测试精度:约84.4%,优于传统方法(如逻辑回归)。
五、RNN的误差反向传播(BPTT)
目标函数:平均每个时间步的损失。
梯度计算:链式法则涉及所有时间步,长序列需截断(Truncated BPTT)。
六、门控循环单元(GRU)
1. 核心思想
GRU通过引入更新门(Update Gate)和重置门(Reset Gate),动态控制信息的保留与遗忘:
更新门:决定当前隐藏状态保留多少历史信息。
重置门:决定忽略多少历史信息以生成候选状态。
2. 数学表达
优势:参数比LSTM少,计算效率高,适合中小规模序列任务。
七、长短期记忆网络(LSTM)
1. 核心结构
LSTM通过记忆细胞(Cell State)和三个门控机制(遗忘门、输入门、输出门)实现长期依赖建模:
遗忘门:决定从记忆细胞中丢弃哪些信息。
输入门:决定将哪些新信息存入记忆细胞。
输出门:决定基于记忆细胞输出哪些信息。
2. 数学表达
优势:参数量是RNN的4倍,但长序列建模能力显著提升,适合语言模型、机器翻译等任务。
八、深度循环神经网络
1. 多层堆叠结构
通过堆叠多个RNN层(如LSTM或GRU),模型可学习不同层级的时序特征:
底层:捕捉局部模式(如单词组合)。
高层:捕捉全局语义(如句子主题)。
2. 数学表达
对于第ℓ层隐藏状态:
应用场景:语音识别、文档分类等复杂任务。
九、双向循环神经网络(Bi-RNN)
1. 核心思想
同时捕捉序列的前向和后向上下文信息:
前向层:从序列起点到终点处理。
后向层:从序列终点到起点处理。
输出:拼接或加权两种方向的隐藏状态。
2. 数学表达
优势:在命名实体识别(NER)、情感分析中表现优异。
十、实战对比与性能分析
1. 训练效果(基于The Time Machine数据集)
模型 |
困惑度(Perplexity) |
训练效率 |
RNN |
15 → 10 |
低 |
GRU |
10 → 5 |
中 |
LSTM |
8 → 4 |
高 |
Bi-LSTM |
6 → 3 |
较高 |
2. 代码示例(PyTorch实现LSTM)
import torch.nn as nn
class LSTMModel(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__()
self.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
out, (h_n, c_n) = self.lstm(x) # out: (batch_size, seq_len, hidden_dim)
out = self.fc(out[:, -1, :]) # 取最后一个时间步输出
return out