Advertisement

深度学习论文: Making Convolutional Networks Shift-Invariant Again及其PyTorch实现

阅读量:

深度学习领域的研究论文:《Revisiting the Shift-Invariance of Convolutional Networks及其PyTorch实现》
Revisiting the Shift-Invariance of Convolutional Networks
PDF下载链接:https://arxiv.org/pdf/1904.11486.pdf
深度学习模型实现:https://github.com/shanglianlm0525/CvPytorch
深度学习模型实现:https://github.com/shanglianlm0525/PyTorch-Networks

1 概述

在CNN架构中使用的下采样过程因未满足采样定理而无法保证平移不变性。而在信号处理领域针对这类问题通常采用提高采样率或应用抗混叠技术来解决。其中,在图像处理领域中使用stride=1即可实现这一目标。然而,在图像处理中设置stride=1已经是极限。本文主要致力于通过应用抗混叠技术使CNN恢复其平移不变性。

在这里插入图片描述

2 Anti-aliasing

在进行抗混叠处理时,在图像或信号中通过应用特定的抗混叠滤波器来消除由于频率叠加而产生的混淆现象(即所谓的" aliasing"),其具体步骤包括首先对目标信号施加低通滤波器以去除高于 Nyquist 速率的部分频谱内容(即所谓的" pre-filtering"),接着进行采样操作以便获得高质量的样本数据集(从而有效避免因高频信号的存在而导致的采样不达标的问题)。

在这里插入图片描述

PyTorch代码:

复制代码
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import numpy as np
    
    
    def get_pad_layer(pad_type):
    if(pad_type in ['refl','reflect']):
        PadLayer = nn.ReflectionPad2d
    elif(pad_type in ['repl','replicate']):
        PadLayer = nn.ReplicationPad2d
    elif(pad_type=='zero'):
        PadLayer = nn.ZeroPad2d
    else:
        print('Pad type [%s] not recognized'%pad_type)
    return PadLayer
    
    
    class BlurPool2D(nn.Module):
    """
        Making Convolutional Networks Shift-Invariant Again
        https://arxiv.org/abs/1904.11486
    """
    def __init__(self, channels, pad_type='reflect', filt_size=4, stride=2, pad_off=0):
        super(BlurPool2D, self).__init__()
        self.filt_size = filt_size
        self.pad_off = pad_off
        self.pad_sizes = [int(1.*(filt_size-1)/2), int(np.ceil(1.*(filt_size-1)/2)), int(1.*(filt_size-1)/2), int(np.ceil(1.*(filt_size-1)/2))]
        self.pad_sizes = [pad_size+pad_off for pad_size in self.pad_sizes]
        self.stride = stride
        self.off = int((self.stride-1)/2.)
        self.channels = channels
    
        if(self.filt_size==1):
            a = np.array([1.,])
        elif(self.filt_size==2):
            a = np.array([1., 1.])
        elif(self.filt_size==3):
            a = np.array([1., 2., 1.])
        elif(self.filt_size==4):
            a = np.array([1., 3., 3., 1.])
        elif(self.filt_size==5):
            a = np.array([1., 4., 6., 4., 1.])
        elif(self.filt_size==6):
            a = np.array([1., 5., 10., 10., 5., 1.])
        elif(self.filt_size==7):
            a = np.array([1., 6., 15., 20., 15., 6., 1.])
    
        filt = torch.Tensor(a[:,None]*a[None,:])
        filt = filt/torch.sum(filt)
        self.register_buffer('filt', filt[None,None,:,:].repeat((self.channels,1,1,1)))
    
        self.pad = get_pad_layer(pad_type)(self.pad_sizes)
    
    def forward(self, inp):
        if(self.filt_size==1):
            if(self.pad_off==0):
                return inp[:,:,::self.stride,::self.stride]
            else:
                return self.pad(inp)[:,:,::self.stride,::self.stride]
        else:
            return F.conv2d(self.pad(inp), self.filt, stride=self.stride, groups=inp.shape[1])
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

全部评论 (0)

还没有任何评论哟~