最近实验当中借鉴了FPN网络,由于FPN网络对图片shape有要求,采用了两种方式,其一是在data_layer.cpp中,对原图进行padding操作;其二是需要对特征图进行类似crop操作,使得两者进行eltwise操作的时候shape是一致的。

简单说一下添加padding的操作,在data_layer.cpp的DataSetup()和load_batch()函数中添加:

1 //cv_img是读入的原图像,ext_img是填充pad的图像2 //extRows,extCols是填充的行和列,具体可查opencv中的copyMakeBorder用法3 copyMakeBorder(cv_img,ext_img,0,extRows,0,extCols,BORDER_CONSTANT);

下面介绍第二种Interp插值操作:

第一步:添加相应的代码,主要代码来源于:https://github.com/hszhao/PSPNet

1.在PSPNet/include/cafffe/layers/interp_layer.hpp添加代码,代码如下:

1 #ifndef CAFFE_INTERP_LAYER_HPP_
2 #define CAFFE_INTERP_LAYER_HPP_
3
4 #include <vector>
5
6 #include "caffe/blob.hpp"
7 #include "caffe/layer.hpp"
8 #include "caffe/proto/caffe.pb.h"
9
10 namespace caffe {11 /**
12  * @brief Changes the spatial resolution by bi-linear interpolation.13  *        The target size is specified interms of pixels.14  *        The start andend pixels of the input are mapped to the start15  *        andend pixels of the output.16  */
17 template <typename Dtype>
18 class InterpLayer : public Layer<Dtype>{19 public:20   explicit InterpLayer(const LayerParameter&param)21       : Layer<Dtype>(param) {}22   virtual void LayerSetUp(const vector<Blob<Dtype>*>&bottom,23       const vector<Blob<Dtype>*>&top);24   virtual void Reshape(const vector<Blob<Dtype>*>&bottom,25       const vector<Blob<Dtype>*>&top);26
27   virtual inline const char* type() const { return "Interp"; }28   virtual inline int ExactNumBottomBlobs() const { return 1; }     //此处可以根据需求修改Interp层的输入个数,默认是1;下同29   virtual inline int ExactNumTopBlobs() const { return 1; }30
31 protected:32   virtual void Forward_cpu(const vector<Blob<Dtype>*>&bottom,33       const vector<Blob<Dtype>*>&top);34   virtual void Forward_gpu(const vector<Blob<Dtype>*>&bottom,35       const vector<Blob<Dtype>*>&top);36   virtual void Backward_cpu(const vector<Blob<Dtype>*>&top,37       const vector<bool>& propagate_down, const vector<Blob<Dtype>*>&bottom);38   virtual void Backward_gpu(const vector<Blob<Dtype>*>&top,39       const vector<bool>& propagate_down, const vector<Blob<Dtype>*>&bottom);40
41 int num_, channels_;42 int height_in_, width_in_;43 int height_out_, width_out_;44 int pad_beg_, pad_end_;45 int height_in_eff_, width_in_eff_;46 };47
48 }  //namespace caffe49
50 #endif // CAFFE_CONV_LAYER_HPP_

2.在PSPNet/include/caffe/util/interp.hpp中添加代码,代码如下:

1 #ifndef CAFFE_UTIL_INTERP_H_
2 #define CAFFE_UTIL_INTERP_H_
3
4 #include <cublas_v2.h>
5 #include "caffe/proto/caffe.pb.h"
6
7 namespace caffe {8
9 // Bi-linear interpolation10 // IN : [channels height1 width1] cropped froma bigger [Height1 Width1] image11 // OUT: [channels height2 width2] cropped froma bigger [Height2 Width2] image12
13 template <typename Dtype, bool packed>
14 void caffe_cpu_interp2(const int channels,15     const Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,16           Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2);17
18 template <typename Dtype, bool packed>
19 void caffe_gpu_interp2(const int channels,20     const Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,21           Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2);22
23 //Backward (adjoint) operation24 template <typename Dtype, bool packed>
25 void caffe_cpu_interp2_backward(const int channels,26       Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,27     const Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2);28
29 template <typename Dtype, bool packed>
30 void caffe_gpu_interp2_backward(const int channels,31       Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,32     const Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2);33
34 // Create Gaussian pyramid of an image. Assume output space is pre-allocated.35 //IN : [channels height width]36 template <typename Dtype, bool packed>
37 void caffe_cpu_pyramid2(const int channels,38     const Dtype *data, const int height, const int width,39     Dtype *data_pyr, const int levels);40
41 template <typename Dtype, bool packed>
42 void caffe_gpu_pyramid2(const int channels,43     const Dtype *data, const int height, const int width,44     Dtype *data_pyr, const int levels);45
46   /*
47 template <typename Dtype, bool packed>
48 void caffe_cpu_mosaic(const int channels,49     const Dtype *data1, const MosaicParameter mosaic_params1,50     const Dtype *data_pyr, const int levels,51           Dtype *data2, const MosaicParameter mosaic_params2);52 template <typename Dtype, bool packed>
53 void caffe_gpu_mosaic(const int channels,54     const Dtype *data1, const MosaicParameter mosaic_params1,55     const Dtype *data_pyr, const int levels,56           Dtype *data2, const MosaicParameter mosaic_params2);57   */
58
59 }  //namespace caffe60
61 #endif

3.在PSPNet/include/caffe/common.cuh 添加代码,代码如下:

1 #ifndef CAFFE_COMMON_CUH_
2 #define CAFFE_COMMON_CUH_
3
4 #include <cuda.h>
5
6 #if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600   //注意标红需要添加,不然会报错(根据自己服务器CUDA配置需求添加)
7
8 #else
9 // CUDA: atomicAdd is not defined fordoubles10 static __inline__ __device__ double atomicAdd(double *address, double val) {11   unsigned long long int* address_as_ull = (unsigned long long int*)address;12   unsigned long long int old = *address_as_ull, assumed;13   if (val==0.0)14     return __longlong_as_double(old);15 do {16     assumed =old;17     old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed)));18   } while (assumed !=old);19   return __longlong_as_double(old);20 }21
22 #endif
23 #endif

4.在PSPNet/src/caffe/layers/interp_layer.cpp 下添加代码,代码如下:

1 #include <vector>
2
3 #include "caffe/layer.hpp"
4 #include "caffe/util/math_functions.hpp"
5 #include "caffe/util/interp.hpp"
6 #include "caffe/layers/interp_layer.hpp"
7
8 namespace caffe {9
10 template <typename Dtype>
11 void InterpLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>&bottom,12       const vector<Blob<Dtype>*>&top) {13   InterpParameter interp_param = this->layer_param_.interp_param();14   pad_beg_ =interp_param.pad_beg();15   pad_end_ =interp_param.pad_end();16   CHECK_LE(pad_beg_, 0) << "Only supports non-pos padding (cropping) for now";17   CHECK_LE(pad_end_, 0) << "Only supports non-pos padding (cropping) for now";18 }19
20 template <typename Dtype>
21 void InterpLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>&bottom,22       const vector<Blob<Dtype>*>&top) {23   num_ = bottom[0]->num();24   channels_ = bottom[0]->channels();25   height_in_ = bottom[0]->height();26   width_in_ = bottom[0]->width();27   height_in_eff_ = height_in_ + pad_beg_ +pad_end_;28   width_in_eff_ = width_in_ + pad_beg_ +pad_end_;29   InterpParameter interp_param = this->layer_param_.interp_param();30   if (interp_param.has_shrink_factor() &&
31 !interp_param.has_zoom_factor()) {32     const int shrink_factor =interp_param.shrink_factor();33     CHECK_GE(shrink_factor, 1) << "Shrink factor must be positive";34     height_out_ = (height_in_eff_ - 1) / shrink_factor + 1;35     width_out_ = (width_in_eff_ - 1) / shrink_factor + 1;36   } else if (interp_param.has_zoom_factor() &&
37 !interp_param.has_shrink_factor()) {38     const int zoom_factor =interp_param.zoom_factor();39     CHECK_GE(zoom_factor, 1) << "Zoom factor must be positive";40     height_out_ = height_in_eff_ + (height_in_eff_ - 1) * (zoom_factor - 1);41     width_out_ = width_in_eff_ + (width_in_eff_ - 1) * (zoom_factor - 1);42   } else if (interp_param.has_height() &&interp_param.has_width()) {43     height_out_  =interp_param.height();44     width_out_  =interp_param.width();45   } else if (interp_param.has_shrink_factor() &&
46 interp_param.has_zoom_factor()) {47     const int shrink_factor =interp_param.shrink_factor();48     const int zoom_factor =interp_param.zoom_factor();49     CHECK_GE(shrink_factor, 1) << "Shrink factor must be positive";50     CHECK_GE(zoom_factor, 1) << "Zoom factor must be positive";51     height_out_ = (height_in_eff_ - 1) / shrink_factor + 1;52     width_out_ = (width_in_eff_ - 1) / shrink_factor + 1;53     height_out_ = height_out_ + (height_out_ - 1) * (zoom_factor - 1);54     width_out_ = width_out_ + (width_out_ - 1) * (zoom_factor - 1);55   } else{56 LOG(FATAL);57 }58   CHECK_GT(height_in_eff_, 0) << "height should be positive";59   CHECK_GT(width_in_eff_, 0) << "width should be positive";60   CHECK_GT(height_out_, 0) << "height should be positive";61   CHECK_GT(width_out_, 0) << "width should be positive";62   top[0]->Reshape(num_, channels_, height_out_, width_out_);63 }64
65 template <typename Dtype>
66 void InterpLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>&bottom,67       const vector<Blob<Dtype>*>&top) {68   caffe_cpu_interp2<Dtype,false>(num_ *channels_,69     bottom[0]->cpu_data(), - pad_beg_, -pad_beg_, height_in_eff_, width_in_eff_, height_in_, width_in_,70     top[0]->mutable_cpu_data(), 0, 0, height_out_, width_out_, height_out_, width_out_);71 }72
73 template <typename Dtype>
74 void InterpLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>&top,75       const vector<bool>& propagate_down, const vector<Blob<Dtype>*>&bottom) {76   if (!propagate_down[0]) { return; }77   caffe_set(bottom[0]->count(), Dtype(0), bottom[0]->mutable_cpu_diff());78   caffe_cpu_interp2_backward<Dtype,false>(num_ *channels_,79     bottom[0]->mutable_cpu_diff(), - pad_beg_, -pad_beg_, height_in_eff_, width_in_eff_, height_in_, width_in_,80     top[0]->cpu_diff(), 0, 0, height_out_, width_out_, height_out_, width_out_);81 }82
83 #ifndef CPU_ONLY
84 template <typename Dtype>
85 void InterpLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>&bottom,86       const vector<Blob<Dtype>*>&top) {87   caffe_gpu_interp2<Dtype,false>(num_ *channels_,88     bottom[0]->gpu_data(), - pad_beg_, -pad_beg_, height_in_eff_, width_in_eff_, height_in_, width_in_,89     top[0]->mutable_gpu_data(), 0, 0, height_out_, width_out_, height_out_, width_out_);90 }91
92 template <typename Dtype>
93 void InterpLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>&top,94       const vector<bool>& propagate_down, const vector<Blob<Dtype>*>&bottom) {95   if (!propagate_down[0]) { return; }96   caffe_gpu_set(bottom[0]->count(), Dtype(0), bottom[0]->mutable_gpu_diff());97   caffe_gpu_interp2_backward<Dtype,false>(num_ *channels_,98     bottom[0]->mutable_gpu_diff(), - pad_beg_, -pad_beg_, height_in_eff_, width_in_eff_, height_in_, width_in_,99     top[0]->gpu_diff(), 0, 0, height_out_, width_out_, height_out_, width_out_);100 }101 #endif
102
103 #ifdef CPU_ONLY
104 STUB_GPU(InterpLayer);105 #endif
106
107 INSTANTIATE_CLASS(InterpLayer);108 REGISTER_LAYER_CLASS(Interp);109
110 } // namespace caffe

4.在PSPNet/src/caffe/util/interp.cpp中添加代码,代码如下:

1 #include "caffe/common.hpp"
2 #include "caffe/util/interp.hpp"
3 #include <algorithm>
4 #include <cmath>
5
6 namespace caffe {7
8 // Bi-linear interpolation9 // IN : [channels height1 width1] cropped froma bigger [Height1 Width1] image10 // OUT: [channels height2 width2] cropped froma bigger [Height2 Width2] image11 template <typename Dtype, bool packed>
12 void caffe_cpu_interp2(const int channels,13     const Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,14     Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2) {15   CHECK(x1 >= 0 && y1 >= 0 && height1 > 0 && width1 > 0 && x2 >= 0 && y2 >= 0 && height2 > 0 && width2 >0);16   CHECK(Width1 >= width1 + x1 && Height1 >= height1 + y1 && Width2 >= width2 + x2 && Height2 >= height2 +y2);17   //special case: just copy18   if (height1 == height2 && width1 ==width2) {19     for (int h2 = 0; h2 < height2; ++h2) {20       const int h1 =h2;21       for (int w2 = 0; w2 < width2; ++w2) {22     const int w1 =w2;23     if(packed) {24       const Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];25       Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];26       for (int c = 0; c < channels; ++c) {27         pos2[0] =pos1[0];28         pos1++;29         pos2++;30 }31 }32     else{33       const Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];34       Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];35       for (int c = 0; c < channels; ++c) {36         pos2[0] =pos1[0];37         pos1 += Width1 *Height1;38         pos2 += Width2 *Height2;39 }40 }41 }42 }43     return;44 }45   const float rheight = (height2 > 1) ? static_cast<float>(height1 - 1) / (height2 - 1) : 0.f;46   const float rwidth = (width2 > 1) ? static_cast<float>(width1 - 1) / (width2 - 1) : 0.f;47   for (int h2 = 0; h2 < height2; ++h2) {48     const float h1r = rheight *h2;49     const int h1 =h1r;50     const int h1p = (h1 < height1 - 1) ? 1: 0;51     const Dtype h1lambda = h1r -h1;52     const Dtype h0lambda = Dtype(1.) -h1lambda;53     for (int w2 = 0; w2 < width2; ++w2) {54       const float w1r = rwidth *w2;55       const int w1 =w1r;56       const int w1p = (w1 < width1 - 1) ? 1: 0;57       const Dtype w1lambda = w1r -w1;58       const Dtype w0lambda = Dtype(1.) -w1lambda;59       if(packed) {60     const Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];61     Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];62     for (int c = 0; c < channels; ++c) {63       pos2[0] =
64         h0lambda * (w0lambda * pos1[0]            + w1lambda * pos1[channels * w1p]) +
65         h1lambda * (w0lambda * pos1[channels * h1p * Width1] + w1lambda * pos1[channels * (h1p * Width1 +w1p)]);66       pos1++;67       pos2++;68 }69 }70       else{71     const Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];72     Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];73     for (int c = 0; c < channels; ++c) {74       pos2[0] =
75         h0lambda * (w0lambda * pos1[0]            + w1lambda * pos1[w1p]) +
76         h1lambda * (w0lambda * pos1[h1p * Width1] + w1lambda * pos1[h1p * Width1 +w1p]);77       pos1 += Width1 *Height1;78       pos2 += Width2 *Height2;79 }80 }81 }82 }83 }84
85
86 // Backward (adjoint) operation 1 <- 2(accumulates)87 template <typename Dtype, bool packed>
88 void caffe_cpu_interp2_backward(const int channels,89     Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,90     const Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2) {91   CHECK(x1 >= 0 && y1 >= 0 && height1 > 0 && width1 > 0 && x2 >= 0 && y2 >= 0 && height2 > 0 && width2 >0);92   CHECK(Width1 >= width1 + x1 && Height1 >= height1 + y1 && Width2 >= width2 + x2 && Height2 >= height2 +y2);93   // special case: same-size matching grids94   if (height1 == height2 && width1 ==width2) {95     for (int h2 = 0; h2 < height2; ++h2) {96       const int h1 =h2;97       for (int w2 = 0; w2 < width2; ++w2) {98     const int w1 =w2;99     if(packed) {100       Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];101       const Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];102       for (int c = 0; c < channels; ++c) {103         pos1[0] +=pos2[0];104         pos1++;105         pos2++;106 }107 }108     else{109       Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];110       const Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];111       for (int c = 0; c < channels; ++c) {112         pos1[0] +=pos2[0];113         pos1 += Width1 *Height1;114         pos2 += Width2 *Height2;115 }116 }117 }118 }119     return;120 }121   const float rheight = (height2 > 1) ? static_cast<float>(height1 - 1) / (height2 - 1) : 0.f;122   const float rwidth = (width2 > 1) ? static_cast<float>(width1 - 1) / (width2 - 1) : 0.f;123   for (int h2 = 0; h2 < height2; ++h2) {124     const float h1r = rheight *h2;125     const int h1 =h1r;126     const int h1p = (h1 < height1 - 1) ? 1: 0;127     const Dtype h1lambda = h1r -h1;128     const Dtype h0lambda = Dtype(1.) -h1lambda;129     for (int w2 = 0; w2 < width2; ++w2) {130       const float w1r = rwidth *w2;131       const int w1 =w1r;132       const int w1p = (w1 < width1 - 1) ? 1: 0;133       const Dtype w1lambda = w1r -w1;134       const Dtype w0lambda = Dtype(1.) -w1lambda;135       if(packed) {136     Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];137     const Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];138     for (int c = 0; c < channels; ++c) {139       pos1[0] += h0lambda * w0lambda *pos2[0];140       pos1[channels * w1p] += h0lambda * w1lambda *pos2[0];141       pos1[channels * h1p * Width1] += h1lambda * w0lambda *pos2[0];142       pos1[channels * (h1p * Width1 + w1p)] += h1lambda * w1lambda *pos2[0];143       pos1++;144       pos2++;145 }146 }147       else{148     Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];149     const Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];150     for (int c = 0; c < channels; ++c) {151       pos1[0] += h0lambda * w0lambda *pos2[0];152       pos1[w1p] += h0lambda * w1lambda *pos2[0];153       pos1[h1p * Width1] += h1lambda * w0lambda *pos2[0];154       pos1[h1p * Width1 + w1p] += h1lambda * w1lambda *pos2[0];155       pos1 += Width1 *Height1;156       pos2 += Width2 *Height2;157 }158 }159 }160 }161 }162
163 // Create Gaussian pyramid of an image. Assume output space is pre-allocated.164 //IN : [channels height width]165 template <typename Dtype, bool packed>
166 void caffe_cpu_pyramid2(const int channels,167     const Dtype *data, const int height, const int width,168     Dtype *data_pyr, const int levels) {169   CHECK(height > 0 && width > 0 && levels >=0);170   int height1 = height, width1 =width;171   int height2 = height, width2 =width;172   const Dtype *data1 =data;173   Dtype *data2 =data_pyr;174   for (int l = 0; l < levels; ++l) {175     height2 /= 2;176     width2 /= 2;177     if (height2 == 0 || width2 ==0) {178       break;179 }180     for (int h2 = 0; h2 < height2; ++h2) {181       const int h1 = 2 *h2;182       for (int w2 = 0; w2 < width2; ++w2) {183     const int w1 = 2 *w2;184     if(packed) {185       const Dtype* pos1 = &data1[channels * (h1 * width1 +w1)];186       Dtype* pos2 = &data2[channels * (h2 * width2 +w2)];187       for (int c = 0; c < channels; ++c) {188         pos2[0] =  static_cast<Dtype>(.25) *
189           (pos1[0]                 + pos1[channels] +
190            pos1[channels * width1] + pos1[channels * (width1 + 1)]);191         pos1++;192         pos2++;193 }194 }195     else{196       const Dtype* pos1 = &data1[h1 * width1 +w1];197       Dtype* pos2 = &data2[h2 * width2 +w2];198       for (int c = 0; c < channels; ++c) {199         pos2[0] =  static_cast<Dtype>(.25) *
200           (pos1[0]      + pos1[1] +
201            pos1[width1] + pos1[width1 + 1]);202         pos1 += width1 *height1;203         pos2 += width2 *height2;204 }205 }206 }207 }208     data1 =data2;209     height1 =height2;210     width1 =width2;211     data2 += channels * height2 *width2;212 }213 }214
215   /*
216 template <typename Dtype, bool packed>
217 void caffe_cpu_mosaic(const int channels,218     const Dtype *data1, const MosaicParameter mosaic_params1,219     const Dtype *data_pyr, const int levels,220           Dtype *data2, const MosaicParameter mosaic_params2) {221   const int num1 =mosaic_params1.rects_size();222   const int num2 =mosaic_params2.rects_size();223   CHECK(num1 == num2 || (num1 == 1 && num2 > 1) || (num2 == 1 && num1 > 1));224   const int num =std::max(num1, num2);225   for (int i = 0; i < num; ++i) {226     const Rect rect1 = mosaic_params1.rects((i <num1) ? i : 0);227     const Rect rect2 = mosaic_params2.rects((i <num2) ? i : 0);228     int level = log2(sqrt((float)rect1.height() * rect1.width() / rect2.height() /rect2.width()));229     level =std::max(0, std::min(levels, level));230     if (data_pyr == 0 || level ==0) {231       caffe_cpu_interp2<Dtype,packed>(channels,232 data1, rect1.x(), rect1.y(), rect1.height(), rect1.width(), mosaic_params1.height(), mosaic_params1.width(),233 data2, rect2.x(), rect2.y(), rect2.height(), rect2.width(), mosaic_params2.height(), mosaic_params2.width());234 }235     else{236       const Dtype *data_pyr_l =data_pyr;237       int factor = 2;238       for (int l = 1; l < level; ++l) {239     data_pyr_l += channels * (mosaic_params1.height() / factor) * (mosaic_params1.width() /factor);240     factor *= 2;241 }242       caffe_cpu_interp2<Dtype,packed>(channels,243       data_pyr_l, rect1.x() / factor, rect1.y() / factor, rect1.height() / factor, rect1.width() / factor, mosaic_params1.height() / factor, mosaic_params1.width() /factor,244 data2, rect2.x(), rect2.y(), rect2.height(), rect2.width(), mosaic_params2.height(), mosaic_params2.width());245 }246 }247 }248 template <typename Dtype, bool packed>
249 void caffe_gpu_mosaic(const int channels,250     const Dtype *data1, const MosaicParameter mosaic_params1,251     const Dtype *data_pyr, const int levels,252           Dtype *data2, const MosaicParameter mosaic_params2) {253   const int num1 =mosaic_params1.rects_size();254   const int num2 =mosaic_params2.rects_size();255   CHECK(num1 == num2 || (num1 == 1 && num2 > 1) || (num2 == 1 && num1 > 1));256   const int num =std::max(num1, num2);257   for (int i = 0; i < num; ++i) {258     const Rect rect1 = mosaic_params1.rects((i <num1) ? i : 0);259     const Rect rect2 = mosaic_params2.rects((i <num2) ? i : 0);260     int level = log2(sqrt((float)rect1.height() * rect1.width() / rect2.height() /rect2.width()));261     level =std::max(0, std::min(levels, level));262     if (data_pyr == 0 || level ==0) {263       caffe_gpu_interp2<Dtype,packed>(channels,264 data1, rect1.x(), rect1.y(), rect1.height(), rect1.width(), mosaic_params1.height(), mosaic_params1.width(),265 data2, rect2.x(), rect2.y(), rect2.height(), rect2.width(), mosaic_params2.height(), mosaic_params2.width());266 }267     else{268       const Dtype *data_pyr_l =data_pyr;269       int factor = 2;270       for (int l = 1; l < level; ++l) {271     data_pyr_l += channels * (mosaic_params1.height() / factor) * (mosaic_params1.width() /factor);272     factor *= 2;273 }274       caffe_gpu_interp2<Dtype,packed>(channels,275       data_pyr_l, rect1.x() / factor, rect1.y() / factor, rect1.height() / factor, rect1.width() / factor, mosaic_params1.height() / factor, mosaic_params1.width() /factor,276 data2, rect2.x(), rect2.y(), rect2.height(), rect2.width(), mosaic_params2.height(), mosaic_params2.width());277 }278 }279 }280   */
281
282 //Explicit instances283 template void caffe_cpu_interp2<float,false>(const int, const float *, const int, const int, const int, const int, const int, const int, float *, const int, const int, const int, const int, const int, const int);284 template void caffe_cpu_interp2<float,true>(const int, const float *, const int, const int, const int, const int, const int, const int, float *, const int, const int, const int, const int, const int, const int);285 template void caffe_cpu_interp2<double,false>(const int, const double *, const int, const int, const int, const int, const int, const int, double *, const int, const int, const int, const int, const int, const int);286 template void caffe_cpu_interp2<double,true>(const int, const double *, const int, const int, const int, const int, const int, const int, double *, const int, const int, const int, const int, const int, const int);287
288 template void caffe_cpu_interp2_backward<float,false>(const int, float *, const int, const int, const int, const int, const int, const int, const float *, const int, const int, const int, const int, const int, const int);289 template void caffe_cpu_interp2_backward<double,false>(const int, double *, const int, const int, const int, const int, const int, const int, const double *, const int, const int, const int, const int, const int, const int);290
291 template void caffe_cpu_pyramid2<float,false>(const int, const float *, const int, const int, float *, const int);292 template void caffe_cpu_pyramid2<float,true>(const int, const float *, const int, const int, float *, const int);293 template void caffe_cpu_pyramid2<double,false>(const int, const double *, const int, const int, double *, const int);294 template void caffe_cpu_pyramid2<double,true>(const int, const double *, const int, const int, double *, const int);295
296   /*
297 template void caffe_cpu_mosaic<float,false>(const int, const float *, const MosaicParameter, const float *, const int, float *, const MosaicParameter);298 template void caffe_cpu_mosaic<float,true>(const int, const float *, const MosaicParameter, const float *, const int, float *, const MosaicParameter);299 template void caffe_cpu_mosaic<double,false>(const int, const double *, const MosaicParameter, const double *, const int, double *, const MosaicParameter);300 template void caffe_cpu_mosaic<double,true>(const int, const double *, const MosaicParameter, const double *, const int, double *, const MosaicParameter);301 template void caffe_gpu_mosaic<float,false>(const int, const float *, const MosaicParameter, const float *, const int, float *, const MosaicParameter);302 template void caffe_gpu_mosaic<float,true>(const int, const float *, const MosaicParameter, const float *, const int, float *, const MosaicParameter);303 template void caffe_gpu_mosaic<double,false>(const int, const double *, const MosaicParameter, const double *, const int, double *, const MosaicParameter);304 template void caffe_gpu_mosaic<double,true>(const int, const double *, const MosaicParameter, const double *, const int, double *, const MosaicParameter);305   */
306
307 } // namespace caffe

5.在PSPNet/src/caffe/util/interp.cu中添加代码,代码如下:

1 #include "caffe/common.hpp"
2 #include "caffe/common.cuh"
3 #include "caffe/util/interp.hpp"
4
5 namespace caffe {6
7 // Bi-linear interpolation8 // IN : [channels height1 width1] cropped froma bigger [Height1 Width1] image9 // OUT: [channels height2 width2] cropped froma bigger [Height2 Width2] image10 template <typename Dtype, bool packed>
11 __global__void caffe_gpu_interp2_kernel(const int n, const float rheight, const float rwidth,12 const int channels,13     const Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,14     Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2) {15   int index = threadIdx.x + blockIdx.x *blockDim.x;16   if (index <n) {17     const int w2 = index % width2; // 0:width2-1
18     const int h2 = index / width2; // 0:height2-1
19     //special case: just copy20     if (height1 == height2 && width1 ==width2) {21       const int h1 =h2;22       const int w1 =w2;23       if(packed) {24     const Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];25     Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];26     for (int c = 0; c < channels; ++c) {27       pos2[0] =pos1[0];28       pos1++;29       pos2++;30 }31 }32       else{33     const Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];34     Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];35     for (int c = 0; c < channels; ++c) {36     pos2[0] =pos1[0];37     pos1 += Width1 *Height1;38     pos2 += Width2 *Height2;39 }40 }41       return;42 }43     //
44     const float h1r = rheight *h2;45     const int h1 =h1r;46     const int h1p = (h1 < height1 - 1) ? 1: 0;47     const Dtype h1lambda = h1r -h1;48     const Dtype h0lambda = Dtype(1.) -h1lambda;49     //
50     const float w1r = rwidth *w2;51     const int w1 =w1r;52     const int w1p = (w1 < width1 - 1) ? 1: 0;53     const Dtype w1lambda = w1r -w1;54     const Dtype w0lambda = Dtype(1.) -w1lambda;55     //
56     if(packed) {57       const Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];58       Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];59       for (int c = 0; c < channels; ++c) {60     pos2[0] =
61       h0lambda * (w0lambda * pos1[0]            + w1lambda * pos1[channels * w1p]) +
62       h1lambda * (w0lambda * pos1[channels * h1p * Width1] + w1lambda * pos1[channels * (h1p * Width1 +w1p)]);63     pos1++;64     pos2++;65 }66 }67     else{68       const Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];69       Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];70       for (int c = 0; c < channels; ++c) {71     pos2[0] =
72       h0lambda * (w0lambda * pos1[0]            + w1lambda * pos1[w1p]) +
73       h1lambda * (w0lambda * pos1[h1p * Width1] + w1lambda * pos1[h1p * Width1 +w1p]);74     pos1 += Width1 *Height1;75     pos2 += Width2 *Height2;76 }77 }78 }79 }80
81 template <typename Dtype, bool packed>
82 void caffe_gpu_interp2(const int channels,83     const Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,84     Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2) {85   CHECK(x1 >= 0 && y1 >= 0 && height1 > 0 && width1 > 0 && x2 >= 0 && y2 >= 0 && height2 > 0 && width2 >0);86   CHECK(Width1 >= width1 + x1 && Height1 >= height1 + y1 && Width2 >= width2 + x2 && Height2 >= height2 +y2);87   const float rheight = (height2 > 1) ? static_cast<float>(height1 - 1) / (height2 - 1) : 0.f;88   const float rwidth = (width2 > 1) ? static_cast<float>(width1 - 1) / (width2 - 1) : 0.f;89   const int num_kernels = height2 *width2;90   caffe_gpu_interp2_kernel<Dtype,packed><<<CAFFE_GET_BLOCKS(num_kernels), CAFFE_CUDA_NUM_THREADS>>>
91 (num_kernels, rheight, rwidth, channels,92 data1, x1, y1, height1, width1, Height1, Width1,93 data2, x2, y2, height2, width2, Height2, Width2);94 CUDA_POST_KERNEL_CHECK;95 }96
97 // Backward (adjoint) operation 1 <- 2(accumulates)98 template <typename Dtype, bool packed>
99 __global__void caffe_gpu_interp2_kernel_backward(const int n, const float rheight, const float rwidth,100 const int channels,101     Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,102     const Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2) {103   int index = threadIdx.x + blockIdx.x *blockDim.x;104   if (index <n) {105     const int w2 = index % width2; // 0:width2-1
106     const int h2 = index / width2; // 0:height2-1
107     //special case: just copy108     if (height1 == height2 && width1 ==width2) {109       const int h1 =h2;110       const int w1 =w2;111       if(packed) {112     Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];113     const Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];114     for (int c = 0; c < channels; ++c) {115       pos1[0] +=pos2[0];116       pos1++;117       pos2++;118 }119 }120       else{121     Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];122     const Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];123     for (int c = 0; c < channels; ++c) {124       pos1[0] +=pos2[0];125       pos1 += Width1 *Height1;126       pos2 += Width2 *Height2;127 }128 }129       return;130 }131     //
132     const float h1r = rheight *h2;133     const int h1 =h1r;134     const int h1p = (h1 < height1 - 1) ? 1: 0;135     const Dtype h1lambda = h1r -h1;136     const Dtype h0lambda = Dtype(1.) -h1lambda;137     //
138     const float w1r = rwidth *w2;139     const int w1 =w1r;140     const int w1p = (w1 < width1 - 1) ? 1: 0;141     const Dtype w1lambda = w1r -w1;142     const Dtype w0lambda = Dtype(1.) -w1lambda;143     //
144     if(packed) {145       Dtype* pos1 = &data1[channels * ((y1 + h1) * Width1 + (x1 +w1))];146       const Dtype* pos2 = &data2[channels * ((y2 + h2) * Width2 + (x2 +w2))];147       for (int c = 0; c < channels; ++c) {148     atomicAdd(&pos1[0], h0lambda * w0lambda *pos2[0]);149     atomicAdd(&pos1[channels * w1p], h0lambda * w1lambda *pos2[0]);150     atomicAdd(&pos1[channels * h1p * Width1], h1lambda * w0lambda *pos2[0]);151     atomicAdd(&pos1[channels * (h1p * Width1 + w1p)], h1lambda * w1lambda *pos2[0]);152     pos1++;153     pos2++;154 }155 }156     else{157       Dtype* pos1 = &data1[(y1 + h1) * Width1 + (x1 +w1)];158       const Dtype* pos2 = &data2[(y2 + h2) * Width2 + (x2 +w2)];159       for (int c = 0; c < channels; ++c) {160     atomicAdd(&pos1[0], h0lambda * w0lambda *pos2[0]);161     atomicAdd(&pos1[w1p], h0lambda * w1lambda *pos2[0]);162     atomicAdd(&pos1[h1p * Width1], h1lambda * w0lambda *pos2[0]);163     atomicAdd(&pos1[h1p * Width1 + w1p], h1lambda * w1lambda *pos2[0]);164     pos1 += Width1 *Height1;165     pos2 += Width2 *Height2;166 }167 }168 }169 }170
171 template <typename Dtype, bool packed>
172 void caffe_gpu_interp2_backward(const int channels,173     Dtype *data1, const int x1, const int y1, const int height1, const int width1, const int Height1, const int Width1,174     const Dtype *data2, const int x2, const int y2, const int height2, const int width2, const int Height2, const int Width2) {175   CHECK(x1 >= 0 && y1 >= 0 && height1 > 0 && width1 > 0 && x2 >= 0 && y2 >= 0 && height2 > 0 && width2 >0);176   CHECK(Width1 >= width1 + x1 && Height1 >= height1 + y1 && Width2 >= width2 + x2 && Height2 >= height2 +y2);177   const float rheight = (height2 > 1) ? static_cast<float>(height1 - 1) / (height2 - 1) : 0.f;178   const float rwidth = (width2 > 1) ? static_cast<float>(width1 - 1) / (width2 - 1) : 0.f;179   const int num_kernels = height2 *width2;180   caffe_gpu_interp2_kernel_backward<Dtype,packed><<<CAFFE_GET_BLOCKS(num_kernels), CAFFE_CUDA_NUM_THREADS>>>
181 (num_kernels, rheight, rwidth, channels,182 data1, x1, y1, height1, width1, Height1, Width1,183 data2, x2, y2, height2, width2, Height2, Width2);184 CUDA_POST_KERNEL_CHECK;185 }186
187
188 // Create Gaussian pyramid of an image. Assume output space is pre-allocated.189 //IN : [channels height width]190 template <typename Dtype, bool packed>
191 __global__void caffe_gpu_pyramid2_kernel(const int n, const int channels,192     const Dtype *data1, const int height1, const int width1,193     Dtype *data2, const int height2, const int width2) {194   int index = threadIdx.x + blockIdx.x *blockDim.x;195   if (index <n) {196     const int w2 = index % width2; // 0:width2-1
197     const int h2 = index / width2; // 0:height2-1
198     const int w1 = 2 *w2;199     const int h1 = 2 *h2;200     if(packed) {201       const Dtype* pos1 = &data1[channels * (h1 * width1 +w1)];202       Dtype* pos2 = &data2[channels * (h2 * width2 +w2)];203       for (int c = 0; c < channels; ++c) {204     pos2[0] =  static_cast<Dtype>(.25) *
205       (pos1[0]                 + pos1[channels] +
206        pos1[channels * width1] + pos1[channels * (width1 + 1)]);207     pos1++;208     pos2++;209 }210 }211     else{212       const Dtype* pos1 = &data1[h1 * width1 +w1];213       Dtype* pos2 = &data2[h2 * width2 +w2];214       for (int c = 0; c < channels; ++c) {215     pos2[0] =  static_cast<Dtype>(.25) *
216       (pos1[0]      + pos1[1] +
217        pos1[width1] + pos1[width1 + 1]);218     pos1 += width1 *height1;219     pos2 += width2 *height2;220 }221 }222 }223 }224
225 template <typename Dtype, bool packed>
226 void caffe_gpu_pyramid2(const int channels,227     const Dtype *data, const int height, const int width,228     Dtype *data_pyr, const int levels) {229   CHECK(height > 0 && width > 0 && levels >=0);230   int height1 = height, width1 =width;231   int height2 = height, width2 =width;232   const Dtype *data1 =data;233   Dtype *data2 =data_pyr;234   for (int l = 0; l < levels; ++l) {235     height2 /= 2;236     width2 /= 2;237     if (height2 == 0 || width2 ==0) {238       break;239 }240     const int num_kernels = height2 *width2;241     caffe_gpu_pyramid2_kernel<Dtype,packed><<<CAFFE_GET_BLOCKS(num_kernels), CAFFE_CUDA_NUM_THREADS>>>
242 (num_kernels, channels, data1, height1, width1, data2, height2, width2);243 CUDA_POST_KERNEL_CHECK;244     data1 =data2;245     height1 =height2;246     width1 =width2;247     data2 += channels * height2 *width2;248 }249 }250
251
252 //Explicit instances253 template void caffe_gpu_interp2<float,false>(const int, const float *, const int, const int, const int, const int, const int, const int, float *, const int, const int, const int, const int, const int, const int);254 template void caffe_gpu_interp2<float,true>(const int, const float *, const int, const int, const int, const int, const int, const int, float *, const int, const int, const int, const int, const int, const int);255 template void caffe_gpu_interp2<double,false>(const int, const double *, const int, const int, const int, const int, const int, const int, double *, const int, const int, const int, const int, const int, const int);256 template void caffe_gpu_interp2<double,true>(const int, const double *, const int, const int, const int, const int, const int, const int, double *, const int, const int, const int, const int, const int, const int);257
258 template void caffe_gpu_interp2_backward<float,false>(const int, float *, const int, const int, const int, const int, const int, const int, const float *, const int, const int, const int, const int, const int, const int);259 template void caffe_gpu_interp2_backward<double,false>(const int, double *, const int, const int, const int, const int, const int, const int, const double *, const int, const int, const int, const int, const int, const int);260
261 template void caffe_gpu_pyramid2<float,false>(const int, const float *, const int, const int, float *, const int);262 template void caffe_gpu_pyramid2<float,true>(const int, const float *, const int, const int, float *, const int);263 template void caffe_gpu_pyramid2<double,false>(const int, const double *, const int, const int, double *, const int);264 template void caffe_gpu_pyramid2<double,true>(const int, const double *, const int, const int, double *, const int);265
266 } // namespace caffe

6.在PSPNet/src/caffe/proto/caffe.proto中添加代码,代码如下:

1 message LayerParameter {2   optional string name = 1; //the layer name3   optional string type = 2; //the layer type4   repeated string bottom = 3; //the name of each bottom blob5   repeated string top = 4; //the name of each top blob6
7   // The train / test phase forcomputation.8   optional Phase phase = 10;9
10   // The amount of weight to assign each top blob inthe objective.11   // Each layer assigns a default value, usually of either 0 or 1,12   //to each top blob.13   repeated float loss_weight = 5;14
15   // Specifies training parameters (multipliers on globallearning constants,16   // and the name and other settings used forweight sharing).17   repeated ParamSpec param = 6;18
19   //The blobs containing the numeric parameters of the layer.20   repeated BlobProto blobs = 7;21
22   //Specifies on which bottoms the backpropagation should be skipped.23   // The size must be either 0 orequal to the number of bottoms.24   repeated bool propagate_down = 11;25
26   // Rules controlling whether and when a layer is included inthe network,27   // based on the current NetState.  You may specify a non-zero number of rules28   // to include OR exclude, but not both.  If no include orexclude rules are29   // specified, the layer isalways included.  If the current NetState meets30   // ANY (i.e., one or more) of the specified rules, the layer is
31   // included/excluded.32   repeated NetStateRule include = 8;33   repeated NetStateRule exclude = 9;34
35   // Parameters for data pre-processing.36   optional TransformationParameter transform_param = 100;37
38   //Parameters shared by loss layers.39   optional LossParameter loss_param = 101;40
41   // Layer type-specific parameters.42   //
43   //Note: certain layers may have more than one computational engine44   // for their implementation. These layers include an Engine type and
45   // engine parameter forselecting the implementation.46   // The default for the engine is set by the ENGINE switch at compile-time.47   optional AccuracyParameter accuracy_param = 102;48   optional AdaptiveBiasChannelParameter adaptive_bias_channel_param = 148;49   optional ArgMaxParameter argmax_param = 103;50   optional BatchNormParameter batch_norm_param = 139;51   optional BNParameter bn_param = 152;52   optional BiasParameter bias_param = 141;53   optional BiasChannelParameter bias_channel_param = 149;54   optional ConcatParameter concat_param = 104;55   optional ContrastiveLossParameter contrastive_loss_param = 105;56   optional ConvolutionParameter convolution_param = 106;57   optional DataParameter data_param = 107;58   optional DenseCRFParameter dense_crf_param = 146;59   optional DomainTransformParameter domain_transform_param = 147;60   optional DropoutParameter dropout_param = 108;61   optional DummyDataParameter dummy_data_param = 109;62   optional EltwiseParameter eltwise_param = 110;63   optional ELUParameter elu_param = 140;64   optional EmbedParameter embed_param = 137;65   optional ExpParameter exp_param = 111;66   optional FlattenParameter flatten_param = 135;67   optional HDF5DataParameter hdf5_data_param = 112;68   optional HDF5OutputParameter hdf5_output_param = 113;69   optional HingeLossParameter hinge_loss_param = 114;70   optional ImageDataParameter image_data_param = 115;71   optional InfogainLossParameter infogain_loss_param = 116;72   optional InnerProductParameter inner_product_param = 117;73   optional InterpParameter interp_param = 143;   //注意143不能和其他的数字重复,可以自己情况调整
74   optional LogParameter log_param = 134;75   optional LRNParameter lrn_param = 118;76   optional MatReadParameter mat_read_param = 151;77   optional MatWriteParameter mat_write_param = 145;78   optional MemoryDataParameter memory_data_param = 119;79   optional MVNParameter mvn_param = 120;80   optional PoolingParameter pooling_param = 121;81   optional PowerParameter power_param = 122;82   optional PReLUParameter prelu_param = 131;83   optional PythonParameter python_param = 130;84   optional ReductionParameter reduction_param = 136;85   optional ReLUParameter relu_param = 123;86   optional ReshapeParameter reshape_param = 133;87   optional ScaleParameter scale_param = 142;88   optional SegAccuracyParameter seg_accuracy_param = 144;89   optional SigmoidParameter sigmoid_param = 124;90   optional SoftmaxParameter softmax_param = 125;91   optional SPPParameter spp_param = 132;92   optional SliceParameter slice_param = 126;93   optional TanHParameter tanh_param = 127;94   optional ThresholdParameter threshold_param = 128;95   optional TileParameter tile_param = 138;96   optional UniqueLabelParameter unique_label_param = 150;97   optional WindowDataParameter window_data_param = 129;98 }

1 message InterpParameter {2   optional int32 height = 1 [default = 0]; //Height of output3   optional int32 width = 2 [default = 0]; //Width of output4   optional int32 zoom_factor = 3 [default = 1]; //zoom factor5   optional int32 shrink_factor = 4 [default = 1]; //shrink factor6   optional int32 pad_beg = 5 [default = 0]; //padding at begin of input7   optional int32 pad_end = 6 [default = 0]; //padding at end of input8 }

7.在网络结构中添加Interp层,代码如下:

1 layer{2   bottom:"input"
3   top:"output"
4   name:"interp_layer"
5   type:"Interp"
6 interp_param{        //注意可按需求改为interp_param{height:60 width:60}(即固定特征图的尺寸),也可以不需要这个interp_param参数7      shrink_factor:4
8      zoom_factor:3
9 pad_beg:010 pad_end:011 }12 }

第二步,添加完相应的代码,则进行编译

1.因为修改过caffe.proto,所以需要重新编译proto,需要先安装protobuf,安装之后需要编译caffe.proto文件,生成caffe.pb.h和caffe.pb.cc文件。编译过程如下:

1 #确定protobuf的版本
2 $ protoc --version3 libprotoc 2.5.04
5 #编译caffe.proto,需要先进入src/caffe/proto目录下,也可以不进入,指定路径
6 $ protoc -I=./ --cpp_out=./ ./caffe.proto7
8 #查看编译结果
9 $ ls10 caffe.pb.cc  caffe.pb.h  caffe.proto

2.编译caffe,退到caffe路径下,编译:

1 //确保每一步都成功执行2 make clean3 make -j84 make pycaffe

...大体上是这样一个流程,编译过程中遇到相应问题再百度,有错误的地方欢迎大家指正。

版权声明:

作者:王老头
出处:http://www.cnblogs.com/wmr95/p/8715607.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,并在文章页面明显位置给出原文链接,否则,作者将保留追究法律责任的权利。

转载于:https://www.cnblogs.com/wmr95/p/8715607.html

Caffe中Interp层的使用相关推荐

  1. caffe中各层的作用

    caffe中各层的作用: 关于caffe中的solver: cafffe中的sover的方法都有: Stochastic Gradient Descent (type: "SGD" ...

  2. Caffe中BN层与CONV层的融合(merge_bn)

    半年前写的博客,今天发现没有发出去,还好本地有md的文档,决定重新发一下 毕竟网上来回抄袭的blog太多了,代码质量也莫得保证 今天需要用pytorch融合下bn层,写个脚本稍后再传到csdn上 原理 ...

  3. caffe中各个层——解析

    转自:http://www.cnblogs.com/denny402/p/5071126.html 所有的层都具有的参数,如name, type, bottom, top和transform_para ...

  4. caffe中batchnormal层的param参数lr_mult和decay_mult都为0的原因

    如下截取一部分train.prototxt的片段: layer {   name: "conv2_em/bn"   type: "BatchNorm"   bo ...

  5. caffe中HDF5层及数据生成

    HDF 文件结构包括一个file id(文件号).至少一个 data descriptor (数据描述符).没有或多个 data element(数据内容)数据内容. file id (文件号)是一个 ...

  6. caffe中卷积层的实现

    在caffe中卷基层是通过矩阵相乘来实现的实现,直接计算卷积可以由下面的程序表示: 可以看到,这段程序循环嵌套多,时间复杂度高,而使用矩阵相乘的形式:很多现成的矩阵运算库,不重复"造轮子&q ...

  7. Caffe中Convolution层

    层类型:Convolution  lr_mult: 学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr.如果有两个lr_mult, 则第一个表示权值的学习率 ...

  8. caffe中常用层: BatchNorm层详解

    Batchnorm原理详解 前言:Batchnorm是深度网络中经常用到的加速神经网络训练,加速收敛速度及稳定性的算法,可以说是目前深度网络必不可少的一部分.  本文旨在用通俗易懂的语言,对深度学习的 ...

  9. 在caffe中添加新层 L1 Loss layer

    本文地址:http://blog.csdn.net/ismarvellous/article/details/79069661,转载请注明出处. 本文涉及的所有完整文件可在我的github下载. 1. ...

最新文章

  1. SpreadJS 类Excel表格控件 - V12 新特性详解
  2. SLF4J log4j 学习笔记一
  3. 通过数据库绑定的dropdownlist,如何让其第一条默认显示--请选择--
  4. BZOJ-1934-Vote善意的投票-SHOI2007
  5. sonar 规则之漏洞类型
  6. (转)超全面设计指南:如何做大屏数据可视化设计?
  7. 一致性hash算法虚拟节点_一致性 Hash 算法
  8. vue 获取id元素,vue.js怎么获取dom元素?
  9. 【PHP】Ajax跨域解决方案 、jsonp、cors
  10. Linux安装后无法进入图形界面(GNOME,KDE等)的解决方法
  11. LINUX下载编译SDL2
  12. linux系统数据库导出语句,数据库应用-SQL语句导入导出大全
  13. 计算机桌面壁纸在哪个文件夹,桌面背景在哪个文件夹,详细教您xp win7 win10系统桌面背景在哪个文件夹?...
  14. Mac系统搭建C语言开发环境
  15. 贝塞尔曲线运动n阶追踪方程的数学原理及其匀速化方法和应用
  16. 天正坐标标注怎么不显示_cad中坐标标注怎么显示不了xy的
  17. LeetCode 413.等差数列的划分
  18. “黑盒”下的攻击实现,真实世界的“人脸识别”遭遇危险!
  19. Typora 设置代码块的默认编程语言以及字体颜色设置
  20. jfs jfs2_在AIX 6.1上使用JFS2快照

热门文章

  1. 《Selenium自动化测试指南》—第1章1.1节自动化测试基础
  2. Ubuntu下搭建NFS,并在开发板挂载
  3. 基于Linux C的socketEthereal程序和Package分析 (一个)
  4. SpringMVC 理论与实用技术(一) 简单、实用、易懂的几个实例
  5. lipo 制作通用版本 静态库
  6. c#接口和抽象类的区别
  7. Spring.NET学习笔记(4)-对象作用域和类型转换
  8. Kazuo Inamori
  9. Spotify开源其Cassandra编排工具cstar
  10. 图解Linux系统启动流程