记录一下caffe1.0里添加densenet
参考https://blog.csdn.net/caicai2526/article/details/79792644DenseNet网络是应用由于分类任务中,在目前较好的分类网络ResNets,他们之前存在着很多的不同。下面先来说一说。 先来看一看网络模型结构: DenseNet主要解决的问题是缓解了消失梯度的问题,增强了特征的传播,促进了特征再利用,大大减少了参数的数量,使网络模型模型进行缩减
参考https://blog.csdn.net/caicai2526/article/details/79792644
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 kernel_h_, kernel_w_;
int stride_h_, stride_w_;
int pad_h_, pad_w_;
int channels_;
int height_, width_;
int pooled_height_, pooled_width_;
bool global_pooling_;
bool ceil_mode_;//添加一个ceil_mode_
Blob<Dtype> rand_idx_;
Blob<int> max_idx_;
};
这边的ceil_mode_是确定是否取整,默认值为True;ceil具体问下有介绍
第二步: 修改src/caffe/layers/pooling_layer.cpp
找到第37行,添加如下
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();
} else {
找到第91行,添加,和注释如下:
if (global_pooling_) {
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,第925行修改如下
// 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 {
然后make all -j8应该编译就能通过了
关于ceil()和floor()区别是一个取整的区别,
C/C++ 取整函数ceil(),floor()
#include <math.h> double floor(double x);
float floorf(float x); long double floorl(long double x);
double floor(double x);
double ceil(double x);
使用floor函数。floor(x)返回的是小于或等于x的最大整数。
如: floor(10.5) == 10 floor(-10.5) == -11
使用ceil函数。ceil(x)返回的是大于x的最小整数。
如: ceil(10.5) == 11 ceil(-10.5) ==-10
floor()是向负无穷大舍入,floor(-10.5) == -11;
ceil()是向正无穷大舍入,ceil(-10.5) == -10
更多推荐
所有评论(0)