显著性检测:1)显著性物体检测-最能引起视觉注意的物体区域2)注视点预测:人类视觉注意机制
视觉注意机制的两种机制:1)自底而上基于数据驱动的注意机制,如颜色、边缘 2)自上而下基于任务驱动的目标的注意机制,如认知因素钟的只是、预期、兴趣
物体分割:Gragh Cuts分割~最小割最大流算法优化
GrabCut分割:前景/背景的颜色分割 ~ 高斯混合模型,Kneans获得(高斯混合包括Kmeans和EM算法)、
美图秀秀用到
需要给初始标记
语义分割:
目标:从像素水平上,理解、识别图片的内容;根据语义信息分割
输入图片,输出同尺寸的分割标记(像素水平),每个像素会被识别为一个类别category ;
不需要标记,自己生成的
算法研究:
2015前:手工特征+图模型(马尔科夫/条件随机场CRF)
之后:深度神经网模型
传统cnn的问题:后半段网络无空间信息;输入图片尺寸固定
全卷机网络FCN:所有层都是卷积层(Googlenet等还是有全局的卷积层,因为需要把二维的空间信息变为一维的概率信息节点);解决降采样后的低分辨率问题~稀疏输出
语义分割是像素级别、更为精确的,比rcnn系列网络改进的要更深入和充分,且输出就是要原图尺寸的,所以可以使用完全意义上的全卷机网络
语义分割要求2-D输出尺寸,逐个像素的 ~ 一般都为FCN系列
检测网络 ~ rcnn系列
分类网络 ~ cnn系列
FCN:全卷机网络 2015年
卷积化:所有全连接层转换为卷积层;适应任何尺寸输入,输出低分辨率分割图片~因为几个像素会变为一个像素,所以分辨率降低
VGGAlexNet之所以要固定图片尺寸,是因为最后一层卷积层,但是全改为卷积层后就不需要控制输入尺寸
但是
卷积化后的核尺寸:gc6-8~1*1,4096 -1*1,4096-1*1,N个类别 ~前两个1*1卷积是特征变换的作用,最后一个是特征推断的作用
分辨率下降32倍~五层卷积层,2的5次方
-->
反卷积:将低分辨率图片进行上采样,输出同分辨率/同尺寸的分割图片 ~反卷积上采样32倍 ~会有信息损失
卷积:3*3,步长2 反卷积:3*3,步长1/2 ;反卷积核是卷积核的转至,学习率为0~因为反卷积的前向和后巷传播分别对应卷积操作的后巷和前向传播,优化上做颠倒就行,故学习率为0
也叫转至卷积
FCN-卷积/转至卷积的参数关系:
s=1时:
核尺寸: k k
步长 : s s
padding:p k-p-1
输入:i o
输出:o i + (k-1)-2p
s>1 and a=i+2p-k整除s时:
k k
s 1(因为1/s小数步长,是通过补零输入实现的)
p k-p-1,不整除时在上方和右方再补0~p’=amods --- 不对称补0
i i‘=i+(s-1)(i-1)
o s(i'-1)+a+k-2p,a=0 当不整除s时,a!=0
DeepLab网络
DeepLab-DCNN:
--》
因为反卷积不能完全恢复信息,所以Deeplab提出了更好的方案
~因为vgg前面五个卷积层都有pooling,所以在第五个卷积层的地方加上了反卷积上采样,导致信息丢失
基本结构:优化后的DCNN(分辨率下降)+双线性插值上采样+传统的CRF图模型
新的上采样卷积方案:带孔hole结构的膨胀卷积Atrous dilated convolution
多尺度图片表达:atrous空间金字塔池化
边界分割的优化:使用全连接条件随机场CRF进行迭代优化
孔算法
--》
解决原始fcn网络的输出低分率问题
无上采样,恢复感受野,可以finetue,保证了网络最终的高分辨率输出(仅8倍降采样)
参数数量不变、计算量不变
卷积核结构:尺寸不变3*3,步长不变1,但是元素间距变大(1-》2)
采用层:conv5即第五卷机组~孔尺寸2 conv6~孔尺寸4 (第四池化层步长2变为1,导致第五卷积层感受野变小,所以孔尺寸为1,即中间补0 ; 普通池化,卷积核3,步长为2,padding=1--》输出4个节点-》 密集池化,步长为1,padding=1,输出7个,其中四个对应的就是普通池化的输出--》 孔算法,padding=2,卷积核间隔补0 ,不是输入神经元补0 !)
膨胀卷积atrous/dilated convolution
--》
孔算法的正式名称
与降低池化曾步长配对使用,取代上采样反卷积
孔尺寸-rate,越大,感受也越大,插rate-1个0
孔算法带来的增加的输出其实对应的就是stride从2变为1后,对应的特征图多出的神经元的位置,也就是孔的位置
atrous金字塔池化:
不同感受也也就是不同rate捕捉不同尺寸上的特征
在conv6层引入4个并行膨胀卷积,kernel=3,rate=6,12,18,24
4个膨胀卷积后各自增加两个1*1卷积:是为了做在像素级别上的特征推断
fc6-》fc7-》fc8 深度 4096-》2014-》类别数量 ~ 三个分支
融合:三个分支概率融合
全连接CRF:
通过迭代精化分割结果
输入:第一次输入 dcnn输入结果,后面输入crf迭代结果
跳层结构skip layer:精化分割图片
可以拟合出双线性插值,双。。可以作为全卷机的特例
分为偶数/奇数输入输出
但是
直接使用32倍反卷积得到的分割结果粗糙
-->
skip layers:
使用前两个卷积层的输出做融合~跳层:pool4和pool3后会增加一个1*1卷积层做预测,生成预测图,再融合,再做上采样;
较浅网络更加精确,较深网络的结果鲁棒,所以现在可以棒两个深浅信息都用起来
最后的反卷积层分两类1)固定为双线性插值,不学习2)初始化为双线性插值,需要学习
基础cnn网络:Alexnet、vgg。。
反池化操作:记录池化时选的是哪一个位置~开关变量,这样反池化时可以恢复
使用Alexnet构建FCN:
1、使用alexnet作为初始网络,保留参数;舍弃最后一个全连接层
2、替换两个同深度的卷积层(4096,1,1);追加一个预测卷积层(21,1,1);追加一个步长为32的双线性插值反卷积层
3、conv7进行2倍上采样;提取pool4输出,追加预测卷积层;相加融合;追加步长为1的双线性插值反卷积层
4、对上次融合结果2倍上采样;提取pool3输出,追加预测卷积层;相加融合;追加步长为8的双线性插值反卷积层
训练:
初始化:卷积层~前5个卷积层使用初始cnn网络的参数;剩余第六第七卷积层初始化为0
反卷积层~最后一层反卷积固定为双线性插值,不做学习;其他的需融合的需要学习
FCN网络缺点:
边缘检测性比较差,故第一个卷积层大量补0,之后做剪裁
代码:
https://blog.csdn.net/weixin_38437404/article/details/78089035?locationNum=10&fps=1
https://blog.csdn.net/dawei_01/article/details/79569466
TypeError: Can't convert 'bytes' object to str implicitly
解决方法:使用字节码的decode()方法。
示例:
str = 'I am string'
byte = b' I am bytes'
s = str + byte
print(s)
这时会报错:TypeError: Can't convert 'bytes' object to str implicitly
解决方法:
s = str + byte.decode()
evaluate:批量评估 reference:单个评估
utils:辅助类
@layer~装饰器:
Python装饰器的用法,具体教程看这个链接:http://wiki.jikexueyuan.com/project/explore-python/Functional/decorator.html
装饰器的作用是:封装成可以组装的基本网络层(卷积、膨胀卷积、池化等),方便组装复杂网络
装饰器用于装饰(包裹、封装)原有函数的输出,返回的是包装后的函数layer_decorated
需要装饰的函数,在其函数名上方追加装饰器@layer
对函数做封装,不改变函数本身的实现,但在其上再封装别的调用功能,如调用conv函数时,先调用装饰器,即def layer函数,并且传入要包装的函数,在layer decorated中解析要包装的函数的参数。
network.py:
return self-返回类对象,才能执行类相关操作
setup(self, is_training)网络构建函数,需要子类做实现
model.py:
DeepLab-ResNet-101网络定义,基于ResNet-101.
必须要继承network中的layer,否则其中的setup函数会报异常
(self.feed('data')
.conv(7, 7, 64, 2, 2, biased=False, relu=False, name='conv1')
.batch_normalization(is_training=is_training_bn, activation_fn=tf.nn.relu, name='bn_conv1')
.max_pool(3, 3, 2, 2, name='pool1')
# 残差直连的通道升维,因为此处特征的2D尺寸有降维
.conv(1, 1, 256, 1, 1, biased=False, relu=False, name='res2a_branch1')
.batch_normalization(is_training=is_training_bn, activation_fn=None, name='bn2a_branch1'))
返回值self之后追加各层,因为maxpool的步长为2,所以2d尺寸有降维,即长宽都减小了一半。所以在残差直连时需要通道升维,即从64升到256
# 第四卷积组,第22残差单元
# atrous膨胀卷积,Rate = 2
.atrous_conv(3, 3, 256, 2, padding='SAME', biased=False, relu=False, name='res4b21_branch2b')
第四卷机组共有23个残差单元,其中3*3的卷积使用膨胀卷积
Conv4第四卷机组用的rate=2
conv5第五卷机组用的rate=4
# 第六卷积组,atrous空间金字塔池化(4个并行膨胀卷积)
BATCH_SIZE = 4 --现存不够时,减少batchsize,最少为1
batchsize小是因为输出时密集输出,高分辨率的
# 获取不同类型的网络权重参数名
不同分组 -如可训练的、全连接的、w的--因为学习率时不同的
# 定义优化器
opt_conv = tf.train.MomentumOptimizer(learning_rate, args.momentum)
opt_fc_w = tf.train.MomentumOptimizer(learning_rate * 10.0, args.momentum)
opt_fc_b = tf.train.MomentumOptimizer(learning_rate * 20.0, args.momentum)
# 加载已有的checkpoint文件
if args.restore_from is not None:
loader = tf.train.Saver(var_list=restore_var)
手动、断电停止后,也可继续训练
load(loader, sess, args.restore_from)
Python装饰器的用法,具体教程看这个链接:
http://wiki.jikexueyuan.com/project/explore-python/Functional/decorator.html
装饰器的作用是:封装成可以组装的基本网络层(卷积、膨胀卷积、池化等),方便组装复杂网络
--》
可以看到,类 Bold
有两个方法:
__init__()
:它接收一个函数作为参数,也就是被装饰的函数__call__()
:让类对象可调用,就像函数调用一样,在调用被装饰函数时被调用
还可以让类装饰器带参数:
class Tag(object):
def __init__(self, tag):
self.tag = tag
def __call__(self, func):
def wrapped(*args, **kwargs):
return "<{tag}>{res}</{tag}>".format(
res=func(*args, **kwargs), tag=self.tag
)
return wrapped
@Tag('b')
def hello(name):
return 'hello %s' % name
需要注意的是,如果类装饰器有参数,则 __init__
接收参数,而 __call__
接收 func
。