Spatial Reflection in Caffe

Any ideas on how to implement spatial reflection in kef like a torch?

  (x): nn.SpatialReflectionPadding(l=1, r=1, t=1, b=1)
  (x): nn.SpatialConvolution(64 -> 64, 3x3)
  (x): nn.ReLU

      

+3


source to share


1 answer


One way to do this is using the Python Layer for Caffe. Then you can customize the features yourself and customize them based on your needs. However, this layer can only run on the CPU, so it can slow down your model, especially if you are using it in the middle of a network.

Later I defined the pad's zero input layer using the Python level, which you can change to suit your needs:

import caffe
import numpy as np

class SpatialReflectionPadding(caffe.Layer):

def setup(self,bottom,top):
    if len(bottom) != 1: # check that a single bottom blob is given
        raise Exception("Expected a single blob")       
    if len(bottom[0].shape) != 4: # check that it is 4D
        raise Exception("Expected 4D blob")
    params = eval(self.param_str) # get the params given in the prototxt
    self.l = params["l"]
    self.r = params["r"]
    self.t = params["t"]
    self.b = params["b"]

def reshape(self,bottom,top):
    top[0].reshape(bottom[0].shape[0],bottom[0].shape[1],bottom[0].shape[2]+self.t+self.b,bottom[0].shape[3]+self.r+self.l) # set the shape of the top blob based on the shape of the existing bottom blob

def forward(self,bottom,top):
    for i in range(0,top[0].shape[2]):
        for j in range(0,top[0].shape[3]):
            if (i < self.t or i >= self.t+bottom[0].shape[2]) or (j < self.l or j >= self.l+bottom[0].shape[3]):
                top[0].data[:,:,i,j] = 0 # for the padded part, set the value to 0
            else:
                top[0].data[:,:,i,j] = bottom[0].data[:,:,i-self.t,j-self.l] # for the rest, copy the value from the bottom blob

def backward(self,top,propagate_down,bottom):
    bottom[0].diff[...] = np.full(bottom[0].shape,1) * top[0].diff[:,:,self.t:self.t+bottom[0].shape[2],self.l:self.l+bottom[0].shape[3]] # set the gradient for backward pass

      



Then in your prototxt file you can use it like:

layer {
    name: "srp" # some name
    type: "Python"
    bottom: "some_layer" # the layer which provides the input blob
    top: "srp"
    python_param {
        module: "caffe_srp" # whatever is your module name
        layer: "SpatialReflectionPadding"
        param_str: '{ "l": 1, "b": 1, "t": 1, "r": 1}'
    }
}

      

I'm not 100% sure if it works correctly, although when I used it it seems to have done it. In any case, he should give an idea and a starting point on how to proceed. Alternatively, you can refer to this question and its answers .

+2


source







All Articles