Densely connected convolutional networks(DenseNet)论文解读以及运行(Caffe)

DenseNet网络是应用由于分类任务中,在目前较好的分类网络ResNets,他们之前存在着很多的不同。下面先来说一说。
先来看一看网络模型结构:
这里写图片描述
DenseNet主要解决的问题是缓解了消失梯度的问题,增强了特征的传播,促进了特征再利用,大大减少了参数的数量,使网络模型模型进行缩减。
这篇文章中作者主要用了DenseNet-121(k=32),DenseNet-169(k=32),DenseNet-201(k=32),DenseNet-161(k=48),在三个数据集中进行测试。下图是测试结果。
这里写图片描述
DenseNet是一种密集的连接模式的直观效果,它需要的参数比传统的娟娟网络少,无需重新学习冗余的特征图,改善看网络中的信息流和梯度。对于ResNet是采用合并之前所有层的特征到一层的方法。
下面是图片输入后进行操作,值得注意的是Dense里面每一张特征图谱的连接的前提条件必须是特征图谱的大小一致,不然的话也是不可能连接的在文章中作者说的并不是很清楚,我们可以从提供的代码中进行解读,以及对于图像是如何进行降维的在文中我们可以知道两个Dense之间是有一个卷积层和一个pooling层,降维的操作主要是在pooling层中进行,卷积层并没有。
这里写图片描述
下面是文章的链接以及代码的链接:
https://arxiv.org/pdf/1608.06993.pdf
https://github.com/liuzhuang13/DenseNet
一个博客对文章的翻译:
https://blog.csdn.net/tumi678/article/details/78667966?locationNum=7&fps=1

代码实现(Caffe)

后续pytorch以及keras等代码实现之后补充
在利用本文提供的代码对自己的数据进行训练:网络结构的prototxt文件地址:https://github.com/shicai/DenseNet-Caffe
在利用的时候出现的问题:
Question:https://github.com/shicai/DenseNet-Caffe/issues/10
fine-tuning:https://github.com/shicai/DenseNet-Caffe/issues/8
[libprotobuf ERROR google/protobuf/text_format.cc:245] Error parsing text-format caffe.NetParameter: 54:14: Message type “caffe.PoolingParameter” has no field named “ceil_mode”.
解决办法:https://github.com/BVLC/caffe/pull/3057/files
其中,include/caffe/vision_layers.hpp,由于caffe结构已经修改,没有这个文件了,经过查看之后,发现该文件是:/home/ccf/caffe/include/caffe/layers/pooling_layer.hpp
第一步:/home/ccf/caffe/include/caffe/layers/pooling_layer.hpp

   int height_, width_;
   int pooled_height_, pooled_width_;
   bool global_pooling_;
+  bool ceil_mode_;
   Blob<Dtype> rand_idx_;
   Blob<int> max_idx_;
 };

第二步: src/caffe/layers/pooling_layer.cpp

       || (!pool_param.has_stride_h() && !pool_param.has_stride_w()))
       << "Stride is stride OR stride_h and stride_w are required.";
   global_pooling_ = pool_param.global_pooling();
+  ceil_mode_ = pool_param.ceil_mode();
   if (global_pooling_) {
     kernel_h_ = bottom[0]->height();
     kernel_w_ = bottom[0]->width();
@@ -90,10 +91,18 @@ void PoolingLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
     kernel_h_ = bottom[0]->height();
     kernel_w_ = bottom[0]->width();
   }
-  pooled_height_ = static_cast<int>(ceil(static_cast<float>(
-      height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
-  pooled_width_ = static_cast<int>(ceil(static_cast<float>(
-      width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;
+  // Specify the structure by ceil or floor mode
+  if (ceil_mode_) {
+    pooled_height_ = static_cast<int>(ceil(static_cast<float>(
+        height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
+    pooled_width_ = static_cast<int>(ceil(static_cast<float>(
+        width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;
+  } else {
+    pooled_height_ = static_cast<int>(floor(static_cast<float>(
+        height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
+    pooled_width_ = static_cast<int>(floor(static_cast<float>(
+        width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;
+  }
   if (pad_h_ || pad_w_) {
     // If we have padding, ensure that the last pooling starts strictly
     // inside the image (instead of at the padding); otherwise clip the last.

第三步:src/caffe/proto/caffe.proto

   // If global_pooling then it will pool over the size of the bottom by doing
   // kernel_h = bottom->height and kernel_w = bottom->width
   optional bool global_pooling = 12 [default = false];
+  // Specify floor/ceil mode
+  optional bool ceil_mode = 13 [default = true];
 }

 message PowerParameter {

之后对caffe重新编译make -j128

猜你喜欢

转载自blog.csdn.net/caicai2526/article/details/79792644