双线性插值和转置卷积

  1. 小小问答
  2. 双线性插值代码
  3. 参考链接

先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值
得到公式:
$$\frac {y - y_0}{x - x_0} = \frac {y_1 - y_0}{x_1 - x_0}$$
$$y = \frac {x_1 - x}{x_1 -x_0}y_0 + \frac{x - x_0}{x_1 - x_0}y_1$$

通常我们训练的时候可以随机初始化权重,但是在 fcn 的网络中,使用随机初始化的权重将会需要大量的时间进行训练,所以我们卷积层可以使用在 imagenet 上预训练的权重,那么转置卷积我们使用什么样的初始权重呢?这里就要用到 bilinear kernel。

# 定义 bilinear kernel
def bilinear_kernel(in_channels, out_channels, kernel_size):
    '''return a bilinear filter tensor
    '''
    factor = (kernel_size + 1) // 2
    if kernel_size % 2 == 1:
        center = factor - 1
    else:
        center = factor - 0.5
    og = np.ogrid[:kernel_size, :kernel_size]
    filt = (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor)
    weight = np.zeros((in_channels, out_channels, kernel_size, kernel_size), dtype='float32')
    weight[range(in_channels), range(out_channels), :, :] = filt
    return torch.from_numpy(weight)

小小问答

  1. 双线性插值和转置卷积在进行上采样的时候,有什么区别吗?

  2. 转置卷积和膨胀卷积的区别,分别在哪些网络被使用(FCN\UNET\DEEPLAB)

  3. pytorch中,转置卷积的API output_padding是什么?什么时候用呢?存在的意义是什么?

双线性插值代码

import numpy as np
import cv2
from PIL import Image
from utils.image_process import crop_resize_data

def Bilinear_interpolation(src, new_size):
    dst_w, dst_h = new_size[:2] #目标图像的 W H
    src_h, src_w = src.shape[:2]
    if src_h == dst_h and src_w == dst_w:
        return src.copy()
    # 得到缩放比, 定位目标点在原图的位置
    scale_x = float(src_w)/dst_w
    scale_y = float(src_h)/dst_h

    dst = np.zeros((dst_h, dst_w, 3))

    for n in range(3): # 循环channels
        for dst_y in range(dst_h): # 循环高
            for dst_x in range(dst_w): #循环宽
                # 得到目标像素点在原图上的坐标
                # 每个像素点都是一个边长为1的正方形,位于(h,w)的像素点,她的中心是(h+0.5,w+0.5)
                src_x = (dst_x + 0.5) * scale_x-0.5
                src_y = (dst_y +0.5) * scale_y -0.5

                # top_left point
                src_x_0 = int(np.floor(src_x))
                src_y_0 = int(np.floor(src_y))

                # 像素值的坐标为整数, 边界为1, 防止出界
                src_x_1 = min(src_x_0+1, src_w -1)
                src_y_1 = min(src_y_0+1, src_h -1)

                value_0 = (src_x_1 - src_x)*src[src_y_0,src_x_0,n] + (src_x-src_x_0)*src[src_y_0,src_x_1,n]
                value_1 = (src_x_1 - src_x)*src[src_y_1,src_x_0,n] + (src_x-src_x_0)*src[src_y_1,src_x_1,n]
                dst[dst_y,dst_x,n] = int((src_y_1-src_y)*value_0) + int((src_y-src_y_0)*value_1)
                dst[dst>255]=255
                dst[dst<0]=0
    return dst.astype('uint8')

参考链接

https://medium.com/activating-robotic-minds/up-sampling-with-transposed-convolution-9ae4f2df52d0
https://blog.csdn.net/qq_41368247/article/details/86626446
https://rosettacode.org/wiki/Bilinear_interpolation

Make a pause between images display in openCV:
https://stackoverflow.com/questions/46671348/make-a-pause-between-images-display-in-opencv


请多多指教。

文章标题:双线性插值和转置卷积

本文作者:顺强

发布时间:2018-03-11, 23:59:00

原始链接:http://shunqiang.ml/cnn-bilinear-convtranspose/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏