图像上采样upsampling的主要目的是放大图像,主要包括:

(1)几乎都是采用内插值法,即在原有图像像素的基础上,在像素点值之间采用合适的插值算法插入新的元素;

(2)反卷积方法(Deconvolution),又称转置卷积法(Transposed Convolution);

(3)反池化方法(Unpooling)。

参见:CNN中的卷积、反卷积与反池化

1 线性插值法(linear interpolation) 


  这里讲解线性插值法的推导为了给双线性插值公式做铺垫。 

  线性插值法是指使用连接两个已知量的直线来确定在这个两个已知量之间的一个未知量的值的方法。 


    

线性插值tensorflow_卷积

线性插值tensorflow_深度学习_02

线性插值tensorflow_FCN_03

2 双线性插值 

  双线性插值是插值算法中的一种,是线性插值的扩展。利用原图像中目标点四周的四个真实存在的像素值来共同决定目标图中的一个像素值,其核心思想是在两个方向分别进行一次线性插值。 

线性插值tensorflow_卷积_04

线性插值tensorflow_卷积_05

具体的实现方式,可以直接参考fcn.berkerlyvision.org中的surgery.py如下:

def upsample_filt(size):
    """
    Make a 2D bilinear kernel suitable for upsampling of the given (h, w) size.
    """
    factor = (size + 1) // 2
    if size % 2 == 1:
        center = factor - 1
    else:
        center = factor - 0.5
    og = np.ogrid[:size, :size]
    return (1 - abs(og[0] - center) / factor) * \
           (1 - abs(og[1] - center) / factor)


如果看了上面的简单实例和具体代码还不会使用bilinear,就看最后一个例子,这里以FCN举例。 在FCN的berkerly官方caffe实现,以voc-fcn32/train.prototxt举例,bilinear部分代码如下:(此部分没看懂,先放这)

layer {
  name: "score_fr"
  type: "Convolution"
  bottom: "fc7"
  top: "score_fr"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 21
    pad: 0
    kernel_size: 1
  }
}
layer {
  name: "upscore"
  type: "Deconvolution"
  bottom: "score_fr"
  top: "upscore"
  param {
    lr_mult: 0
  }
  convolution_param {
    num_output: 21
    bias_term: false
    kernel_size: 64
    stride: 32
  }
}

其中,upscore层使用surgery.py中的upsample_filt函数进行实现(本文第一段代码),相当于设置参数type: ‘bilinear’,这个很容易实现。通过测试可以发现,在forward-propagation过程中,score_fr层的blob shape是[1, 21, 16, 16],经过bilinear后变为[1, 21, 544, 544]。依照代码简单分析就可以发现bilinear的具体计算流程如下: 

(1) 64%2 == 0,所以center的坐标为(31.5, 31.5),note在python中下标从0开始;

(2) 计算出一个64x64的矩阵,每个位置根据代码所示填数,其实就是线性规则 ;

(3) 二维来看,将score_fr层的16x16的每一个位置的坐标放在31.5位置,也就是在相邻元素之间插入32个位置,周边补充32个位置,不同元素对插入的不同值有影响,则相互叠加,最后将原来的16x16的元素移除,也就形成了32x17 = 544,也就是具体upscore层算出来的值。

形象表示结果: 


32个元素 [16x16中的(0,0)元素] 32个元素 [16x16中的(0,1)元素] 32个元素 … 


其中,中括号中的元素不可见。


参考:

1.FCN中反卷积、上采样、双线性插值之间的关系


2.Transposed Convolution, Fractionally Strided Convolution or Deconvolution

http://buptldy.github.io/2016/10/29/2016-10-29-deconv/


3.更多关于卷积和反卷积的可视化理解:

https://github.com/vdumoulin/conv_arithmetic 

4.计算机视觉中upsampling(上采样)的三种方式