废话都在上一篇笔记的结尾处了, 下面开始正文。………………
(这次尝试改了一下目录结构)
——————————————————————————
课程链接:飞桨实战速成营
https://aistudio.baidu.com/aistudio/education/group/info/16606/notice
视频录播:飞桨计算机视觉项目实战营
https://www.bilibili.com/video/BV1pp4y1871g?t=2008
前置知识
一、1x1卷积
参考资料:1x1的卷积能做什么呢?
https://blog.csdn.net/ybdesire/article/details/80314925
- 个人大白话理解:融合多个通道图,就是把多通道图相加,最后得到一个图。一般就是用来减少通道数(融合通道数)的。
典型网络
一、FCN网络
FCN
是第一篇提出图像分割概念的网络,属于开山之作,极具有历史意义。
1.基本概念
FCN = Fully Convolutional Networks(全卷积神经网络)
,当时提出的概念,没有线性层,将线性层替换为卷积层,形成全卷积网络。
2.实现过程
- 可以看到,如果从把池化层
pool5
直接放大到原图,虽然有分类效果,但是丢失了很多边缘细节。 - 如果把
pool5
与pool4
融合后再放大,那效果就好很多,保留了些信息。如果再重复操作呢,就能保留更多信息。
特别说明:在
FCN
网络中,特征融合的过程是 逐像素点相加 的操作。
- 用框图表示,
FCN
的结构可以表示为如上。更加清楚的明白到:卷积到一半的蓝色score
、绿色score
和红色score2x
,分别融合得到8x
后再直接放大。得到语义分割的效果。 - 注意这个网络结构有点类似直线前进,主要还是因为只有
2x
到8x
的过程是特征融合的,在8x
后并不是继续卷积融合上去,而是直接放大。
二、U-Net网络
- 对比
FCN
网络,有U型结构,而且有完全对称的Encoder-Decoder
结构,同时,特征融合 为 维度拼接。
1.基本概念
- 特点①:
U-shape
(U型结构);特点②:Pooling replaced by upsampling
(池化被上采样所取代)。 - 重点补充:卷积后尺寸缩小,但是通道数会增加,也就是信息量会减少,但是特征图会增加。
看懂网络结构图,可以看到右下角有标注不同颜色方向的箭头的意思。分别代表:
- 3*3 卷积层 + ReLU 激活层
- 复制 和 拼接剪裁
- 下采样:max pool 池化层
- 上采样:up-conv 转置卷积 (?)
- 1*1 卷积层输出
2.实现过程
- 下文的代码实战部分会实现。(自己在实现这个网络模型时可以做适当裁剪,不必完全一模一样。)
三、Deeplabv3p网络
- 对比前2个网络提出新的概念和思路:提出
ASPP
和Separable Conv
1.基本概念
- 新概念:
空洞卷积
和深度可分离卷积
。 - 可以看到上图中,a)就类似
FCN
网络,b)就类似U-Net
网络,c)就是Deeplabv3p
网络,结合了a)和 b)两种网络结构。
①感受野
- 在了解空洞卷积之前,先复习/了解一下感受野的概念。
参考资料:卷积神经网络中感受野的详细介绍
https://blog.csdn.net/program_developer/article/details/80958716
- 之前的笔记中也有记载,其概念想法就是一个点包含了周围的信息,而包含的越多,就是指感受野越大。
- 在图像分割中,我们可以通过增大感受野,来增强图像分割效果。
- 另一种概念:更多上下文信息。
- 然后具体的做法就是指代到卷积中,每次卷积都会把卷积核尺寸内的信息集中在一点中,然后卷积多几次后那集中的信息就越多。
- 所以增大感受野的方法很简单。但是实际运用就有问题,单纯靠增加 卷积次数 来增加 感受野 太浪费资源了。参数多,计算量大。
- 所以就提出了2个解决方法:空洞卷积 和 深度可分离卷积。
②空洞卷积
Dilated Convolution
和Atrous Convolution
都是 空洞卷积 的意思。- 空洞卷积的思路就是:扩大卷积核,来扩大感受野,但是扩充的位置不填参数全填零。这样就可以达到即保持了参数数量,又能扩大感受野的目的。
- “空洞”的意思一个就是指填零的意思,当
D=1
时不填,当D=2
时就开始间隔一格填零。 - 另外,飞桨API没有现成的函数可调用。但是可以通过修改普通卷积函数的参数来达到空洞卷积的效果。
③Atrous Spatial Pyramid Pooling (ASPP)
ASPP
就是Deeplabv3p
网络中的一种空洞卷积的运用。- 前4段是普通卷积池化,这里的下标(4、8、16)是指原图大小的比例,不是通道数的意思。
- 然后通过4个卷积核,其中1个为
1x1卷积
,3个为空洞卷积
,最后再经过1个1x1卷积
融合成一幅图像,输出。
④深度可分离卷积
- 深度可分离卷积 中的 深度 指的是通道维度; 可分离 指的是卷积核可分离;
- 介绍两种 深度可分离卷积 的实现过程,分别是:
Spatial Separable Convolution
和Depthwise Separable Convolution
; 别搞错了,这是两种不同的方法,别上课听着听着就自动略过了。、
1)Spatial Separable Convolution
- 该方法的 可分离 的体现在:在把卷积核拆分,
3x3的卷积核
可才分为1个1x3的行向量
和1个3x1的列向量
。 - 可分离的优点是:参数量又减少了,计算量也减少了,能高效计算。另外,减少参数量还可以避免过拟合。
- 缺点:并不是所有卷积核都可以这样拆分的,这样就限制了应用性,所以实际很少用这种方法……
2)Depthwise Separable Convolution
- 左边是常规思路,一个卷积核广播然后和多通道图卷积得到的图再直接相加。
- 然后中间和右边的过程就是
Depthwise Separable Convolution
,其可以理解成Depthwise Convolution
和Pointwise Convolution
二步的组合。 - 第一步
Depthwise Convolution
就不用一个卷积核广播,而是复制三份分别卷积得到三个特征图。 - 第二步
Pointwise Convolution
就是把三个特征图用三个1x1卷积
融合,而不是用广播机制自动叠加。
- 从明面上看没感觉这样有什么加快计算的过程,但是经过老师的推算,老师得出了这样算的话是能大大减少计算的。2333。
题外话:
- 我一开始看这个示意图,发现三个卷积核的颜色不一样,还以为是代表不一样的卷积核呢,到群里咨询后dalao告诉我是等价的。而且后面也知道深度可分离卷积可以和普通卷积互换。所以可以理解为这是换另一个形式的卷积,实际效果是为了一样的。
- 我这段视频看了几遍,居然每次都听漏了一点,
Spatial Separable Convolution
和Depthwise Separable Convolution
是不一样的。看到两页PPT不一样的介绍时,还在纳闷,为什么会操作不一样的?原来是自己搞错了。
附上聊天截图作纪念,图片我缩小后再放上的,要看原图就点链接
3)代码示例
- 飞桨没有现成的 深度可分离卷积 API可以调用,不过实现起来也《不难》。老师给出了示范。
- 上面例子中的
ConvBN
和ConvBNReLU
都是自己写的另一个类……后面的代码实战再细讲。
2.实现过程
- 上图是
Deeplabv3p
的结构图,其中除了输入的第一次是普通卷积外,其余的所有卷积都是空洞卷积
和深度可分离卷积
的组合。 - 也就是说其实普通卷积一般都是可以替换掉的,对与复杂网络来说,这种改变的效果变化还是挺明显的。
四、HRNet网络
- 主要特点,是应用在
High Resolution
(高分辨率)的图像处理中。
1.基本概念
- 上一排是原本的网络思路,然后下面的改良后的思路。
- ①
High resolution
:就是每个分支都会保持尺寸大小进行卷积,也就是保持分辨率。(之前明明说过,如果保持尺寸的卷积计算量很大,是不可行的……) - 最高尺寸的分支是原图的
1/4
左右,并不是真正的高分辨率原图。 - ②
Parallel
:就是指几条线平行计算。最后Multi-head
输出是把所有分支融合一起输出。
- ③
Repeat fusions
:就是指几条平行线的融合。注意看左边的图示箭头标注,理解多层融合时的操作。 - 如上图。如果要融合出比本身大的图,就上采样放大后再融合,否则反之。
Down sample
和Up sample
。同时,通道数不一样时会用1x1卷积
融合。
- ④
Multi-head
:有点奇妙的是,根据最后点融合的不同,能实现不同功能。 - 从左到右依次是:特征跟踪,特征点检查或语义分割,目标检测,图像分类。
五、OCRNet网络
- 特点①:
Object Contextual Representation
:强调上下文链接。 - 特点②:
Attention based on soft region
:注意力。
1.基本概念
- 思路①:
coares-to-fine
:先进行粗分类,再进行细分类。(这不是一直在做的吗……) - 思路②:相关性,对比一下
ASPP
和OCR
,后者更加能明确知道自己的分类。??完全没懂这个示意图…… - 思路③:
Relational conetext
:指的是注意力。下文讲解。
①相关性/注意力
相关资料:综述—图像处理中的注意力机制
https://blog.csdn.net/xys430381_1/article/details/89323444
- 结构图中的
T
指的是时间轴,是指用在视频上的,这里直接忽略它。 - 先
0:1x1卷积
操作,后φ:1x1卷积
操作,然后将得到的2个特征图进行点乘
——这一步就是图像中求相识性/注意力的过程。 - 再操作2次,如图示。
(线性代数没学过这个概念,不是很懂,所以先含糊过去)
2.实现过程
- 下一排的框图是参考上一排的框图搭建的,可以找到三个框框(红色、紫色、黄色)对应关系。
- 更加详细的过程如上图所示。
我暂时听不懂,这个概念有点不能理解。先暂时放一放。
六、总结
- 个人理解总结:上采样:四星;特征融合:三星;感受野:五星:多尺度上下文:一星……
代码实战
项目链接:全流程,从零搞懂基于PaddlePaddle的图像分割
https://aistudio.baidu.com/aistudio/projectdetail/1674328
一、创建数据集
1. 准备图片
- 可以自己手动拍摄,或者网上收集。记得之前有听说过可以写爬虫上网收集。(之后好好学一下)
2.标注图片
- 有了图片后最关键的还是给每一张图片打算标签,准确的标签才能使网络正确的收敛。
- 这次课程的项目里推荐使用
labelme
进行标注。
github链接:wkentaro / labelme
https://github.com/wkentaro/labelme
- 该软件会把标注好的文件以
json
的文件格式保存,然后我们用代码生成需要的文件:原始图片和标签图片。
# 这里要注意的是,由于labelme自带的labelme_json_to_dataset命令只能处理单个json文件,
# 如果要批量处理所有生成的json文件可以采用并修改如下示例代码:
import os
path = PATH_TO_JSON
json_file = os.listdir(path)
#os.system("conda activate labelme")
for file in json_file:
os.system("labelme_json_to_dataset %s"%(path+"/"+file))
- 最后再把弄好的图片上传到
AI Studio
上打包做成数据集。
二、U-Net :训练、验证和预测
- 本次代码实战以
U-Net网络
为例,讲述两种进行训练、验证和预测的方法:基于Paddle2.0 API的方法和基于PaddleSeg2.0的方法。 U-Net
网络结构是一个基于FCN并改进后的深度学习网络,包含下采样(编码器,特征提取)和上采样(解码器,分辨率还原)两个阶段,因模型结构比较像U型而命名为U-Net
。
1.基于 Paddle2.0 API
这部分借鉴了项目『跟着雨哥学AI』系列06:趣味案例——基于U-Net的宠物图像分割 的部分内容。
https://aistudio.baidu.com/aistudio/projectdetail/1246330
- 总体流程:
(熟悉的常规操作来一波)
- 查看系统环境:Paddle版本等;
- 解压数据集,看看数据集里的内容正不正常;
- 确定好格式后,划分训练集、验证集、测试集;
- 划分好后,抽样检查一下看看正不正常;
- 使用飞桨的
Dataset
(数据集定义) +DataLoader
(多进程数据集加载),创建数据集类; - 使用飞桨的API创建类,组建模型;
- 确定损失函数、学习率、循环次数等训练参数,开始训练,保存模型、参数;
- 为了方便调参和理解,可以使用模型可视化组件,API
model.summary()
和 可视化工具; - 读取模型,使用测试集测试;
- 预测结果可视化,随机抽几张图片看看预测效果;
2.基于 PaddleSeg
- 总体流程:
- 安装
PaddleSeg
、下载克隆源码; - 选择
yml
参数文件,修改参数; - 开始训练……
- 结果可视化,然后【完】……
PaddleSeg
工具其实就是把飞桨的API再打包一次给人调用。图像分割的代码都会有一类通用性,然后把这部分内容全打包起来就得到了PaddleSeg
。按照这个逻辑去想,应该不同大类的网络任务都有对应的打包工具给人调用。
题外话,这样一操作就像我现在在做的事,参加智能车比赛,写框架给队友用。我的框架是在逐飞库的基础上写的,然后我写好框架后就给队友调用。队友只需要关心跑车算法就可以了。如果这么想的话,其实
PaddleSeg
这个源码并不算很“死”的。应该是可以根据实际需要自己改动的,后来也验证了这一猜想。
3.总结
- 基于
Paddle2.0 API
的重要点是模型的 手动搭建 过程;基于PaddleSeg
的重点是参数文件的 手动调用 过程。这里不展开了,原项目讲得比我好得多。
- 代码实战部分,我其实没有讲代码的实际内容。根据前面几次笔记的经验,我觉得在博客里复制粘贴那些代码然后加上自己的理解注释,这一行为不是特别好。还不如我在
AI Studio
上fork
一个项目,然后加上讲解注释再发布。那样的作用还大一点。- 因为代码实际的内容是多样化的——随便怎么写,能实现就好了。而我们最重要的是掌握思路。那之后如果要自己写就有方向,如果不会写也会调用(哈哈哈,应用“工程师”)。
三 、总结
- 至此,一二天的课程笔记结束,开始下一篇第三天课程的笔记。
磨了几天终于磨完了,
写到最后都不想细写了。然后直接写标题总结了事。而且项目里都有注释了,我不复制粘贴了,绝对不算因为我懒。