This repository contains a Caffe implementation of the paper Making Convolutional Networks Shift-Invariant Again.
BlurPool combine blur filter and subsample, then blur filter use gaussian blur in antialiased-cnns.
Provide subsample layer to support antialiased-cnns.
Forward:
Backward:
Gaussian blur use Deep Separable Convolution whit gauss initialization, gaussian kernel obeys std=0.1, and let lr_mult = 0 ,decay_mult = 0,fixed gaussian kernel weight.
- MaxPool(stride = 2)
layer {
bottom: "bottom"
top: "max_pool"
name: "max_pool"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 1
pad:1
}
}
layer {
bottom: "max_pool"
top: "blurconv"
name: "blurconv"
type: "ConvolutionDepthwise"
param {
lr_mult: 0
decay_mult: 0
}
convolution_param {
num_output: 64
bias_term: false
pad: 0
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.1
}
}
}
layer {
bottom: "blurconv"
top: "subsample"
name: "subsample"
type: "Subsample"
subsample_param {
kernel_size: 2
stride: 2
}
}
- Conv(stride = 2)+ReLU
layer {
bottom: "bottom"
top: "conv"
name: "conv"
type: "Convolution"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
bottom: "conv"
top: "conv"
name: "relu"
type: "ReLU"
}
layer {
bottom: "conv"
top: "blurconv"
name: "blurconv"
type: "ConvolutionDepthwise"
param {
lr_mult: 0
decay_mult: 0
}
convolution_param {
num_output: 64
bias_term: false
pad: 1
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.1
}
}
}
layer {
bottom: "blurconv"
top: "subsample"
name: "subsample"
type: "Subsample"
subsample_param {
kernel_size: 2
stride: 2
}
}
- AvePool(stride = 2)
layer {
bottom: "bottom"
top: "blurconv"
name: "blurconv"
type: "ConvolutionDepthwise"
param {
lr_mult: 0
decay_mult: 0
}
convolution_param {
num_output: 64
bias_term: false
pad: 1
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.1
}
}
}
layer {
bottom: "blurconv"
top: "subsample"
name: "subsample"
type: "Subsample"
subsample_param {
kernel_size: 2
stride: 2
}
}
- let pad = (kernel_size-1)/2 in ConvolutionDepthwise layer.
- BlurPool should be after ReLU layer, even if there is batchnormal layer between convolution layer and ReLU layer.
- Add Subsample layer
Modify caffe.proto like this:
Add option in LayerParameter:
message LayerParameter {
optional SubsampleParameter subsample_param = Your last ID;
}
Add message at the end:
message SubsampleParameter {
// Pad, kernel size, and stride are all given as a single value for equal
// dimensions in height and width or as Y, X pairs.
optional uint32 pad = 3 [default = 0]; // The padding size (equal in Y, X)
optional uint32 pad_h = 8 [default = 0]; // The padding height
optional uint32 pad_w = 9 [default = 0]; // The padding width
optional uint32 kernel_size = 1; // The kernel size (square)
optional uint32 kernel_h = 4; // The kernel height
optional uint32 kernel_w = 5; // The kernel width
optional uint32 stride = 2 [default = 1]; // The stride (equal in Y, X)
optional uint32 stride_h = 6; // The stride height
optional uint32 stride_w = 7; // The stride width
}
Add subsample_layer.hpp, subsample_layer.cpp and subsample_layer.cu to the specified folder.
- Add Deep Separable Convolution layer
Deep separable convolution does not need to be declared in caffe.proto.
Add conv_dw_layer.hpp, conv_dw_layer.cpp and conv_dw_layer.cu to the specified folder.
Deep Separable Convolution layer fork from Caffe sp2823.
Reference in vgg16_antialiase_train.prototxt,resnet18_antialiase_train.prototxt and Anti-aliasing common downsampling layers in caffe.