【深度学习】深度神经网络后处理之全连接CRFs(DenseCRF)

这把我C 2021-06-07 17:47:54 14407

【深度学习】深度神经网络后处理之全连接CRFs(DenseCRF)

文章目录
1 概述
2 条件随机场
    2.1 什么样的问题需要CRF模型
    2.2 随机场到马尔科夫随机场
    2.3 从马尔科夫随机场到条件随机场
3 python实现图像分割CRFs后处理
4 全连接CRF用于精确定位
5 CRFasRNN
6 总结

1 概述

目前图像像素级语义分割比较流行使用深度学习全卷积神经网络FCN或者各种FCN的改进版U-Net、V-Net、SegNet等方法。这些模型中使用了反卷积层进行上采样操作,虽然能够将特征图恢复至原图尺寸,但也造成了特征的损失,自然而然产生了分类目标边界模糊的问题。为了得到更精确的最终分类结果,通常要进行一些图像后处理。全连接CRFs是在目前深度学习图像分割应用中常用的一种图像后处理方式,它是CRFs的改进模式,能够结合原始影像中所有像素之间的关系对深度学习得到的分类结果进行处理,优化分类图像中粗糙和不确定性的标记,修正细碎的错分区域,同时得到更细致的分割边界。

全连接CRFs原理物体通常由大的空间相邻的区域表示,每个像素 都拥有一个类别标签 i ,而且还有一个对应观测值 ,这样在无向图中每个像素点都成为某一个节点,若使用像素与像素之间的关系作为边连接,这样就组成了条件随机场。最终目的就是使用观测值 来推测这个像素i本来拥有的类别标签 ,如下图所示:
在这里插入图片描述
全连接CRFs与稀疏CRFs的最大差别在于:每个像素点都与所有的像素点相连接构成连接边。如果一张图像大小是256256,那么就相当于有65536个像素点,因此如果采用全连接CRFs的话,那么就会构造出6553665536条边。如果图像大小再大一些,那么就会变得十分恐怖,普通条件随机场推理算法根本行不通。这时,文献《Efficient Inference in Fully Connected CRFs with Gaussian Edge Potentials》给出了快速推理算法

在这里插入图片描述

在这里插入图片描述

全连接条件随机场使用二元势函数解释了一个像素与另一个像素之间的关系,给像素关系紧密的两个像素赋予相同的类别标签,而关系相差很大的两个像素会赋予不同的类别标签,这个“关系”的判断与像素的颜色值、像素间的相对距离都有关系。全连接条件随机场中二元势函数解释了每一个像素与其他所有像素的关系,与条件随机场相比,“全连接”更加紧密一些。在全连接CRFs进行影像后处理的实际操作中,一元势能为概率分布图,即由模型输出的特征图经过softmax函数运算得到的结果;二元势能中的位置信息和颜色信息由原始影像提供。当能量E(x)越小时,预测的类别标签X就越准确,我们通过迭代最小化能量函数,得到最终的后处理结果。

2 条件随机场

简单而又直白的讲,线性条件随机场,是只考虑 概率图中相邻变量是否满足特征函数的一个模型。
在这里插入图片描述
在这里插入图片描述

2.1 什么样的问题需要CRF模型

这里举一个简单的例子:假设有Bob一天从早到晚的一系列照片,Bob想考考我们,要我们猜这一系列的每张照片对应的活动,比如: 工作的照片,吃饭的照片,唱歌的照片等等。一个比较直观的办法就是,我们找到Bob之前的日常生活的一系列照片,然后找Bob问清楚这些照片代表的活动标记,这样我们就可以用监督学习的方法来训练一个分类模型,比如逻辑回归,接着用模型去预测这一天的每张照片最可能的活动标记。

这种办法虽然是可行的,但是却忽略了一个重要的问题,就是这些照片之间的顺序其实是有很大的时间顺序关系的,而用上面的方法则会忽略这种关系。比如我们现在看到了一张Bob闭着嘴的照片,那么这张照片我们怎么标记Bob的活动呢?比较难去打标记。但是如果我们有Bob在这一张照片前一点点时间的照片的话,那么这张照片就好标记了。如果在时间序列上前一张的照片里Bob在吃饭,那么这张闭嘴的照片很有可能是在吃饭咀嚼。而如果在时间序列上前一张的照片里Bob在唱歌,那么这张闭嘴的照片很有可能是在唱歌。

为了让我们的分类器表现的更好,可以在标记数据的时候,可以考虑相邻数据的标记信息。这一点,是普通的分类器难以做到的。而这一块,也是CRF比较擅长的地方。

2.2 随机场到马尔科夫随机场

首先,我们来看看什么是随机场。“随机场”的名字取的很玄乎,其实理解起来不难。随机场是由若干个位置组成的整体,当给每一个位置中按照某种分布随机赋予一个值之后,其全体就叫做随机场。还是举词性标注的例子:假如有一个十个词形成的句子需要做词性标注。这十个词每个词的词性可以在已知的词性集合(名词,动词...)中去选择。当我们为每个词选择完词性后,这就形成了一个随机场。

了解了随机场,我们再来看看马尔科夫随机场。马尔科夫随机场是随机场的特例,它假设随机场中某一个位置的赋值仅仅与和它相邻的位置的赋值有关,和与其不相邻的位置的赋值无关。继续举十个词的句子词性标注的例子: 如果我们假设所有词的词性只和它相邻的词的词性有关时,这个随机场就特化成一个马尔科夫随机场。比如第三个词的词性除了与自己本身的位置有关外,只与第二个词和第四个词的词性有关。 

2.3 从马尔科夫随机场到条件随机场

CRF是马尔科夫随机场的特例,它假设马尔科夫随机场中只有X和Y两种变量,X一般是给定的,而Y一般是在给定X的条件下的输出。这样马尔科夫随机场就特化成了条件随机场。在我们十个词的句子词性标注的例子中,X是词,Y是词性。因此,如果我们假设它是一个马尔科夫随机场,那么它也就是一个CRF。

对于CRF,给出准确的数学语言描述:设X与Y是随机变量,P(Y|X)是给定X时Y的条件概率分布,若随机变量Y构成的是一个马尔科夫随机场,则称条件概率分布P(Y|X)是条件随机场。

3 python实现图像分割CRFs后处理

安装 pydensecrf
https://blog.csdn.net/weixin_42181588/article/details/89322067

import numpy as np
import pydensecrf.densecrf as dcrf
try:
    from cv2 import imread, imwrite
except ImportError:
    # 如果没有安装OpenCV,就是用skimage
    from skimage.io import imread, imsave
    imwrite = imsave
from pydensecrf.utils import unary_from_labels, create_pairwise_bilateral, create_pairwise_gaussian

"""
original_image_path  原始图像路径
predicted_image_path  之前用自己的模型预测的图像路径
CRF_image_path  即将进行CRF后处理得到的结果图像保存路径
"""
def CRFs(original_image_path,predicted_image_path,CRF_image_path):

    img = imread(original_image_path)

    # 将predicted_image的RGB颜色转换为uint32颜色 0xbbggrr
    anno_rgb = imread(predicted_image_path).astype(np.uint32)
    anno_lbl = anno_rgb[:,:,0] + (anno_rgb[:,:,1] << 8) + (anno_rgb[:,:,2] << 16)

    # 将uint32颜色转换为1,2,...
    colors, labels = np.unique(anno_lbl, return_inverse=True)

    # 如果你的predicted_image里的黑色(0值)不是待分类类别,表示不确定区域,即将分为其他类别
    # 那么就取消注释以下代码
    #HAS_UNK = 0 in colors
    #if HAS_UNK:
    #colors = colors[1:]

    # 创建从predicted_image到32位整数颜色的映射。
    colorize = np.empty((len(colors), 3), np.uint8)
    colorize[:,0] = (colors & 0x0000FF)
    colorize[:,1] = (colors & 0x00FF00) >> 8
    colorize[:,2] = (colors & 0xFF0000) >> 16

    # 计算predicted_image中的类数。
    n_labels = len(set(labels.flat))
    #n_labels = len(set(labels.flat)) - int(HAS_UNK) ##如果有不确定区域,用这一行代码替换上一行

    ###########################
    ###     设置CRF模型     ###
    ###########################
    use_2d = False               
    #use_2d = True   
    ###########################################################   
    ##不是很清楚什么情况用2D        
    ##作者说“对于图像,使用此库的最简单方法是使用DenseCRF2D类”
    ##作者还说“DenseCRF类可用于通用(非二维)密集CRF”
    ##但是根据我的测试结果一般情况用DenseCRF比较对
    #########################################################33
    if use_2d:                   
        # 使用densecrf2d类
        d = dcrf.DenseCRF2D(img.shape[1], img.shape[0], n_labels)

        # 得到一元势(负对数概率)
        U = unary_from_labels(labels, n_labels, gt_prob=0.2, zero_unsure=None)
        #U = unary_from_labels(labels, n_labels, gt_prob=0.2, zero_unsure=HAS_UNK)## 如果有不确定区域,用这一行代码替换上一行
        d.setUnaryEnergy(U)

        # 增加了与颜色无关的术语,功能只是位置而已
        d.addPairwiseGaussian(sxy=(3, 3), compat=3, kernel=dcrf.DIAG_KERNEL,
                              normalization=dcrf.NORMALIZE_SYMMETRIC)

        # 增加了颜色相关术语,即特征是(x,y,r,g,b)
        d.addPairwiseBilateral(sxy=(80, 80), srgb=(13, 13, 13), rgbim=img,compat=10,
                               kernel=dcrf.DIAG_KERNEL,
                               normalization=dcrf.NORMALIZE_SYMMETRIC)
    else:
        # 使用densecrf类
        d = dcrf.DenseCRF(img.shape[1] * img.shape[0], n_labels)

        # 得到一元势(负对数概率)
        U = unary_from_labels(labels, n_labels, gt_prob=0.7, zero_unsure=None)  
        #U = unary_from_labels(labels, n_labels, gt_prob=0.7, zero_unsure=HAS_UNK)## 如果有不确定区域,用这一行代码替换上一行
        d.setUnaryEnergy(U)

        # 这将创建与颜色无关的功能,然后将它们添加到CRF中
        feats = create_pairwise_gaussian(sdims=(3, 3), shape=img.shape[:2])
        d.addPairwiseEnergy(feats, compat=3,kernel=dcrf.DIAG_KERNEL,
                            normalization=dcrf.NORMALIZE_SYMMETRIC)

        # 这将创建与颜色相关的功能,然后将它们添加到CRF中
        feats = create_pairwise_bilateral(sdims=(80, 80), schan=(13, 13, 13),
                                          img=img, chdim=2)
        d.addPairwiseEnergy(feats, compat=10,
                            kernel=dcrf.DIAG_KERNEL,
                            normalization=dcrf.NORMALIZE_SYMMETRIC)

    ####################################
    ###         做推理和计算         ###
    ####################################

    # 进行5次推理
    Q = d.inference(5)

    # 找出每个像素最可能的类
    MAP = np.argmax(Q, axis=0)

    # 将predicted_image转换回相应的颜色并保存图像
    MAP = colorize[MAP,:]
    imwrite(CRF_image_path, MAP.reshape(img.shape))
    print("CRF图像保存在",CRF_image_path,"!")

    CRFs("original.png","predict.png","predict_CRFs.png")

4 全连接CRF用于精确定位

在这里插入图片描述

在这里插入图片描述
飞机图像的得分图(softmax功能前的输入)和置信图(softmax功能的输出)。我们在每个平均场迭代后显示得分(第一行)和置信(第二行)图。 最后一个DCNN层的输出用作平均场推理方法的输入

5 CRFasRNN

最开始使用DenseCRF是直接加在FCN的输出后面,可想这样是比较粗糙的。而且在深度学习中,我们都追求end-to-end的系统,所以CRFasRNN这篇文章将DenseCRF真正结合进了FCN中。

这篇文章也使用了平均场近似的方法,因为分解的每一步都是一些相乘相加的计算,和普通的加减(具体公式还是看论文吧),所以可以方便的把每一步描述成一层类似卷积的计算。这样即可结合进神经网络中,并且前后向传播也不存在问题。

6 总结

概率图模型的网络化。因为PGM通常不太方便加入DL的模型中,将PGM网络化后能够是PGM参数自学习,同时构成end-to-end的系统。
U-Net with a CRF-RNN layer
在这里插入图片描述

在这里插入图片描述

https://github.com/EsmeYi/UNet-CRF-RNN

crfrnn_layer.py

在这里插入图片描述

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 98 7 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
这把我C
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区