美文网首页
Transpose Convolution Initializa

Transpose Convolution Initializa

作者: 是许嘉晨 | 来源:发表于2018-12-08 11:49 被阅读0次

    第一篇博客首先感谢我的女朋友姜旭艳小姐的大力支持 😊


    在语义分割问题中经常出现的操作就是反卷积,目的是将图片从较小的分辨率放大到更大的分辨率。反卷积层的参数初始化在训练过程中有很大的作用,如果采用随机初始化可能导致训练时间更长或者是效果不好,所以往往采用的是bilinear kernel初始化。

    bilinear kernel实现代码

    def upsample_filt(size):
        """
        size: Size of the filter
        """
        factor = (size + 1) 
        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)
    
    # 以 size = 4 为例
    
    factor = 5
    center = 1.5
    og = 
    [array([[0],
           [1],
           [2],
           [3]]), array([[0, 1, 2, 3]])]
    
    abs(og[0] - center) = 
    [[ 1.5]
     [ 0.5]
     [ 0.5]
     [ 1.5]]
    
    # 显然 abs(og[0] - center) 表示的是图像上每一个像素点到中心点(center)的距离
    # 然后再利用核长度 factor 进行归一化
    # 之所以 factor = size + 1 是因为将中心点也考虑进来了 所以总共有 size + 1 个像素
    # 然后 (1 - abs(og[0] - center) / factor) 表示的就是在x轴方向上每个像素点的权重
    # 距离越远权重越小
    # 最后将x和y轴上的值相乘得到整个图像上每个像素点的权重
    
    1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor = 
    [[ 0.0625  0.1875  0.1875  0.0625]
     [ 0.1875  0.5625  0.5625  0.1875]
     [ 0.1875  0.5625  0.5625  0.1875]
     [ 0.0625  0.1875  0.1875  0.0625]]
    

    在反卷积核中卷积核是一个四维变量[in_channels, out_channels, H, W],所以需要将卷积核的每一层都用上述的双线性插值核来赋值。
    因此完整的初始化代码为

    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)
    
    conv_trans = nn.ConvTranspose2d(3, 3, 4, 2, 1)
    # 将其定义为 bilinear kernel
    conv_trans.weight.data = bilinear_kernel(3, 3, 4)
    

    相关文章

      网友评论

          本文标题:Transpose Convolution Initializa

          本文链接:https://www.haomeiwen.com/subject/refqhqtx.html