Caffe中Interp层的使用
最近实验当中借鉴了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¶m)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层的使用相关推荐
- caffe中各层的作用
caffe中各层的作用: 关于caffe中的solver: cafffe中的sover的方法都有: Stochastic Gradient Descent (type: "SGD" ...
- Caffe中BN层与CONV层的融合(merge_bn)
半年前写的博客,今天发现没有发出去,还好本地有md的文档,决定重新发一下 毕竟网上来回抄袭的blog太多了,代码质量也莫得保证 今天需要用pytorch融合下bn层,写个脚本稍后再传到csdn上 原理 ...
- caffe中各个层——解析
转自:http://www.cnblogs.com/denny402/p/5071126.html 所有的层都具有的参数,如name, type, bottom, top和transform_para ...
- caffe中batchnormal层的param参数lr_mult和decay_mult都为0的原因
如下截取一部分train.prototxt的片段: layer { name: "conv2_em/bn" type: "BatchNorm" bo ...
- caffe中HDF5层及数据生成
HDF 文件结构包括一个file id(文件号).至少一个 data descriptor (数据描述符).没有或多个 data element(数据内容)数据内容. file id (文件号)是一个 ...
- caffe中卷积层的实现
在caffe中卷基层是通过矩阵相乘来实现的实现,直接计算卷积可以由下面的程序表示: 可以看到,这段程序循环嵌套多,时间复杂度高,而使用矩阵相乘的形式:很多现成的矩阵运算库,不重复"造轮子&q ...
- Caffe中Convolution层
层类型:Convolution lr_mult: 学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr.如果有两个lr_mult, 则第一个表示权值的学习率 ...
- caffe中常用层: BatchNorm层详解
Batchnorm原理详解 前言:Batchnorm是深度网络中经常用到的加速神经网络训练,加速收敛速度及稳定性的算法,可以说是目前深度网络必不可少的一部分. 本文旨在用通俗易懂的语言,对深度学习的 ...
- 在caffe中添加新层 L1 Loss layer
本文地址:http://blog.csdn.net/ismarvellous/article/details/79069661,转载请注明出处. 本文涉及的所有完整文件可在我的github下载. 1. ...
最新文章
- SpreadJS 类Excel表格控件 - V12 新特性详解
- SLF4J log4j 学习笔记一
- 通过数据库绑定的dropdownlist,如何让其第一条默认显示--请选择--
- BZOJ-1934-Vote善意的投票-SHOI2007
- sonar 规则之漏洞类型
- (转)超全面设计指南:如何做大屏数据可视化设计?
- 一致性hash算法虚拟节点_一致性 Hash 算法
- vue 获取id元素,vue.js怎么获取dom元素?
- 【PHP】Ajax跨域解决方案 、jsonp、cors
- Linux安装后无法进入图形界面(GNOME,KDE等)的解决方法
- LINUX下载编译SDL2
- linux系统数据库导出语句,数据库应用-SQL语句导入导出大全
- 计算机桌面壁纸在哪个文件夹,桌面背景在哪个文件夹,详细教您xp win7 win10系统桌面背景在哪个文件夹?...
- Mac系统搭建C语言开发环境
- 贝塞尔曲线运动n阶追踪方程的数学原理及其匀速化方法和应用
- 天正坐标标注怎么不显示_cad中坐标标注怎么显示不了xy的
- LeetCode 413.等差数列的划分
- “黑盒”下的攻击实现,真实世界的“人脸识别”遭遇危险!
- Typora 设置代码块的默认编程语言以及字体颜色设置
- jfs jfs2_在AIX 6.1上使用JFS2快照