深度学习论文: 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)
还没有任何评论哟~
