2017-08-01 36 views
1

我有一個要求,以3D濾鏡方式實現去卷積層的正向計算。如何在3D濾鏡方式下實現caffe中的deconv圖層?

這裏,'3D濾波方式'是指像CV中的高斯濾波器那樣的卷積。相比之下,咖啡館則以gemm + col2im的方式實施了deconv。

我找到類似的問題here。這個人根據tranposed conv的介紹寫了代碼。

Image

他/她不打開源代碼。所以,我完成了自己的一個:

template <typename DataType> int deconv_cpu(
    DataType *src, DataType *dst, DataType *para, DataType *bias, 
    int in_width, int in_height, int in_channel, 
    int out_width, int out_height, int out_channel, 
    int ks, int padding = 0, int step = 1) { // step indicates the stride 

    int col, row, ch_o, ch_i, x, y; 
    int r = (ks - 1)/2; //radius; 

    DataType result; 
    DataType *output; 
    DataType *filter; 
    DataType *input; 

    int sim_width, sim_height, sim_pad, width_border, height_border; 
    sim_width = in_width * step - step + 1; 
    sim_height = in_height * step - step + 1; 
    sim_pad = ks - padding - 1; 
    width_border = sim_pad == 0 ? r : 0; 
    height_border = sim_pad == 0 ? r : 0; 
    for (row = height_border; row < (sim_height - height_border); row++) 
    for (col = width_border; col < (sim_width - width_border); col++) 
    { 
     for (ch_o = 0; ch_o < out_channel; ch_o++) 
     { 
      output = dst + ch_o * out_width * out_height; 
      result = 0; 
      for (ch_i = 0; ch_i < in_channel; ch_i++) 
      { 
       filter = para + ks * ks * (in_channel * ch_o + ch_i); 
       //filter = para + ks*ks * (out_channel * ch_i + ch_o); 
       input = src + ch_i * in_width * in_height; 
       for (x = -r; x <= r; x++) 
       { 
        for (y = -r; y <= r; y++) 
        { 
         if ((row + x) >= 0 && (col + y) >= 0 && (row + x) < sim_height && (col + y) < sim_width) 
         { 
          if ((row + x) % step != 0 || (col + y) % step != 0) continue; 
          result += input[(row + x)/step * in_width + (col + y)/step] * filter[(x + r) * ks + (y + r)]; 
         } 
        } 
       } 
      } 

      if (bias != NULL) result = result + bias[ch_o]; 
      output[(row - height_border) * out_width + (col - width_border)] = result; 
     } 
    } 
    return 0; 
} 

我比較結果的朱古力的一個:

const caffe::vector<caffe::shared_ptr<caffe::Blob<float> > > blobs = layers[i]->blobs(); 
float *filter = blobs[0]->mutable_cpu_data(); 
float *bias = blobs[1]->mutable_cpu_data(); 

caffe::shared_ptr<caffe::Blob<float> > blob; 
blob = caffe_net->blob_by_name(np.bottom(0)); 
deconv_cpu(blob->mutable_cpu_data(), dst, filter, bias, width1, 
height1, c1, width2, height2, c2, ks, pad, stride); 

blob = caffe_net->blob_by_name(np.top(0)); 
if(compare(dst, blob->mutable_cpu_data()) == 0) printf("match\n"); 
else printf("do not match\n"); 

但是,代碼不給與朱古力的實現同樣的結果。

有誰知道什麼是錯的?或者有關代碼的建議或評論?

回答

0

此問題最終通過更改過濾器索引來修復: 過濾器[(r-x)* ks +(r-y)]