CVPR、PAMI
前期介绍
论文简介
可以去作者主页了解他们
前两个作者师出同门,老师为第三个。他们三个都是caffe深度学习框架的开发者
该论文是2015 CVPR的最佳论文。CVPR为计算机视觉方向的一个顶会
作为深度学习的小白,这个两个东西是一定要知道的
所需知识
神经网络
掌握神经网络的基本概念以及前向传播和反向传播的大致过程
卷积神经网络
掌握CNN基本原理,包括卷积、池化、上采样等
分类网路
掌握经典分类算法的思想,包括VGG net、AlexNet、GoogLeNet等
FCN以经典分类算法为基础,是它们的改良
PyTorch基础
掌握Python语言和Pytorch框架的基本用法,以及基础函数的定义
学习目标
课程安排
论文导读
论文背景
概念
语义分割
实例分割:有分割的优先级,比如背景不进行分割,同种类也用不同颜色标注
全景分割:上边两者的结合
何恺明的论文2019,全景分割。
语义分割研究现状
传统方法
Normalized cut(归一化切割)
分割具有相同特征的区域,纹理、颜色相同一个整体
缺点:效率低、准确度不高、慢
每运行一次N-cut,只能切割一次图片,为了分割出图像上的多个物体,需要多次运行。
Structured Random Forests(结构化的随机森林)
优点:改善噪点问题
缺点:过拟合,准确率不高
SVM(支持向量机)
深度学习卷积神经网络
FCN
SegNet
LinkNet
传统方法代表问题
深度学习代表问题
不匹配关系
SPP、ASPP、PSPNet、GCN、DFN等
不寻常类
RedNet、RDFNet
语义分割实现流程
数据集
CamVid适合新手
CityScapes 适合进阶,比较完整,用的频率比较高
FCN论文使用了NYUDv2和PASCAL VOC
上边两种为一类 多了一个通道D(深度)
指标
该三个指标都是越大越好
论文成果
论文意义
深度学习语义分割领域的开山之作
论文泛读
论文结构
摘要精读
摘要的写法:
- 卷积网络是什么。整个大背景的概述
- 核心观点是什么
- 我们设计的网络可以达到什么效果,有什么作用和功能
- 为了实现这个功能,我们做了哪些步骤,或哪些创新点
- 我们这个东西在哪些数据集上得到了什么好结果
分割术语
后两个效果不是很好
引言和相关工作
追溯FCN的思想源头,回顾FCN出现之前的语义分割方法
论文对应部分讲解
全局信息和局部信息
图片顶部图:上边轮廓分明的是局部信息,下边一团的是全局信息。左边汽车旁边的是下采样块,从原图的1/2到1/8称为浅层网络,还未对原始输入图造成特别大的破坏,这时的图像信息、几何信息比较丰富,轮廓分明。到1/16和1/32,也就是第四和第五层,这个特征图的特征已经被破坏的差不多了,只剩下计算机能够识别的高级特征,即下边那个一团绿色的块。总结来说,如果一个网络有五个下采样块,前三个(1/2到1/8)成为浅层网络,后两个(1/16和1/32)下采样块成为深层网络
感受野/域小的缺点为底部图的a和b对照
先验知识补充
根据论文第三节的顺序,补充相关知识点
感受域
感受野这个概念也在其它领域中使用如:分类、检测、 识别
感受域大小指的是这个结点对应原图的区域大小,而不是上一层的区域大小。(约定俗成)
$$RF_1$$ (感受域)一般为1,图中kernel_size(卷积核)为3,stride(步长)为1
计算后,$$RF_2$$ = 3, $$RF_3$$ = 5 都是对应着layer1原图的。
平移不变性
CNN不符合平移不变性(图顶端给出的这边论文指出:其中一个原因是忽略了采样定律/二次采样/下采样,有过多的下采样导致这个问题,如果所有卷积层的步长都为1的话,没有进行下采样,无论网络有多深,都满足平移不变性,一旦步长发生了变化为2或4,这样大尺度的一个跨越,就会破坏原始网络空间的坐标。图底部论文证实了二次采样/下采样是导致平移不变性在卷积神经网络上失效的主要原因),平移不变性不适用于卷积神经网络
算法对比
shift-and-stitch
上采样
图片内左边下边蓝色的为4*4输入图,阴影为3*3卷积核,蓝色上边绿色的为2*2的输出图
模型详解
算法架构
conv1等为卷积块,pool1等为池化层
FCN-32s直接一步扩大32倍
FCN-16s conv7先扩大2倍与pool4跳跃连接融合,然后扩大16倍
FCN-8s conv7先扩大4倍,pool4扩大2倍,与pool3融合,然后扩大8倍
蓝色为卷积,绿色为池化。最后两个比较长的卷积层对应conv6-7。该图为的FCN-8s的融合过程
橙色为反卷积还原,灰色代表裁剪(卷积操作时可能会遇到小数、除不尽的情况,需要做一个取整)
黄色的地方为相加融合
图的下半部分为FCN论文第二版的图,省略了卷积层
模型细节
训练技巧
学习率在之后应降低(实验的经验)
实验分析
问题讨论
解决方案:
1、使用已存在的数据集如NYU
2、如图
总结预告
资源利用:硬件充足,使用多块GPU跑模型,得出结果,觉得不好可以进行优化,这些在论文中可以作为点来写。
代码实现
中间链接为code,下边的为数据集
https://github.com/Redmalayantapir/Semantic_Segmentation_FCN
新代码里无这个函数(但有相应代替函数的步骤),可在旧代码里查找。
优化方式:该模型,数据预处理
指标的来源
n = 6 6个类别,可以从0-5得知
35时 都取最大值 5*6+5
橙色框是对每个对应值的计数
bin的值一定等于分类数的平方
行为L,列为P
图像勘误
MPA(类像素精度),对角线/每行和 得出6个数,再相加/6 = MPA
IoU = 对角线 / (行和 + 列和 - 对角线) # 对角线,求出来的是6个数
损失函数
期望
熵
log默认底为2
相对熵(KL散度)
P和Q看作标签和预测值
交叉熵
因为H(P(x))为定值,去掉第三行的H(P(x))后 变为第四行的交叉熵。
softmax
y表示输入的标签值,固定。a为概率值
One-hot(独热)编码
标签要经过两次编码。第一个是哈希编码,用来把每一个像素值对应到实际类别,第二个是One-hot编码,用来计算损失函数。
先通过哈希编码形式,对应成一个具体整数值。(数据处理)
input一个像素点对应RGB三个像素分量,通过哈希编码将其变为一个大的整数。
通过大的整数找对应的实数,也就是它所表示的类别,也就是Semantic Labels上的数字
把Semantic Labels拆开,一层代表一个类别。
将下边的Ont-hot图合到一起就变成了Semantic Labels图
每一层为一个二进制向量。
交叉熵与NLLLoss
NLLLoss的定义式与交叉熵相同。
整体流程
数据预处理,保证数据没问题是第一位
从路径读出数据,用Img库打开。
原图比较简单,主要做转tensor、归一化
标签做哈希编码,哈希编码的作用就是把标签当中每一个像素值对应成一个真实的类别(0-11的分类) 哈希函数的作用是加快查找效率 稀函数是怎么样的 哈希表是怎么对应的 怎么从一个整数对应具体类别
然后两个一起做中心裁剪,变成352*480的形式是为了352进行5次下采样时可以被整除,避免小数出现
定义一个整体的类,类根据不同数据集的路径,测试验证训练,做三个不同的实例化,在验证测试训练时,直接调用即可
模型
正式搭建FCN模型之前,双线性插值的方法,包括它本身如何扩大图片,还要把它作为初始化,初始反卷积、卷积核 是怎么扩大图片的,不是重点,有兴趣可以去了解一下插值法(很系统的一个方法)
手敲前向传播,上边需要的每一个模块,包括VGG前四层拿出来作为下采样块、卷积的定义、反卷积的定义、以及反卷积核的初始化
小作业,32s和16s补充上
训练
指定device
读数据,字典形式,key是img和label对应的value就是处理完的tensor
模型、损失函数优化器、batch_size大小、epoce参数的定义,对模型结果有一定影响,想拔高(大幅度)还得靠数据和模型搭建的功底,设计一个更好的模型,或者把数据处理得更丰富一点,让整个算法得到充分的学习
大循环里嵌套小循环,batch_size那里是小循环,epoce那里是大循环。小循环都把loss打印出来,最后整个loss求一个和,再取平均值,就是一个epoce得到的loss。包括常用的精读、类精度(对应每个类别的精读,所以一共有12个值,对应12个类别)、MIoU
用一次训练一次验证的方式
验证,将fcn模型从train模式改为val模式,这时不需要反向传播去做一个学习,只检验一下学习的效果如何,输出一个指标
作业,把验证的方法加到训练里边去,去看一下如何实现一次训练一次验证
测试、预测
测试输出数值化的结果图
预测输出的彩色的预测图
测试时,不仅要把模型指定成测试形式,还要加载训练时保存的最好权重,对当前权重做一个评估,看它的效果如何
单纯的数值化结果还不够,还要把它输出成预测图,更直观的看到是平滑还是更粗糙。里边涉及到一个上色的过程,如果有数据处理基础,看那一块代码比较简单,
损失函数、指标计算
损失函数部份缺失
按照从头到尾的逻辑梳理,先是期望、熵、相对熵(也叫KL散度),最后变形得到交叉熵,交叉熵与常用的softmax的联系和与NLLLoss的区别,让整个推导变得更加简单。最后达到映射效果,通过减少损失函数来达到让分类也就是softmax的值越大越好,它越大越表示预测和真实值之间的差距越小,说明它俩越像。
求损失函数时,涉及到一个标签编码,也就是One-hot编码。从真实类别对应整数类别再对应二进制向量的过程。举了例子,放了图。这两张图把它拍扁时,就是哈希编码的映射过程,从一张彩色的RGB标签对应到一张分类值的一张标签。然后把分类值标签一层一层割开,也就是扩张开,也就变成了One-hot编码,二进制这样一个形式,然后再把二进制拍扁,又变回了哈希编码这个形式,所以它们之间是有一定联系的。
指标中最重要的是混淆矩阵。预测和真实的标签先伸成一维向量,然后用numpy的bincount方法计数,判断每个像素点出现的个数,然后通过一个一个查数的方式对应到混淆矩阵当中,然后对角线就表示分类正确的像素点,其它就是分类错的。根据混淆矩阵就可以把每个指标计算出来。
python重要库
- numpy,科学运算
- pandas,python数据处理中常用的库,尤其是在爬虫的时候
- PIL,为对图片处理的常用库
- import torchvision.transforms.functional as ff # 对图片处理比较友好的东西,做简单图片处理时可以使用
一些文章或链接整理
https://zhuanlan.zhihu.com/p/34453588
https://blog.csdn.net/qq_36269513/article/details/80420363
https://zhuanlan.zhihu.com/p/32037333
https://blog.csdn.net/weixin_43143670/article/details/104791946