Caffe 运行平台支持DenseNet模型
Posted 楚兴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Caffe 运行平台支持DenseNet模型相关的知识,希望对你有一定的参考价值。
文章目录
在计算机视觉领域,卷积神经网络(CNN)已经成为最主流的方法,比如GoogLenet、VGG-19、Incepetion等模型。CNN史上的一个里程碑事件是ResNet模型的出现,ResNet可以训练出更深的CNN模型,从而实现更高的准确度。ResNet模型的核心是通过建立前面层与后面层之间的“短路连接”(shortcuts,skip connection),这有助于训练过程中梯度的反向传播,从而能训练出更深的CNN网络。
DenseNet模型的基本思路与ResNet一致,但是它建立的是前面所有层与后面层的密集连接(dense connection),它的名称也是由此而来。DenseNet的另一大特色是通过特征在channel上的连接来实现特征重用(feature reuse)。这些特点让DenseNet在参数和计算成本更少的情形下实现比ResNet更优的性能,DenseNet也因此斩获CVPR 2017的最佳论文奖。
1 集成DenseNet的报错信息
最近要把DenseNet集成到现有的运行平台,结果发现加载模型时caffe报如下错误信息:
[TL] 2019/03/21 19:52:17.688357 [8 12 34642][libprotobuf ERROR google/protobuf/text_format.cc:245] Error parsing text-format caffe.NetParameter: 54:15: Message type "caffe.PoolingParameter" has no field named "round_mode".
[TL] 2019/03/21 19:52:17.688714 [8 12 34642]F0321 19:52:17.688385 34642 upgrade_proto.cpp:90] Check failed: ReadProtoFromTextFile(param_file, param) Failed to parse NetParameter file: /workspace/AI/expression_v2/expression.prototxt
[TL] 2019/03/21 19:52:17.688827 [8 12 34642]*** Check failure stack trace: ***
[TL] 2019/03/21 19:52:17.689052 [8 12 34642] @ 0x7fc916efc84d google::LogMessage::Fail()
[TL] 2019/03/21 19:52:17.689222 [8 12 34642] @ 0x7fc916efe61c google::LogMessage::SendToLog()
[TL] 2019/03/21 19:52:17.689387 [8 12 34642] @ 0x7fc916efc43c google::LogMessage::Flush()
[TL] 2019/03/21 19:52:17.689550 [8 12 34642] @ 0x7fc916efef2e google::LogMessageFatal::~LogMessageFatal()
[TL] 2019/03/21 19:52:17.690197 [8 12 34642] @ 0x7fc91639a17e caffe::ReadNetParamsFromTextFileOrDie()
[TL] 2019/03/21 19:52:17.690515 [8 12 34642] @ 0x7fc91624f23c caffe::Net<>::Net()
[TL] 2019/03/21 19:52:17.690695 [8 12 34642] @ 0x7fc91733088f ai_init()
[TL] 2019/03/21 19:52:17.690865 [8 12 34642] @ 0x7fc917331ac9 general_classify_init
[TL] 2019/03/21 19:52:17.690893 [8 12 34642] @ 0x406c2b process()
[TL] 2019/03/21 19:52:17.690949 [8 12 34642] @ 0x437564 aicalc_poll()
[TL] 2019/03/21 19:52:17.690983 [8 12 34642] @ 0x405689 main
[TL] 2019/03/21 19:52:17.691576 [8 12 34642] @ 0x7fc9207e6b35 __libc_start_main
[TL] 2019/03/21 19:52:17.691649 [8 12 34642] @ 0x405b79 (unknown)
最核心的报错信息是Message type "caffe.PoolingParameter" has no field named "round_mode"
,这是因为我们现有运行平台使用的caffe版本较低,pooling层不支持round_mode
参数。(之所以选择一个较低的caffe版本,则是因为最初做工程化的时候,最新版caffe不支持SSD模型)
一开始编译caffe的时候还发现了编译出现乱码的情况,通过命令export LC_ALL="C"
,去除所有本地化的设置,即可让编译正确执行。
2 caffe源码分析及修改
2.1 pooling层源码分析
pooling_layer.hpp新旧版本代码对比:
48 int stride_h_, stride_w_; | 48 int stride_h_, stride_w_;
49 int pad_h_, pad_w_; | 49 int pad_h_, pad_w_;
50 int channels_; | 50 int channels_;
51 int height_, width_; | 51 int height_, width_;
52 int pooled_height_, pooled_width_; | 52 int pooled_height_, pooled_width_;
53 bool global_pooling_; | 53 bool global_pooling_;
54 PoolingParameter_RoundMode round_mode_; | ----------------------------------------------------------------------------
55 Blob<Dtype> rand_idx_; | 54 Blob<Dtype> rand_idx_;
56 Blob<int> max_idx_; | 55 Blob<int> max_idx_;
57 ; | 56 ;
58 | 57
59 // namespace caffe | 58 // namespace caffe
60 | 59
- 61 #endif // CAFFE_POOLING_LAYER_HPP_ |- 60 #endif // CAFFE_POOLING_LAYER_HPP_
对比之后发现头文件的改动只是增加了一个字段:PoolingParameter_RoundMode round_mode_
。
pooling_layer.cpp新旧版本代码对比:
91 switch (round_mode_) | 90 pooled_height_ = static_cast<int>(ceil(static_cast<float>(
92 case PoolingParameter_RoundMode_CEIL: | 91 height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
93 pooled_height_ = static_cast<int>(ceil(static_cast<float>( | 92 pooled_width_ = static_cast<int>(ceil(static_cast<float>(
94 height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1; | 93 width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;
95 pooled_width_ = static_cast<int>(ceil(static_cast<float>( | ----------------------------------------------------------------------------
96 width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1; | ----------------------------------------------------------------------------
97 break; | ----------------------------------------------------------------------------
98 case PoolingParameter_RoundMode_FLOOR: | ----------------------------------------------------------------------------
99 pooled_height_ = static_cast<int>(floor(static_cast<float>( | ----------------------------------------------------------------------------
100 height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1; | ----------------------------------------------------------------------------
101 pooled_width_ = static_cast<int>(floor(static_cast<float>( | ----------------------------------------------------------------------------
102 width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1; | ----------------------------------------------------------------------------
103 break; | ----------------------------------------------------------------------------
104 default: | ----------------------------------------------------------------------------
105 LOG(FATAL) << "Unknown rounding mode."; | ----------------------------------------------------------------------------
106
对比之后发现cpp文件的改动也很小,只是根据round_mode参数决定对池化后的宽高取ceil还是floor。
2.2 caffe源码修改
改动1:用新版本caffe中的pooling_layer.hpp
和pooling_layer.cpp
文件替换旧版本caffe中的相应文件。
改动2:在caffe.proto
文件的message PoolingParameter
中追加如下代码:
// How to calculate the output size - using ceil (default) or floor rounding.
enum RoundMode
CEIL = 0;
FLOOR = 1;
optional RoundMode round_mode = 13 [default = CEIL];
使用make -j64
重新编译caffe,编译完成后,得到新版的libcaffe.so.1.0.0
,用最新so替代运行平台中的旧版本so,即可支持DenseNet了。
3 总结
修改流程:
- 改动pooling层的hpp和cpp文件
- 修改caffe.proto文件(因为涉及参数增加)
- 重新编译
以上是关于Caffe 运行平台支持DenseNet模型的主要内容,如果未能解决你的问题,请参考以下文章
行业热点Facebook发布开源Caffe2深度学习框架,顺应跨平台模型训练的新趋势
Horizon:Facebook的应用强化学习平台(PyTorch/Caffe2)