【深度学习】深入浅出 CRF-RNN Layer(The End-to-end)
文章目录 1 概述 2 Initialization 3 Message Passing 4 Re-weighting 5 Compatibility Transform 6 Adding Unary Potentials 7 Normalization 1 概述本文所述方法有三个要点:
用训练的方式求解CRF。 把CRF挂在一个FCN后边,一起训练。 求解CRF时,用独立分布近似真实分布,其算法可以包装成一个RNN。网络结构
网络结构是前边一个FCN,后边挂上一个CRF-RNN,一起训练。第三大部分中的图展示了这个结构。
难题
对于每次迭代来说,FCN出来的是分类的Map,之后要求解CRF。CRF求解由于计算量太大,只能用估计的方式。所以,关键问题是:第一,如何估计?第二,如何在一个迭代里能够自动地求出CRF的结果?
作者利用Krähenbühl文章的算法,求解CRF。他巧妙地将求解步骤,设计成了一个RNN,从而在一个迭代中,能够求出CRF的解。
具体方法
将Krähenbühl文章的算法,拆解成几个步骤,每个步骤都作为一个CNN的Layer。
源码看的是基于keras实现的版本,代码在这里。CRFasRNN把fcn作为骨干网络,然后把fcn的输出作为CRF的二元势的初始化和一元势,前面fcn的部分不再赘述,文章中提出的CRFasRNN作为单独一层用TensorFlow实现,使用起来很简单:
output = CrfRnnLayer(image_dims=(height, weight), num_classes=21, theta_alpha=160., theta_beta=3., theta_gamma=3., num_iterations=10, name=crfrnn)([upscore, img_input])高斯核的参数theta_alpha,theta_beta,theta_gamma作为超参数直接给出,没有参与训练。 CrfRnnLayer的定义在crfrnn_layer.py中,继承了layer类,其中,build方法通过add_weight函数定义了该层可以训练的参数:
def build(self, input_shape): # Weights of the spatial kernel self.spatial_ker_weights = self.add_weight(name=spatial_ker_weights, shape=(self.num_classes, self.num_classes), initializer=_diagonal_initializer, trainable=True) # Weights of the bilateral kernel self.bilateral_ker_weights = self.add_weight(name=bilateral_ker_weights, shape=(self.num_classes, self.num_classes), initializer=_diagonal_initializer, trainable=True) # Compatibility matrix self.compatibility_matrix = self.add_weight(name=compatibility_matrix, shape=(self.num_classes, self.num_classes), initializer=_potts_model_initializer, trainable=True) super(CrfRnnLayer, self).build(input_shape)其中,spatial_ker_weights表示spatial kernel的权重,bilateral_ker_weights 表示bilateral kernel的权重 compatibility_matrix表示相似度矩阵。
A Mean-field Iteration as a Stack of CNN Layers 将DenseCRF变分推断的迭代求解过程表示成RNN的形式,方便和CNN骨干网络共同进行参数更新。要学习的参数是:Gaussian kernels的参数,label compatibility function等等。使用随机梯度下降学习参数。 为什么需要RNN(循环神经网络) 他们都只能单独的取处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。
比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列; 当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。 以nlp的一个最简单词性标注任务来说,将我 吃 苹果 三个单词标注词性为 我/nn 吃/v 苹果/nn。
那么这个任务的输入就是:
我 吃 苹果 (已经分词好的句子)
这个任务的输出是:
我/nn 吃/v 苹果/nn(词性标注好的句子)
对于这个任务来说,我们当然可以直接用普通的神经网络来做,给网络的训练数据格式了就是我-> 我/nn 这样的多个单独的单词->词性标注好的单词。
但是很明显,一个句子中,前一个单词其实对于当前单词的词性预测是有很大影响的,比如预测苹果的时候,由于前面的吃是一个动词,那么很显然苹果作为名词的概率就会远大于动词的概率,因为动词后面接名词很常见,而动词后面接动词很少见。
所以为了解决一些这样类似的问题,能够更好的处理序列的信息,RNN就诞生了。
RNN时间线展开图
2 Initializationsoftmax_out = tf.nn.softmax(q_values, 0) 3 Message Passing
massage passing是用M个高斯滤波器在Q QQ上进行滤波操作来实现的。使用high dimensional Gaussian filtering加速。
在 dense CRF 中,通过在 Q QQ 值上应用 M MM Gaussian filter 来实现 Message passing(消息传递)
高斯滤波参数 是根据图像特征(比如像素位置 和 RGB值)得出的,它反映了某一像素和其他像素之间的关联有多强。
由于 CRF 可能是全连接的,每个滤波器的接收域覆盖整个图像,所以要强行实现这些滤波器不可行。 但是有一些近似的方法可以加快高维高斯滤波的计算速度
使用置换点阵实现,它可以在 O(N) 时间内计算滤波响应,其中 N 是图像的像素数。 高斯滤波
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。 通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
4 Re-weighting是赋权法的一种,是指在训练过程的每一轮中,可根据样本分布为每个训练样本重新赋予权重
5 Compatibility Transform 6 Adding Unary Potentials 7 Normalization免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:深入浅出 CRF-RNN Layer(The End-to-end) https://www.yhzz.com.cn/a/12179.html