• lesson6-图像分割-小象c


    显著性检测: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

  • 相关阅读:
    Linux終端一行命令发送邮件
    团队冲刺2.4
    团队冲刺2.3
    团队冲刺2.2
    找水王
    评价win10自带输入法——微软拼音输入法
    梦断代码阅读笔记01
    团队冲刺2.1
    第十三周总结
    第十二周总结
  • 原文地址:https://www.cnblogs.com/rosyYY/p/8857628.html
Copyright © 2020-2023  润新知