CRFasRNN论文+源码

源码看的是基于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表示相似度矩阵。

4. A Mean-field Iteration as a Stack of CNN Layers

将DenseCRF变分推断的迭代求解过程表示成RNN的形式,方便和CNN骨干网络共同进行参数更新。要学习的参数是:Gaussian kernels的参数,label compatibility function等等。使用随机梯度下降学习参数。

4.1. Initialization

Q i ( l ) ← 1 Z i exp ⁡ ( U i ( l ) )  for all  i Q_{i}(l) \leftarrow \frac{1}{Z_{i}} \exp \left(U_{i}(l)\right) \text { for all } i Qi(l)Zi1exp(Ui(l)) for all i
CRF的一元势的初始化由CNN网络的输出结果直接给出: Q i ( l ) ← 1 Z i exp ⁡ ( U i ( l ) ) Q_{i}(l) \leftarrow \frac{1}{Z_{i}} \exp \left(U_{i}(l)\right) Qi(l)Zi1exp(Ui(l)),其中 Z i = ∑ l exp ⁡ ( U i ( l ) ) Z_{i}=\sum_{l} \exp \left(U_{i}(l)\right) Zi=lexp(Ui(l))对每分配给 i i i像素的每个标签的概率值进行归一化。
这个操作可以直接由 s o f t m a x softmax softmax完成,不需要参数。

softmax_out = tf.nn.softmax(q_values, 0)

4.2 Message Passing

Q ~ i ( m ) ( l ) ← ∑ j ≠ i k ( m ) ( f i , f j ) Q j ( l )  for all  m \tilde{Q}_{i}^{(m)}(l) \leftarrow \sum_{j \neq i} k^{(m)}\left(\mathbf{f}_{i}, \mathbf{f}_{j}\right) Q_{j}(l) \text { for all } m Q~i(m)(l)j̸=ik(m)(fi,fj)Qj(l) for all m
massage passing是用M个高斯滤波器在 Q Q Q上进行滤波操作来实现的。使用high dimensional Gaussian filtering加速。

# Spatial filtering
            spatial_out = custom_module.high_dim_filter(softmax_out, rgb, bilateral=False,
                                                        theta_gamma=self.theta_gamma)
            spatial_out = spatial_out / spatial_norm_vals

            # Bilateral filtering
            bilateral_out = custom_module.high_dim_filter(softmax_out, rgb, bilateral=True,
                                                          theta_alpha=self.theta_alpha,
                                                          theta_beta=self.theta_beta)
            bilateral_out = bilateral_out / bilateral_norm_vals

其中,spatial_norm_valsbilateral_norm_vals是归一化系数:

c, h, w = self.num_classes, self.image_dims[0], self.image_dims[1]
        all_ones = np.ones((c, h, w), dtype=np.float32)

        # Prepare filter normalization coefficients
        spatial_norm_vals = custom_module.high_dim_filter(all_ones, rgb, bilateral=False,
                                                          theta_gamma=self.theta_gamma)
        bilateral_norm_vals = custom_module.high_dim_filter(all_ones, rgb, bilateral=True,
                                                            theta_alpha=self.theta_alpha,
                                                            theta_beta=self.theta_beta)

4.3 Weighting Filter Outputs

Q ˇ i ( l ) ← ∑ m w ( m ) Q ~ i ( m ) ( l ) \check{Q}_{i}(l) \leftarrow \sum_{m} w^{(m)} \tilde{Q}_{i}^{(m)}(l) Qˇi(l)mw(m)Q~i(m)(l)
mean-field iteration的下一步是对上一步用M个滤波器滤波的结果进行求和,对每个类别标签 l l l,如果每个类别单独考虑,就相当于在M个通道上进行1*1的卷积操作,并且得到一个通道数为1的输出。这里的参数也可以用反向传播来学习。为了得到更多的可调节参数,对每个类别 l l l,我们使用独立的核权重。这样做的动机是spatial kernel 与 bilateral kernel的相对重要性取决于目标的类别。例如,bilateral kernel在自行车检测中可能具有很高的重要性,因为颜色的相似性是决定性的;另一方面,由于电视屏幕内的任何东西可能有不同的颜色,它们对电视检测的重要性可能较低。

张量的维度从w* h* M–>w* h* L
在实现时直接使用等效的全连接操作替代。

# Weighting filter outputs
            message_passing = (tf.matmul(self.spatial_ker_weights,
                                         tf.reshape(spatial_out, (c, -1))) +
                               tf.matmul(self.bilateral_ker_weights,
                                         tf.reshape(bilateral_out, (c, -1))))
            # tf.matmul矩阵乘法

4.4 Compatibility Transform

Q ^ i ( l ) ← ∑ l ′ ∈ L μ ( l , l ′ ) Q ˇ i ( l ) \hat{Q}_{i}(l) \leftarrow \sum_{l^{\prime} \in \mathcal{L}} \mu\left(l, l^{\prime}\right) \check{Q}_{i}(l) Q^i(l)lLμ(l,l)Qˇi(l)
标签的相似性函数 μ ( l , l ′ ) \mu (l,l') μ(l,l)参数化表示了两个标签 l l l l ′ l' l的相似性,使用Potts model: μ ( l , l ′ ) = [ l ≠ l ′ ] \mu(l,l')=[l \neq l'] μ(l,l)=[l̸=l],其中, [ . ] [.] [.]表示Iverson bracket:[P] has the value 1 if P is true, and 0 if P is false,如果将不同的标签分配给具有相似属性的像素,则指定固定的惩罚。该模型的一个局限性是,它为所有不同的标签分配相同的惩罚。一个直观的理解是,通过考虑不同标签对之间的兼容性并相应地惩罚赋值,可以获得更好的结果。
Compatibility Transform可以用另一个卷积操作来表示,卷积核尺寸是1*1,输入和输出的通道数都为L,学习到的卷积核的权重就等于学习标签的兼容性函数 μ \mu μ

张量的维度从w* h* L–>w* h* L
在实现时直接使用等效的全连接操作替代。

# Compatibility transform
pairwise = tf.matmul(self.compatibility_matrix, message_passing)

4.5. Adding Unary Potentials

Q ˘ i ( l ) ← U i ( l ) − Q ^ i ( l ) \breve{Q}_{i}(l) \leftarrow U_{i}(l)-\hat{Q}_{i}(l) Q˘i(l)Ui(l)Q^i(l)
直接让两个张量相减。

张量的维度从w* h* L–>w* h* L

# Adding unary potentials
pairwise = tf.reshape(pairwise, (c, h, w))
q_values = unaries - pairwise

4.6. Normalization

Q i ← 1 Z i exp ⁡ ( Q ˘ i ( l ) ) Q_{i} \leftarrow \frac{1}{Z_{i}} \exp \left(\breve{Q}_{i}(l)\right) QiZi1exp(Q˘i(l))
再进行一次softmax操作。

5. The End-to-end Trainable Network

5.1. CRF as RNN

在文章的其他部分,我们可以知道变分推断的一个迭代流程可以表示为一系列CNN层的堆叠,我们使用 f θ f_{\theta} fθ函数表示变分推断一个流程的迭代:

输入:
输入图像 I I I,像素级别的一元势的值 U U U,和边缘概率的估计值(即为每个像素属于每个类别的概率) Q i n Q_{in} Qin,这个可以从上次迭代或者初始化过程中得到。

输出:
下次变分推断的迭代结果可以表示为: f θ ( U , Q i n , I ) f_{\theta}(U,Q_{in},I) fθ(U,Qin,I),向量 θ = { w m , μ ( l , l ′ ) } , m ∈ { 1 , . . . , M } , l , l ′ ∈ { l 1 , . . . , l L } \theta =\{ w^{m},\mu(l,l') \},m \in \{1,...,M \},l,l' \in \{l_1,... , l_L \} θ={wm,μ(l,l)},m{1,...,M},l,l{l1,...,lL}表示 C R F CRF CRF的参数。

可以通过重复实现多个平均场迭代,上述叠层以这样的方式堆叠,每个层迭代从先前的迭代获取Q值估计,和它们的原始形式的一元值。这是等价的将迭代平均场推断处理为循环的神经网络(RNN)。网络的行为由以下公式给出,其中H1、H2是隐藏的。状态和T是平均场迭代次数:
H 1 ( t ) = { softmax ⁡ ( U ) , t = 0 H 2 ( t − 1 ) , 0 < t ≤ T H_{1}(t)=\left\{\begin{array}{ll}{\operatorname{softmax}(U),} & {t=0} \\ {H_{2}(t-1),} & {0<t \leq T}\end{array}\right. H1(t)={softmax(U),H2(t1),t=00<tT
H 2 ( t ) = f θ ( U , H 1 ( t ) , I ) , 0 ≤ t ≤ T H_{2}(t)=f_{\boldsymbol{\theta}}\left(U, H_{1}(t), I\right), \quad 0 \leq t \leq T H2(t)=fθ(U,H1(t),I),0tT
Y ( t ) = { 0 , 0 ≤ t < T H 2 ( t ) , t = T Y(t)=\left\{\begin{array}{ll}{0,} & {0 \leq t<T} \\ {H_{2}(t),} & {t=T}\end{array}\right. Y(t)={0,H2(t),0t<Tt=T

5.2. Completing the Picture

FCN输出的结果作为二元势的初始化和一元势输入,使用SGD更新参数。

你可能感兴趣的:(图像分割)