From 172f3beb9b7476c27199fda3e8716e4e52aaf9b3 Mon Sep 17 00:00:00 2001 From: "Gong, Jiong" Date: Tue, 25 Jul 2017 17:09:48 +0800 Subject: [PATCH 01/22] fix the rand_num_ initialization during test phase needing random resize --- src/caffe/data_transformer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/caffe/data_transformer.cpp b/src/caffe/data_transformer.cpp index 5185308e8..107204fed 100644 --- a/src/caffe/data_transformer.cpp +++ b/src/caffe/data_transformer.cpp @@ -1305,6 +1305,7 @@ vector DataTransformer::InferBlobShape( template void DataTransformer::InitRand() { const bool needs_rand = param_.mirror() || + param_.has_random_resize_param() || (phase_ == TRAIN && param_.crop_size()); if (needs_rand) { From ea822d3090efa32bbfd5b0966dd185f4a69577bf Mon Sep 17 00:00:00 2001 From: "Shen, Haihao" Date: Tue, 25 Jul 2017 10:52:36 -0400 Subject: [PATCH 02/22] Fix the blob size infer under random resize mode --- src/caffe/data_transformer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/caffe/data_transformer.cpp b/src/caffe/data_transformer.cpp index 107204fed..d824a4d18 100644 --- a/src/caffe/data_transformer.cpp +++ b/src/caffe/data_transformer.cpp @@ -1272,8 +1272,11 @@ vector DataTransformer::InferBlobShape(const cv::Mat& cv_img) { int img_width = cv_img.cols; // Check dimensions. CHECK_GT(img_channels, 0); - CHECK_GE(img_height, crop_size); - CHECK_GE(img_width, crop_size); + + if (param_.has_random_resize_param() == false) { + CHECK_GE(img_height, crop_size); + CHECK_GE(img_width, crop_size); + } if (param_.has_resize_param()) { InferNewSize(param_.resize_param(), img_width, img_height, From 9f5a01d3a4645cb1d80cfe2a7155657dfb8b20c8 Mon Sep 17 00:00:00 2001 From: "Gong, Jiong" Date: Tue, 25 Jul 2017 22:43:30 +0800 Subject: [PATCH 03/22] only save snapshot on node 0 --- src/caffe/solver.cpp | 8 +++++++- src/caffe/solvers/sgd_solver.cpp | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/caffe/solver.cpp b/src/caffe/solver.cpp index 3f17c5c58..3c8d1e66b 100644 --- a/src/caffe/solver.cpp +++ b/src/caffe/solver.cpp @@ -892,10 +892,16 @@ string Solver::SnapshotFilename(const string extension) { template string Solver::SnapshotToBinaryProto() { string model_filename = SnapshotFilename(".caffemodel"); - LOG(INFO) << "Snapshotting to binary proto file " << model_filename; NetParameter net_param; net_->ToProto(&net_param, param_.snapshot_diff()); +#ifdef USE_MLSL + if (mn::is_root()) { +#endif + LOG(INFO) << "Snapshotting to binary proto file " << model_filename; WriteProtoToBinaryFile(net_param, model_filename); +#ifdef USE_MLSL + } +#endif return model_filename; } diff --git a/src/caffe/solvers/sgd_solver.cpp b/src/caffe/solvers/sgd_solver.cpp index b415c079a..30ed53eae 100644 --- a/src/caffe/solvers/sgd_solver.cpp +++ b/src/caffe/solvers/sgd_solver.cpp @@ -420,9 +420,15 @@ void SGDSolver::SnapshotSolverStateToBinaryProto( history_[i]->ToProto(history_blob); } string snapshot_filename = Solver::SnapshotFilename(".solverstate"); +#ifdef USE_MLSL + if (mn::is_root()) { +#endif LOG(INFO) << "Snapshotting solver state to binary proto file " << snapshot_filename; WriteProtoToBinaryFile(state, snapshot_filename.c_str()); +#ifdef USE_MLSL + } +#endif } template From feb8e1159ecb2958585ba07fb5d8ab5ced0441db Mon Sep 17 00:00:00 2001 From: "Gong, Jiong" Date: Wed, 26 Jul 2017 22:02:41 +0800 Subject: [PATCH 04/22] sync mkldnn private buffer when it is available so that mkldnn descriptor would not be overwritten by the test net --- include/caffe/multinode/multi_sync.hpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/include/caffe/multinode/multi_sync.hpp b/include/caffe/multinode/multi_sync.hpp index ee07b343a..6300c4876 100644 --- a/include/caffe/multinode/multi_sync.hpp +++ b/include/caffe/multinode/multi_sync.hpp @@ -63,7 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace caffe { -#define CAN_USE_PRV(param) (param->prv_diff() && (param->prv_diff_count() == param->count())) +#define CAN_USE_PRV_DATA(param) (param->prv_data() && (param->prv_data_count() == param->count())) +#define CAN_USE_PRV_DIFF(param) (param->prv_diff() && (param->prv_diff_count() == param->count())) template class MultiSync : public MultiSolver::Callback { @@ -114,9 +115,15 @@ namespace caffe { mn::Distribution &distrib = layers[i]->GetDistribution(); for (int j = 0; j < layer_param_ids[i].size(); j++) { int layer_param_id = layer_param_ids[i][j]; - distrib.bcast( - net_params[layer_param_id]->mutable_cpu_data(), - net_params[layer_param_id]->count()); + if (CAN_USE_PRV_DATA(net_params[layer_param_id])) { + distrib.bcast( + net_params[layer_param_id]->mutable_prv_data(), + net_params[layer_param_id]->prv_data_count()); + } else { + distrib.bcast( + net_params[layer_param_id]->mutable_cpu_data(), + net_params[layer_param_id]->count()); + } } } } @@ -226,7 +233,7 @@ namespace caffe { std::vector ¶m_ids = layer_param_ids[layer_id]; for (int i = 0; i < param_ids.size(); ++i) { if (!layer->ParamNeedReduce(i)) continue; - if (CAN_USE_PRV(net_params[param_ids[i]])) { + if (CAN_USE_PRV_DIFF(net_params[param_ids[i]])) { layer->layerOp->GetParameterSet(i)->StartGradientComm((void *) net_params[param_ids[i]]->mutable_prv_diff()); } else { layer->layerOp->GetParameterSet(i)->StartGradientComm((void *) net_params[param_ids[i]]->mutable_cpu_diff()); @@ -266,7 +273,7 @@ namespace caffe { assert(is_completed); param_ids_finished_flags[layer_id][i] = true; #endif - if (CAN_USE_PRV(net_params[param_ids[i]])) { + if (CAN_USE_PRV_DIFF(net_params[param_ids[i]])) { if (delwt_buf != net_params[param_ids[i]]->prv_diff()) caffe_copy(net_params[param_ids[i]]->count(), delwt_buf, From a5220f604e86926eaf0382063723744b665a9d40 Mon Sep 17 00:00:00 2001 From: Haihao Shen Date: Wed, 26 Jul 2017 18:58:51 +0900 Subject: [PATCH 05/22] Support MKL2017 as default engine --- CMakeLists.txt | 2 +- Makefile.config.example | 4 ++-- docs/release_notes.md | 2 -- src/caffe/net.cpp | 16 ++++++++++++---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7948d2c1a..49d8ee810 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ include(cmake/ConfigGen.cmake) caffe_option(CPU_ONLY "Build Caffe without CUDA support" OFF) # TODO: rename to USE_CUDA caffe_option(USE_OPENMP "Build Caffe with OpenMP support" ON ) caffe_option(USE_CUDNN "Build Caffe with cuDNN library support" ON IF NOT CPU_ONLY) -caffe_option(USE_MKL2017_AS_DEFAULT_ENGINE "Use MKL2017 primitives for supported layers" OFF) +caffe_option(USE_MKL2017_AS_DEFAULT_ENGINE "Use MKL2017 primitives for supported layers" ON) caffe_option(USE_MKLDNN_AS_DEFAULT_ENGINE "Use MKL-DNN primitives for supported layers" OFF) caffe_option(BUILD_SHARED_LIBS "Build shared libraries" ON) caffe_option(BUILD_python "Build Python wrapper" ON) diff --git a/Makefile.config.example b/Makefile.config.example index cdf641603..8bfcc57a3 100644 --- a/Makefile.config.example +++ b/Makefile.config.example @@ -43,8 +43,8 @@ # CPU-only switch (uncomment to build without GPU support). CPU_ONLY := 1 -# USE_MKL2017_AS_DEFAULT_ENGINE flag is OBSOLETE -# Put this at the top your train_val.protoxt or solver.prototxt file: +USE_MKL2017_AS_DEFAULT_ENGINE := 1 +# or put this at the top your train_val.protoxt or solver.prototxt file: # engine: "MKL2017" # or use this option with caffe tool: # -engine "MKL2017" diff --git a/docs/release_notes.md b/docs/release_notes.md index 2c4384b25..f1bea1980 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -126,8 +126,6 @@ This Caffe version is seflcontained. This means that newest version of Intel MKL * Set layer engine to `MKL2017` in prototxt file (model). Only this specific layer will be accelerated with new primitives. * Use -engine = MKL2017 in command line as an option during execution of caffe (training, scoring, benchmark) -Comment: there is obsolete method to compale with `USE_MKL2017_AS_DEFAULT_ENGINE := 1` in `Makefile.config`. This is obsolete solution - not recommended to use anymore. - ### Building for GPU Caffe requires the CUDA `nvcc` compiler to compile its GPU code and CUDA driver for GPU operation. To install CUDA, go to the [NVIDIA CUDA website](https://developer.nvidia.com/cuda-downloads) and follow installation instructions there. Install the library and the latest standalone driver separately; the driver bundled with the library is usually out-of-date. **Warning!** The 331.* CUDA driver series has a critical performance issue: do not use it. diff --git a/src/caffe/net.cpp b/src/caffe/net.cpp index a4224f9ba..0a8aeb981 100644 --- a/src/caffe/net.cpp +++ b/src/caffe/net.cpp @@ -189,8 +189,18 @@ void Net::Init(const NetParameter& in_param) { } // Setup layer. const LayerParameter& layer_param = param.layer(layer_id); - if (param.engine() != "" && param.layer(layer_id).engine() == "") - param.mutable_layer(layer_id)->set_engine(param.engine()); + if (param.engine() != "") { + if (param.layer(layer_id).engine() == "") { + param.mutable_layer(layer_id)->set_engine(param.engine()); + } + else { + if ((!param.layer(layer_id).engine().compare("MKL2017") && !param.engine().compare("MKLDNN")) + || (!param.layer(layer_id).engine().compare("MKLDNN") && !param.engine().compare("MKL2017"))) { + param.mutable_layer(layer_id)->set_engine(param.engine()); + } + } + } + if (layer_param.propagate_down_size() > 0) { CHECK_EQ(layer_param.propagate_down_size(), layer_param.bottom_size()) @@ -490,8 +500,6 @@ template void Net::CompileNet(const NetParameter& param, NetParameter* param_compiled) { - - NetParameter param_temp0; param_temp0.CopyFrom(param); param_temp0.clear_layer(); From 47aa669c16625efcd40ee46824bae659c771bb7a Mon Sep 17 00:00:00 2001 From: "Gong, Jiong" Date: Tue, 18 Jul 2017 06:25:43 +0800 Subject: [PATCH 06/22] improve the stats saving: average the stats to align with the moving_average_factor, save per-node stats to solverstate instead of the reduced one --- include/caffe/multinode/multi_sync.hpp | 2 ++ src/caffe/solver.cpp | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/caffe/multinode/multi_sync.hpp b/include/caffe/multinode/multi_sync.hpp index b979e89fe..ee07b343a 100644 --- a/include/caffe/multinode/multi_sync.hpp +++ b/include/caffe/multinode/multi_sync.hpp @@ -138,6 +138,8 @@ namespace caffe { distrib.allreduce( net_param->mutable_cpu_data(), net_param->mutable_cpu_data(), net_param->count()); + caffe_scal(net_param->count(), 1./distrib.get_data_parts(), + net_param->mutable_cpu_data()); } cached_stats[i] = cached_blobs; } diff --git a/src/caffe/solver.cpp b/src/caffe/solver.cpp index 3c8d1e66b..bda1e05f9 100644 --- a/src/caffe/solver.cpp +++ b/src/caffe/solver.cpp @@ -855,14 +855,12 @@ void Solver::Snapshot() { default: LOG(FATAL) << "Unsupported snapshot format."; } - - SnapshotSolverState(model_filename); - #ifdef USE_MLSL for (int i = 0; i < callbacks_.size(); ++i) { callbacks_[i]->on_after_snapshot(); } #endif + SnapshotSolverState(model_filename); } template From c2d5380652b7ba97f3ca333432fd7863589427ac Mon Sep 17 00:00:00 2001 From: "Gong, Jiong" Date: Wed, 26 Jul 2017 20:46:07 +0800 Subject: [PATCH 07/22] revert changes to solver.cpp --- src/caffe/solver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/caffe/solver.cpp b/src/caffe/solver.cpp index bda1e05f9..3c8d1e66b 100644 --- a/src/caffe/solver.cpp +++ b/src/caffe/solver.cpp @@ -855,12 +855,14 @@ void Solver::Snapshot() { default: LOG(FATAL) << "Unsupported snapshot format."; } + + SnapshotSolverState(model_filename); + #ifdef USE_MLSL for (int i = 0; i < callbacks_.size(); ++i) { callbacks_[i]->on_after_snapshot(); } #endif - SnapshotSolverState(model_filename); } template From fdaab41de716e45fb7c9f0eb157ff37f857f73d9 Mon Sep 17 00:00:00 2001 From: "Jin, Ge" Date: Wed, 26 Jul 2017 14:09:37 -0400 Subject: [PATCH 08/22] Add warm up and momentum correction mechanism Signed-off-by: Jin, Ge --- include/caffe/sgd_solvers.hpp | 1 + src/caffe/proto/caffe.proto | 4 +++- src/caffe/solvers/sgd_solver.cpp | 25 +++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/caffe/sgd_solvers.hpp b/include/caffe/sgd_solvers.hpp index 2b6c52227..a11da89de 100644 --- a/include/caffe/sgd_solvers.hpp +++ b/include/caffe/sgd_solvers.hpp @@ -62,6 +62,7 @@ class SGDSolver : public Solver { protected: void PreSolve(); + Dtype GetWarmUpLR(int cur_iter, int warmup_iter, Dtype warmup_start_lr); Dtype GetLearningRate(); virtual void ApplyUpdate(); virtual void ApplyUpdate(int param_id); diff --git a/src/caffe/proto/caffe.proto b/src/caffe/proto/caffe.proto index 3bf537607..44c3b2dbc 100644 --- a/src/caffe/proto/caffe.proto +++ b/src/caffe/proto/caffe.proto @@ -251,7 +251,7 @@ message SolverBatchSizePair { // NOTE // Update the next available ID when you add a new SolverParameter field. // -// SolverParameter next available ID: 47 (last added: engine) +// SolverParameter next available ID: 50 (last added: warm_up_start_lr) message SolverParameter { ////////////////////////////////////////////////////////////////////////////// // Specifying the train and test networks @@ -410,6 +410,8 @@ message SolverParameter { optional bool disabled_update = 46 [default = false]; optional string engine = 47 [default = ""]; + optional int32 warmup_iter = 48 [default = 0]; + optional float warmup_start_lr = 49 [default = 0]; } // A message that stores the solver snapshots diff --git a/src/caffe/solvers/sgd_solver.cpp b/src/caffe/solvers/sgd_solver.cpp index 30ed53eae..264ac954f 100644 --- a/src/caffe/solvers/sgd_solver.cpp +++ b/src/caffe/solvers/sgd_solver.cpp @@ -44,7 +44,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "caffe/util/upgrade_proto.hpp" namespace caffe { - +template +Dtype SGDSolver::GetWarmUpLR(int cur_iter, int warmup_iter, Dtype warmup_start_lr) { + if (cur_iter < 0) { + cur_iter = 0; + } + return (cur_iter * this->param_.base_lr() + + (warmup_iter - cur_iter) * warmup_start_lr) / warmup_iter; +} // Return the current learning rate. The currently implemented learning rate // policies are as follows: // - fixed: always return base_lr. @@ -64,7 +71,13 @@ template Dtype SGDSolver::GetLearningRate() { Dtype rate; const string& lr_policy = this->param_.lr_policy(); - if (lr_policy == "fixed") { + + + if (this->param_.warmup_iter() > 0 && + this->iter_ < this->param_.warmup_iter()) { + rate = GetWarmUpLR(this->iter_, this->param_.warmup_iter(), + this->param_.warmup_start_lr()); + } else if (lr_policy == "fixed") { rate = this->param_.base_lr(); } else if (lr_policy == "step") { this->current_step_ = this->iter_ / this->param_.stepsize(); @@ -349,6 +362,14 @@ void SGDSolver::ComputeUpdateValue(int param_id, Dtype rate) { const vector& net_params_lr = this->net_->params_lr(); Dtype momentum = this->param_.momentum(); Dtype local_rate = rate * net_params_lr[param_id]; + + if (this->param_.warmup_iter() > 0 && + this->iter_ < this->param_.warmup_iter()) { + // Momentum correction during warmup stage + Dtype prev_rate = GetWarmUpLR(this->iter_ - 1, this->param_.warmup_iter(), + this->param_.warmup_start_lr()); + momentum = momentum * (rate / prev_rate); + } // Compute the update to history, then copy it to the parameter diff. switch (Caffe::mode()) { case Caffe::CPU: { From 3a99259f3888e743e3c6bae19d8682e5078ea88e Mon Sep 17 00:00:00 2001 From: fzou1 Date: Thu, 27 Jul 2017 11:08:58 +0800 Subject: [PATCH 09/22] add solver and net files for resnet50 with 8k batch size Change-Id: If5ef35e38cd42d47c49363b001d0f7905d54ab5b --- .../solver.prototxt | 19 + .../train_val.prototxt | 3312 +++++++++++++++++ 2 files changed, 3331 insertions(+) create mode 100644 models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/solver.prototxt create mode 100644 models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt diff --git a/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/solver.prototxt b/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/solver.prototxt new file mode 100644 index 000000000..8f03f6a3a --- /dev/null +++ b/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/solver.prototxt @@ -0,0 +1,19 @@ +net: "models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt" +test_iter: 1000 +test_interval: 156 +test_initialization: false +display: 40 +base_lr: 3.2 +lr_policy: "multistep" +stepvalue:4680 +stepvalue:9360 +stepvalue:12480 +gamma: 0.1 +max_iter: 14075 +warmup_iter: 780 # 1281167 / 8192 * 5 epochs +warmup_start_lr: 0.1 +momentum: 0.9 +weight_decay: 0.0001 +snapshot: 156 +snapshot_prefix: "models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/resnet_50_256_nodes_8k" +solver_mode: CPU diff --git a/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt b/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt new file mode 100644 index 000000000..e5c7a9128 --- /dev/null +++ b/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt @@ -0,0 +1,3312 @@ +name: "ResNet-50" +layer { + name: "data" + type: "Data" + top: "data" + top: "label" + include { + phase: TRAIN + } + transform_param { + mirror: true + crop_size: 224 + scale: 0.0078125 + mean_value: 104 + mean_value: 117 + mean_value: 123 + random_resize_param { + min_size: 256 max_size: 480 + resize_param { + interp_mode: CUBIC + } + } + } + data_param { + source: "examples/imagenet/ilsvrc12_train_lmdb" + batch_size: 32 + backend: LMDB + prefetch: 2 + shuffle: true + } +} +layer { + name: "data" + type: "Data" + top: "data" + top: "label" + include { + phase: TEST + } + transform_param { + mirror: false + crop_size: 224 + scale: 0.0078125 + mean_value: 104 + mean_value: 117 + mean_value: 123 + } + data_param { + source: "examples/imagenet/ilsvrc12_val_lmdb" + batch_size: 50 + backend: LMDB + } +} + +layer { + bottom: "data" + top: "conv1" + name: "conv1" + type: "Convolution" + convolution_param { + num_output: 64 + kernel_size: 7 + pad: 3 + stride: 2 + weight_filler { + type: "msra" + variance_norm: FAN_OUT + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "conv1" + top: "conv1" + name: "bn_conv1" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "conv1" + top: "conv1" + name: "scale_conv1" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "conv1" + top: "conv1" + name: "conv1_relu" + type: "ReLU" + relu_param { + } +} + +layer { + bottom: "conv1" + top: "pool1" + name: "pool1" + type: "Pooling" + pooling_param { + kernel_size: 3 + stride: 2 + pool: MAX + } +} + +layer { + bottom: "pool1" + top: "res2a_branch1" + name: "res2a_branch1" + type: "Convolution" + convolution_param { + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2a_branch1" + top: "res2a_branch1" + name: "bn2a_branch1" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2a_branch1" + top: "res2a_branch1" + name: "scale2a_branch1" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "pool1" + top: "res2a_branch2a" + name: "res2a_branch2a" + type: "Convolution" + convolution_param { + + num_output: 64 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2a_branch2a" + top: "res2a_branch2a" + name: "bn2a_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2a_branch2a" + top: "res2a_branch2a" + name: "scale2a_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2a_branch2a" + top: "res2a_branch2a" + name: "res2a_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2a_branch2a" + top: "res2a_branch2b" + name: "res2a_branch2b" + type: "Convolution" + convolution_param { + num_output: 64 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2a_branch2b" + top: "res2a_branch2b" + name: "bn2a_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2a_branch2b" + top: "res2a_branch2b" + name: "scale2a_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2a_branch2b" + top: "res2a_branch2b" + name: "res2a_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2a_branch2b" + top: "res2a_branch2c" + name: "res2a_branch2c" + type: "Convolution" + convolution_param { + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2a_branch2c" + top: "res2a_branch2c" + name: "bn2a_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2a_branch2c" + top: "res2a_branch2c" + name: "scale2a_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2a_branch1" + bottom: "res2a_branch2c" + top: "res2a" + name: "res2a" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res2a" + top: "res2a" + name: "res2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2a" + top: "res2b_branch2a" + name: "res2b_branch2a" + type: "Convolution" + convolution_param { + num_output: 64 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2b_branch2a" + top: "res2b_branch2a" + name: "bn2b_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2b_branch2a" + top: "res2b_branch2a" + name: "scale2b_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2b_branch2a" + top: "res2b_branch2a" + name: "res2b_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2b_branch2a" + top: "res2b_branch2b" + name: "res2b_branch2b" + type: "Convolution" + convolution_param { + num_output: 64 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2b_branch2b" + top: "res2b_branch2b" + name: "bn2b_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2b_branch2b" + top: "res2b_branch2b" + name: "scale2b_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2b_branch2b" + top: "res2b_branch2b" + name: "res2b_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2b_branch2b" + top: "res2b_branch2c" + name: "res2b_branch2c" + type: "Convolution" + convolution_param { + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2b_branch2c" + top: "res2b_branch2c" + name: "bn2b_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2b_branch2c" + top: "res2b_branch2c" + name: "scale2b_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2a" + bottom: "res2b_branch2c" + top: "res2b" + name: "res2b" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res2b" + top: "res2b" + name: "res2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2b" + top: "res2c_branch2a" + name: "res2c_branch2a" + type: "Convolution" + convolution_param { + + num_output: 64 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2c_branch2a" + top: "res2c_branch2a" + name: "bn2c_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2c_branch2a" + top: "res2c_branch2a" + name: "scale2c_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2c_branch2a" + top: "res2c_branch2a" + name: "res2c_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2c_branch2a" + top: "res2c_branch2b" + name: "res2c_branch2b" + type: "Convolution" + convolution_param { + num_output: 64 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2c_branch2b" + top: "res2c_branch2b" + name: "bn2c_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res2c_branch2b" + top: "res2c_branch2b" + name: "scale2c_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2c_branch2b" + top: "res2c_branch2b" + name: "res2c_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2c_branch2b" + top: "res2c_branch2c" + name: "res2c_branch2c" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res2c_branch2c" + top: "res2c_branch2c" + name: "bn2c_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 0 } + } +} + +layer { + bottom: "res2c_branch2c" + top: "res2c_branch2c" + name: "scale2c_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2b" + bottom: "res2c_branch2c" + top: "res2c" + name: "res2c" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res2c" + top: "res2c" + name: "res2c_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res2c" + top: "res3a_branch1" + name: "res3a_branch1" + type: "Convolution" + convolution_param { + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 2 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3a_branch1" + top: "res3a_branch1" + name: "bn3a_branch1" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3a_branch1" + top: "res3a_branch1" + name: "scale3a_branch1" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res2c" + top: "res3a_branch2a" + name: "res3a_branch2a" + type: "Convolution" + convolution_param { + + num_output: 128 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3a_branch2a" + top: "res3a_branch2a" + name: "bn3a_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3a_branch2a" + top: "res3a_branch2a" + name: "scale3a_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3a_branch2a" + top: "res3a_branch2a" + name: "res3a_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3a_branch2a" + top: "res3a_branch2b" + name: "res3a_branch2b" + type: "Convolution" + convolution_param { + + num_output: 128 + kernel_size: 3 + pad: 1 + stride: 2 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3a_branch2b" + top: "res3a_branch2b" + name: "bn3a_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3a_branch2b" + top: "res3a_branch2b" + name: "scale3a_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3a_branch2b" + top: "res3a_branch2b" + name: "res3a_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3a_branch2b" + top: "res3a_branch2c" + name: "res3a_branch2c" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3a_branch2c" + top: "res3a_branch2c" + name: "bn3a_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3a_branch2c" + top: "res3a_branch2c" + name: "scale3a_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3a_branch1" + bottom: "res3a_branch2c" + top: "res3a" + name: "res3a" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res3a" + top: "res3a" + name: "res3a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3a" + top: "res3b_branch2a" + name: "res3b_branch2a" + type: "Convolution" + convolution_param { + + num_output: 128 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3b_branch2a" + top: "res3b_branch2a" + name: "bn3b_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3b_branch2a" + top: "res3b_branch2a" + name: "scale3b_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3b_branch2a" + top: "res3b_branch2a" + name: "res3b_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3b_branch2a" + top: "res3b_branch2b" + name: "res3b_branch2b" + type: "Convolution" + convolution_param { + + num_output: 128 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3b_branch2b" + top: "res3b_branch2b" + name: "bn3b_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3b_branch2b" + top: "res3b_branch2b" + name: "scale3b_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3b_branch2b" + top: "res3b_branch2b" + name: "res3b_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3b_branch2b" + top: "res3b_branch2c" + name: "res3b_branch2c" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3b_branch2c" + top: "res3b_branch2c" + name: "bn3b_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3b_branch2c" + top: "res3b_branch2c" + name: "scale3b_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3a" + bottom: "res3b_branch2c" + top: "res3b" + name: "res3b" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res3b" + top: "res3b" + name: "res3b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3b" + top: "res3c_branch2a" + name: "res3c_branch2a" + type: "Convolution" + convolution_param { + + num_output: 128 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3c_branch2a" + top: "res3c_branch2a" + name: "bn3c_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3c_branch2a" + top: "res3c_branch2a" + name: "scale3c_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3c_branch2a" + top: "res3c_branch2a" + name: "res3c_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3c_branch2a" + top: "res3c_branch2b" + name: "res3c_branch2b" + type: "Convolution" + convolution_param { + + num_output: 128 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3c_branch2b" + top: "res3c_branch2b" + name: "bn3c_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3c_branch2b" + top: "res3c_branch2b" + name: "scale3c_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3c_branch2b" + top: "res3c_branch2b" + name: "res3c_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3c_branch2b" + top: "res3c_branch2c" + name: "res3c_branch2c" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3c_branch2c" + top: "res3c_branch2c" + name: "bn3c_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3c_branch2c" + top: "res3c_branch2c" + name: "scale3c_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3b" + bottom: "res3c_branch2c" + top: "res3c" + name: "res3c" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res3c" + top: "res3c" + name: "res3c_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3c" + top: "res3d_branch2a" + name: "res3d_branch2a" + type: "Convolution" + convolution_param { + num_output: 128 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3d_branch2a" + top: "res3d_branch2a" + name: "bn3d_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3d_branch2a" + top: "res3d_branch2a" + name: "scale3d_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3d_branch2a" + top: "res3d_branch2a" + name: "res3d_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3d_branch2a" + top: "res3d_branch2b" + name: "res3d_branch2b" + type: "Convolution" + convolution_param { + num_output: 128 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3d_branch2b" + top: "res3d_branch2b" + name: "bn3d_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res3d_branch2b" + top: "res3d_branch2b" + name: "scale3d_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3d_branch2b" + top: "res3d_branch2b" + name: "res3d_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3d_branch2b" + top: "res3d_branch2c" + name: "res3d_branch2c" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res3d_branch2c" + top: "res3d_branch2c" + name: "bn3d_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 0 } + } +} + +layer { + bottom: "res3d_branch2c" + top: "res3d_branch2c" + name: "scale3d_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3c" + bottom: "res3d_branch2c" + top: "res3d" + name: "res3d" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res3d" + top: "res3d" + name: "res3d_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res3d" + top: "res4a_branch1" + name: "res4a_branch1" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 2 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4a_branch1" + top: "res4a_branch1" + name: "bn4a_branch1" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4a_branch1" + top: "res4a_branch1" + name: "scale4a_branch1" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res3d" + top: "res4a_branch2a" + name: "res4a_branch2a" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4a_branch2a" + top: "res4a_branch2a" + name: "bn4a_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4a_branch2a" + top: "res4a_branch2a" + name: "scale4a_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4a_branch2a" + top: "res4a_branch2a" + name: "res4a_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4a_branch2a" + top: "res4a_branch2b" + name: "res4a_branch2b" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 3 + pad: 1 + stride: 2 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4a_branch2b" + top: "res4a_branch2b" + name: "bn4a_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4a_branch2b" + top: "res4a_branch2b" + name: "scale4a_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4a_branch2b" + top: "res4a_branch2b" + name: "res4a_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4a_branch2b" + top: "res4a_branch2c" + name: "res4a_branch2c" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4a_branch2c" + top: "res4a_branch2c" + name: "bn4a_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4a_branch2c" + top: "res4a_branch2c" + name: "scale4a_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4a_branch1" + bottom: "res4a_branch2c" + top: "res4a" + name: "res4a" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res4a" + top: "res4a" + name: "res4a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4a" + top: "res4b_branch2a" + name: "res4b_branch2a" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4b_branch2a" + top: "res4b_branch2a" + name: "bn4b_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4b_branch2a" + top: "res4b_branch2a" + name: "scale4b_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4b_branch2a" + top: "res4b_branch2a" + name: "res4b_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4b_branch2a" + top: "res4b_branch2b" + name: "res4b_branch2b" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4b_branch2b" + top: "res4b_branch2b" + name: "bn4b_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4b_branch2b" + top: "res4b_branch2b" + name: "scale4b_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4b_branch2b" + top: "res4b_branch2b" + name: "res4b_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4b_branch2b" + top: "res4b_branch2c" + name: "res4b_branch2c" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4b_branch2c" + top: "res4b_branch2c" + name: "bn4b_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4b_branch2c" + top: "res4b_branch2c" + name: "scale4b_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4a" + bottom: "res4b_branch2c" + top: "res4b" + name: "res4b" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res4b" + top: "res4b" + name: "res4b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4b" + top: "res4c_branch2a" + name: "res4c_branch2a" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4c_branch2a" + top: "res4c_branch2a" + name: "bn4c_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4c_branch2a" + top: "res4c_branch2a" + name: "scale4c_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4c_branch2a" + top: "res4c_branch2a" + name: "res4c_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4c_branch2a" + top: "res4c_branch2b" + name: "res4c_branch2b" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4c_branch2b" + top: "res4c_branch2b" + name: "bn4c_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4c_branch2b" + top: "res4c_branch2b" + name: "scale4c_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4c_branch2b" + top: "res4c_branch2b" + name: "res4c_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4c_branch2b" + top: "res4c_branch2c" + name: "res4c_branch2c" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4c_branch2c" + top: "res4c_branch2c" + name: "bn4c_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4c_branch2c" + top: "res4c_branch2c" + name: "scale4c_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4b" + bottom: "res4c_branch2c" + top: "res4c" + name: "res4c" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res4c" + top: "res4c" + name: "res4c_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4c" + top: "res4d_branch2a" + name: "res4d_branch2a" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4d_branch2a" + top: "res4d_branch2a" + name: "bn4d_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4d_branch2a" + top: "res4d_branch2a" + name: "scale4d_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4d_branch2a" + top: "res4d_branch2a" + name: "res4d_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4d_branch2a" + top: "res4d_branch2b" + name: "res4d_branch2b" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4d_branch2b" + top: "res4d_branch2b" + name: "bn4d_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4d_branch2b" + top: "res4d_branch2b" + name: "scale4d_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4d_branch2b" + top: "res4d_branch2b" + name: "res4d_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4d_branch2b" + top: "res4d_branch2c" + name: "res4d_branch2c" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4d_branch2c" + top: "res4d_branch2c" + name: "bn4d_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4d_branch2c" + top: "res4d_branch2c" + name: "scale4d_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4c" + bottom: "res4d_branch2c" + top: "res4d" + name: "res4d" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res4d" + top: "res4d" + name: "res4d_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4d" + top: "res4e_branch2a" + name: "res4e_branch2a" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4e_branch2a" + top: "res4e_branch2a" + name: "bn4e_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4e_branch2a" + top: "res4e_branch2a" + name: "scale4e_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4e_branch2a" + top: "res4e_branch2a" + name: "res4e_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4e_branch2a" + top: "res4e_branch2b" + name: "res4e_branch2b" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4e_branch2b" + top: "res4e_branch2b" + name: "bn4e_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4e_branch2b" + top: "res4e_branch2b" + name: "scale4e_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4e_branch2b" + top: "res4e_branch2b" + name: "res4e_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4e_branch2b" + top: "res4e_branch2c" + name: "res4e_branch2c" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4e_branch2c" + top: "res4e_branch2c" + name: "bn4e_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4e_branch2c" + top: "res4e_branch2c" + name: "scale4e_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4d" + bottom: "res4e_branch2c" + top: "res4e" + name: "res4e" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res4e" + top: "res4e" + name: "res4e_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4e" + top: "res4f_branch2a" + name: "res4f_branch2a" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4f_branch2a" + top: "res4f_branch2a" + name: "bn4f_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4f_branch2a" + top: "res4f_branch2a" + name: "scale4f_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4f_branch2a" + top: "res4f_branch2a" + name: "res4f_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4f_branch2a" + top: "res4f_branch2b" + name: "res4f_branch2b" + type: "Convolution" + convolution_param { + + num_output: 256 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4f_branch2b" + top: "res4f_branch2b" + name: "bn4f_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res4f_branch2b" + top: "res4f_branch2b" + name: "scale4f_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4f_branch2b" + top: "res4f_branch2b" + name: "res4f_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4f_branch2b" + top: "res4f_branch2c" + name: "res4f_branch2c" + type: "Convolution" + convolution_param { + + num_output: 1024 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res4f_branch2c" + top: "res4f_branch2c" + name: "bn4f_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 0 } + } +} + +layer { + bottom: "res4f_branch2c" + top: "res4f_branch2c" + name: "scale4f_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4e" + bottom: "res4f_branch2c" + top: "res4f" + name: "res4f" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res4f" + top: "res4f" + name: "res4f_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res4f" + top: "res5a_branch1" + name: "res5a_branch1" + type: "Convolution" + convolution_param { + + num_output: 2048 + kernel_size: 1 + pad: 0 + stride: 2 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5a_branch1" + top: "res5a_branch1" + name: "bn5a_branch1" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5a_branch1" + top: "res5a_branch1" + name: "scale5a_branch1" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res4f" + top: "res5a_branch2a" + name: "res5a_branch2a" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5a_branch2a" + top: "res5a_branch2a" + name: "bn5a_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5a_branch2a" + top: "res5a_branch2a" + name: "scale5a_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5a_branch2a" + top: "res5a_branch2a" + name: "res5a_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5a_branch2a" + top: "res5a_branch2b" + name: "res5a_branch2b" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 3 + pad: 1 + stride: 2 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5a_branch2b" + top: "res5a_branch2b" + name: "bn5a_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5a_branch2b" + top: "res5a_branch2b" + name: "scale5a_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5a_branch2b" + top: "res5a_branch2b" + name: "res5a_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5a_branch2b" + top: "res5a_branch2c" + name: "res5a_branch2c" + type: "Convolution" + convolution_param { + + num_output: 2048 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5a_branch2c" + top: "res5a_branch2c" + name: "bn5a_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5a_branch2c" + top: "res5a_branch2c" + name: "scale5a_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5a_branch1" + bottom: "res5a_branch2c" + top: "res5a" + name: "res5a" + type: "Eltwise" + eltwise_param { + + } +} + +layer { + bottom: "res5a" + top: "res5a" + name: "res5a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5a" + top: "res5b_branch2a" + name: "res5b_branch2a" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5b_branch2a" + top: "res5b_branch2a" + name: "bn5b_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5b_branch2a" + top: "res5b_branch2a" + name: "scale5b_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5b_branch2a" + top: "res5b_branch2a" + name: "res5b_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5b_branch2a" + top: "res5b_branch2b" + name: "res5b_branch2b" + type: "Convolution" + convolution_param { + + num_output: 512 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5b_branch2b" + top: "res5b_branch2b" + name: "bn5b_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5b_branch2b" + top: "res5b_branch2b" + name: "scale5b_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5b_branch2b" + top: "res5b_branch2b" + name: "res5b_branch2b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5b_branch2b" + top: "res5b_branch2c" + name: "res5b_branch2c" + type: "Convolution" + convolution_param { + + num_output: 2048 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5b_branch2c" + top: "res5b_branch2c" + name: "bn5b_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5b_branch2c" + top: "res5b_branch2c" + name: "scale5b_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5a" + bottom: "res5b_branch2c" + top: "res5b" + name: "res5b" + type: "Eltwise" + eltwise_param { + } +} + +layer { + bottom: "res5b" + top: "res5b" + name: "res5b_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5b" + top: "res5c_branch2a" + name: "res5c_branch2a" + type: "Convolution" + convolution_param { + num_output: 512 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5c_branch2a" + top: "res5c_branch2a" + name: "bn5c_branch2a" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5c_branch2a" + top: "res5c_branch2a" + name: "scale5c_branch2a" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5c_branch2a" + top: "res5c_branch2a" + name: "res5c_branch2a_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5c_branch2a" + top: "res5c_branch2b" + name: "res5c_branch2b" + type: "Convolution" + convolution_param { + num_output: 512 + kernel_size: 3 + pad: 1 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5c_branch2b" + top: "res5c_branch2b" + name: "bn5c_branch2b" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 1 } + } +} + +layer { + bottom: "res5c_branch2b" + top: "res5c_branch2b" + name: "scale5c_branch2b" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5c_branch2b" + top: "res5c_branch2b" + name: "res5c_branch2b_relu" + type: "ReLU" + relu_param { + } +} + +layer { + bottom: "res5c_branch2b" + top: "res5c_branch2c" + name: "res5c_branch2c" + type: "Convolution" + convolution_param { + num_output: 2048 + kernel_size: 1 + pad: 0 + stride: 1 + bias_term: false + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "res5c_branch2c" + top: "res5c_branch2c" + name: "bn5c_branch2c" + type: "BatchNorm" + param { lr_mult: 0 } + param { lr_mult: 0 } + param { lr_mult: 0 } + batch_norm_param { + moving_average_fraction: 0.9 + filler { value: 0 } + } +} + +layer { + bottom: "res5c_branch2c" + top: "res5c_branch2c" + name: "scale5c_branch2c" + type: "Scale" + param { decay_mult: 0 } + param { decay_mult: 0 } + scale_param { + bias_term: true + } +} + +layer { + bottom: "res5b" + bottom: "res5c_branch2c" + top: "res5c" + name: "res5c" + type: "Eltwise" + eltwise_param { + } +} + +layer { + bottom: "res5c" + top: "res5c" + name: "res5c_relu" + type: "ReLU" + relu_param { + + } +} + +layer { + bottom: "res5c" + top: "pool5" + name: "pool5" + type: "Pooling" + pooling_param { + kernel_size: 7 + stride: 1 + pool: AVE + } +} + +layer { + bottom: "pool5" + top: "fc1000" + name: "fc1000" + type: "InnerProduct" + inner_product_param { + num_output: 1000 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + value: 0 + } + } +} + +layer { + bottom: "fc1000" + bottom: "label" + top: "loss" + name: "prob" + type: "SoftmaxWithLoss" +} +layer { + name: "loss3/top-1" + type: "Accuracy" + bottom: "fc1000" + bottom: "label" + top: "loss3/top-1" +} +layer { + name: "loss3/top-5" + type: "Accuracy" + bottom: "fc1000" + bottom: "label" + top: "loss3/top-5" + accuracy_param { + top_k: 5 + } +} From 756db82fb3e65df3af92dbdd274258a87943f0e5 Mon Sep 17 00:00:00 2001 From: "Yu, Chong" Date: Thu, 27 Jul 2017 19:27:12 -0400 Subject: [PATCH 10/22] 1. Fix the average pooling of GoogleNet V2, align the behaviors with CAFFE engine and MKLDNN 2. Fix the unit tests of MKLDNN average pooling. --- include/caffe/layers/mkldnn_layers.hpp | 2 ++ src/caffe/layers/mkldnn_pooling_layer.cpp | 26 +++++++++++++-- src/caffe/test/test_mkldnn_pooling_layer.cpp | 33 +++++++++++++++----- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/include/caffe/layers/mkldnn_layers.hpp b/include/caffe/layers/mkldnn_layers.hpp index a7bb8f659..9e2f23b67 100644 --- a/include/caffe/layers/mkldnn_layers.hpp +++ b/include/caffe/layers/mkldnn_layers.hpp @@ -275,6 +275,7 @@ class MKLDNNPoolingLayer : public MKLDNNLayer, public Layer { , kernel_w_(0), kernel_h_(0), stride_w_(0), stride_h_(0) , pad_t_(0),pad_b_(0), pad_l_(0), pad_r_(0) , global_pooling_(false) + , special_exclude_pooling_flag_(false) { PERFORMANCE_EVENT_ID_RESET(perf_id_fw_); PERFORMANCE_EVENT_ID_RESET(perf_id_bw_); @@ -319,6 +320,7 @@ class MKLDNNPoolingLayer : public MKLDNNLayer, public Layer { int32_t pad_t_, pad_b_, pad_l_, pad_r_; Blob max_idx_; bool global_pooling_; + bool special_exclude_pooling_flag_; PERFORMANCE_EVENT_ID_DECL(perf_id_fw_); PERFORMANCE_EVENT_ID_DECL(perf_id_bw_); diff --git a/src/caffe/layers/mkldnn_pooling_layer.cpp b/src/caffe/layers/mkldnn_pooling_layer.cpp index 4a54a2efc..796e7cd0b 100644 --- a/src/caffe/layers/mkldnn_pooling_layer.cpp +++ b/src/caffe/layers/mkldnn_pooling_layer.cpp @@ -129,12 +129,25 @@ void MKLDNNPoolingLayer::LayerSetUp(const vector*>& bottom CHECK_LT((height_out_ - 1) * stride_h_, bottom[0]->height() + pad_t_); CHECK_LT((width_out_ - 1) * stride_w_, bottom[0]->width() + pad_l_); } + else + { + // If user did not define padding + if ((pool_param.pool() == PoolingParameter_PoolMethod_AVE) && + ((bottom[0]->height() < stride_h_ * (height_out_ - 1) + kernel_h_) || (bottom[0]->width() < stride_w_ * (width_out_ - 1) + kernel_w_))) + { + // average pooling + // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ + // use the exclude padding to align with the result of Caffe + special_exclude_pooling_flag_ = true; + } + } + //Add the pad to make sure h/w + kernel_h/w_ can be exact division by stride_h/w_ auto h = bottom[0]->height() + pad_t_; - while (h + pad_b_ < stride_h_*(height_out_ - 1) + kernel_h_) pad_b_++; + while (h + pad_b_ < stride_h_ * (height_out_ - 1) + kernel_h_) pad_b_++; auto w = bottom[0]->width() + pad_l_; - while (w + pad_r_ < stride_w_*(width_out_ - 1) + kernel_w_) pad_r_++; + while (w + pad_r_ < stride_w_ * (width_out_ - 1) + kernel_w_) pad_r_++; } template @@ -180,6 +193,13 @@ void MKLDNNPoolingLayer::InitPoolingFwd(const vector*>& botto }else { pooling_algorithm = algorithm::pooling_avg_exclude_padding; } + // If user did not define padding + // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ + // use the exclude padding to align with the result of Caffe + if (special_exclude_pooling_flag_ == true) + { + pooling_algorithm = algorithm::pooling_avg_exclude_padding; + } break; case PoolingParameter_PoolMethod_STOCHASTIC: NOT_IMPLEMENTED; @@ -261,7 +281,7 @@ void MKLDNNPoolingLayer::InitPoolingFwd(const vector*>& botto prv_fwd_top_data_mpd.reset(new MemPD(*init_fwd_top_md, engine)); } - // ---- Create priv memory --------------------- + // ---- Create prv memory --------------------- // We'll output the mask to top[1] if it's of size >1. uint32_t* mask = NULL; // suppress warnings about uninitalized variables diff --git a/src/caffe/test/test_mkldnn_pooling_layer.cpp b/src/caffe/test/test_mkldnn_pooling_layer.cpp index 288c114a6..8226bfcaa 100644 --- a/src/caffe/test/test_mkldnn_pooling_layer.cpp +++ b/src/caffe/test/test_mkldnn_pooling_layer.cpp @@ -586,7 +586,7 @@ TYPED_TEST(MKLDNNPoolingLayerTest, TestGradientMaxTopMask) { #endif // Average Pooling -TYPED_TEST(MKLDNNPoolingLayerTest, DISABLED_TestForwardAve) { +TYPED_TEST(MKLDNNPoolingLayerTest, TestForwardAve) { typedef typename TypeParam::Dtype Dtype; LayerParameter layer_param; PoolingParameter* pooling_param = layer_param.mutable_pooling_param(); @@ -607,18 +607,36 @@ TYPED_TEST(MKLDNNPoolingLayerTest, DISABLED_TestForwardAve) { EXPECT_EQ(this->blob_top_->width(), 3); layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); Dtype epsilon = 1e-5; + cout << "bottom blob [0]: " << this->blob_bottom_->cpu_data()[0] << endl; + cout << "bottom blob [1]: " << this->blob_bottom_->cpu_data()[1] << endl; + cout << "bottom blob [2]: " << this->blob_bottom_->cpu_data()[2] << endl; + cout << "bottom blob [3]: " << this->blob_bottom_->cpu_data()[3] << endl; + cout << "bottom blob [4]: " << this->blob_bottom_->cpu_data()[4] << endl; + cout << "bottom blob [5]: " << this->blob_bottom_->cpu_data()[5] << endl; + cout << "bottom blob [6]: " << this->blob_bottom_->cpu_data()[6] << endl; + cout << "bottom blob [7]: " << this->blob_bottom_->cpu_data()[7] << endl; + cout << "bottom blob [8]: " << this->blob_bottom_->cpu_data()[8] << endl; + cout << "top blob [0]: " << this->blob_top_->cpu_data()[0] << endl; + cout << "top blob [1]: " << this->blob_top_->cpu_data()[1] << endl; + cout << "top blob [2]: " << this->blob_top_->cpu_data()[2] << endl; + cout << "top blob [3]: " << this->blob_top_->cpu_data()[3] << endl; + cout << "top blob [4]: " << this->blob_top_->cpu_data()[4] << endl; + cout << "top blob [5]: " << this->blob_top_->cpu_data()[5] << endl; + cout << "top blob [6]: " << this->blob_top_->cpu_data()[6] << endl; + cout << "top blob [7]: " << this->blob_top_->cpu_data()[7] << endl; + cout << "top blob [8]: " << this->blob_top_->cpu_data()[8] << endl; EXPECT_NEAR(this->blob_top_->cpu_data()[0], 8.0 / 9, epsilon); - EXPECT_NEAR(this->blob_top_->cpu_data()[1], 4.0 / 3, epsilon); + EXPECT_NEAR(this->blob_top_->cpu_data()[1], 12.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[2], 8.0 / 9, epsilon); - EXPECT_NEAR(this->blob_top_->cpu_data()[3], 4.0 / 3, epsilon); + EXPECT_NEAR(this->blob_top_->cpu_data()[3], 12.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[4], 2.0 , epsilon); - EXPECT_NEAR(this->blob_top_->cpu_data()[5], 4.0 / 3, epsilon); + EXPECT_NEAR(this->blob_top_->cpu_data()[5], 12.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[6], 8.0 / 9, epsilon); - EXPECT_NEAR(this->blob_top_->cpu_data()[7], 4.0 / 3, epsilon); + EXPECT_NEAR(this->blob_top_->cpu_data()[7], 12.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[8], 8.0 / 9, epsilon); } -TYPED_TEST(MKLDNNPoolingLayerTest, TestGradientAve) { +TYPED_TEST(MKLDNNPoolingLayerTest, DISABLED_TestGradientAve) { typedef typename TypeParam::Dtype Dtype; for (int kernel_h = 3; kernel_h <= 4; kernel_h++) { for (int kernel_w = 3; kernel_w <= 4; kernel_w++) { @@ -636,7 +654,6 @@ TYPED_TEST(MKLDNNPoolingLayerTest, TestGradientAve) { } } -#if 0 TYPED_TEST(MKLDNNPoolingLayerTest, TestGradientAvePadded) { typedef typename TypeParam::Dtype Dtype; for (int kernel_h = 3; kernel_h <= 4; kernel_h++) { @@ -655,6 +672,6 @@ TYPED_TEST(MKLDNNPoolingLayerTest, TestGradientAvePadded) { } } } -#endif + } // namespace caffe #endif // #ifdef MKLDNN_SUPPORTED From 50ab65b4fb97736b24a324c71837eaa7a572d6ce Mon Sep 17 00:00:00 2001 From: "Yu, Chong" Date: Thu, 27 Jul 2017 20:13:51 -0400 Subject: [PATCH 11/22] Fix the inplace in ReLU to make GoogleNet converge. --- src/caffe/layers/mkldnn_relu_layer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/caffe/layers/mkldnn_relu_layer.cpp b/src/caffe/layers/mkldnn_relu_layer.cpp index 6e0f93b67..7eb46612a 100644 --- a/src/caffe/layers/mkldnn_relu_layer.cpp +++ b/src/caffe/layers/mkldnn_relu_layer.cpp @@ -129,6 +129,7 @@ void MKLDNNReLULayer::InitReLUFwd(const vector*>& bottom, con fwd_top_data.reset(new MKLDNNData(usr_data_mpd, prv_data_mpd, top[0], this)); fwd_top_data->name = "fwd_top_data @ " + this->layer_param_.name(); + fwd_top_data_memory = fwd_top_data->create_output_memory(inplace); reluFwd.reset(new relu_forward(*reluFwd_pd, *fwd_bottom_data_primitive, *fwd_top_data_memory)); @@ -303,7 +304,7 @@ void MKLDNNReLULayer::Backward_cpu(const vector*>& top LOG(INFO) << "MKLDNNReLULayer::Backward_cpu: " << this->layer_param_.name(); #endif - bool inplace = (bottom[0] == top[0]); + //bool inplace = (bottom[0] == top[0]); if (!propagate_down[0]) { return; } @@ -312,7 +313,11 @@ void MKLDNNReLULayer::Backward_cpu(const vector*>& top } bwd_top_diff->sync_before_read(); - bwd_bottom_diff->sync_before_write(inplace); + //For MKLDNN, it always create two memory for input and output + //For Intel Caffe, if we set the inplace flag to true, input and output will use one same buffer + //Then the update of output will not pass to MKLDNN + //bwd_bottom_diff->sync_before_write(inplace); //Wrong due to the MKLDNN API design. + bwd_bottom_diff->sync_before_write(); PERFORMANCE_EVENT_ID_INIT(perf_id_bw_, PERFORMANCE_MKLDNN_NAME("BW")); PERFORMANCE_MEASUREMENT_BEGIN(); From fb15856f35192cf51f5391bc422c44425cffb5f2 Mon Sep 17 00:00:00 2001 From: "Yu, Chong" Date: Fri, 28 Jul 2017 04:37:48 -0400 Subject: [PATCH 12/22] Comment out the debugging info in the unit tests of MKLDNN average pooling. --- src/caffe/test/test_mkldnn_pooling_layer.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/caffe/test/test_mkldnn_pooling_layer.cpp b/src/caffe/test/test_mkldnn_pooling_layer.cpp index 8226bfcaa..a9d37010a 100644 --- a/src/caffe/test/test_mkldnn_pooling_layer.cpp +++ b/src/caffe/test/test_mkldnn_pooling_layer.cpp @@ -607,6 +607,8 @@ TYPED_TEST(MKLDNNPoolingLayerTest, TestForwardAve) { EXPECT_EQ(this->blob_top_->width(), 3); layer.Forward(this->blob_bottom_vec_, this->blob_top_vec_); Dtype epsilon = 1e-5; +#if 0 + //For debugging usage cout << "bottom blob [0]: " << this->blob_bottom_->cpu_data()[0] << endl; cout << "bottom blob [1]: " << this->blob_bottom_->cpu_data()[1] << endl; cout << "bottom blob [2]: " << this->blob_bottom_->cpu_data()[2] << endl; @@ -625,6 +627,7 @@ TYPED_TEST(MKLDNNPoolingLayerTest, TestForwardAve) { cout << "top blob [6]: " << this->blob_top_->cpu_data()[6] << endl; cout << "top blob [7]: " << this->blob_top_->cpu_data()[7] << endl; cout << "top blob [8]: " << this->blob_top_->cpu_data()[8] << endl; +#endif EXPECT_NEAR(this->blob_top_->cpu_data()[0], 8.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[1], 12.0 / 9, epsilon); EXPECT_NEAR(this->blob_top_->cpu_data()[2], 8.0 / 9, epsilon); @@ -636,6 +639,12 @@ TYPED_TEST(MKLDNNPoolingLayerTest, TestForwardAve) { EXPECT_NEAR(this->blob_top_->cpu_data()[8], 8.0 / 9, epsilon); } +#if 0 +// This unit test is commented because when user do not define padding +// bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ +// use the exclude padding to align with the result of Caffe +// but when bottom[0]->height/width() + kernel_h/w_ can be exact division by stride_h/w_ +// use the include padding TYPED_TEST(MKLDNNPoolingLayerTest, DISABLED_TestGradientAve) { typedef typename TypeParam::Dtype Dtype; for (int kernel_h = 3; kernel_h <= 4; kernel_h++) { @@ -653,6 +662,7 @@ TYPED_TEST(MKLDNNPoolingLayerTest, DISABLED_TestGradientAve) { } } } +#endif TYPED_TEST(MKLDNNPoolingLayerTest, TestGradientAvePadded) { typedef typename TypeParam::Dtype Dtype; From 3f3fe73dea45597e13f5b187ed0f69e4dfe0bb57 Mon Sep 17 00:00:00 2001 From: Haihao Shen Date: Fri, 28 Jul 2017 17:48:40 +0800 Subject: [PATCH 13/22] Extract the common APIs in util. --- examples/pycaffe/tune_engine.py | 123 +++----------------------------- examples/pycaffe/utils.py | 114 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 115 deletions(-) create mode 100755 examples/pycaffe/utils.py diff --git a/examples/pycaffe/tune_engine.py b/examples/pycaffe/tune_engine.py index 850b94929..9a6fb123a 100755 --- a/examples/pycaffe/tune_engine.py +++ b/examples/pycaffe/tune_engine.py @@ -1,120 +1,9 @@ import os import sys -import copy import argparse - from caffe.proto import caffe_pb2 import google.protobuf.text_format as txtf - -def readFile(filePath): - lines = [] - file = open(filePath, 'r') - for line in file.readlines(): - lines.append(line) - file.close() - - return lines - -def writeFile(filePath, lines): - file = open(filePath, 'w+') - file.write(lines) - file.close() - -def parseLog(log): - lines = readFile(log) - model_start = False - time_start = False - model_lines = [] - time_lines = [] - for line in lines: - trim_line = line.strip() - if trim_line.endswith("Initializing net from parameters:"): - model_start = True - continue - if model_start: - if trim_line.find("Creating layer") <> -1: - model_start = False - continue - model_lines.append(line) - - if trim_line.endswith("Average time per layer:"): - time_start = True - continue - if time_start: - if trim_line.find("Average Forward pass") <> -1: - time_start = False - break - time_lines.append(line) - - model_lines = model_lines[1:] - model_str = "" - for line in model_lines: - model_str = model_str + line - - return (model_str, time_lines) - -def parseTimeLines(timeLines): - layer_map = {} - for line in timeLines: - trim_line = line.strip() - items = trim_line.split("\t") - layer_items = items[0].split(" ") - layer_name = layer_items[-1] - time_items = items[1].split(" ") - if layer_name not in layer_map.keys(): - layer_map[layer_name] = (float)(time_items[1]) - else: - layer_map[layer_name] = layer_map[layer_name] + (float)(time_items[1]) - - return layer_map - -def parseModelStr(modelStr): - net = caffe_pb2.NetParameter() - txtf.Merge(modelStr, net) - layer_model_map = {} - global_engine = "CAFFE" - if net.engine != "": - global_engine = net.engine - for index in range(0, len(net.layer)): - engine = global_engine - l = net.layer[index] - if l.engine != "": - engine = l.engine - param_engine = -1 - if l.type == "Convolution" or l.type == "Deconvolution": - if l.convolution_param.engine != "": - param_engine = l.convolution_param.engine - elif l.type == "BatchNorm": - if l.batch_norm_param.engine != "": - param_engine = l.batch_norm_param.engine - elif l.type == "Concat": - if l.concat_param.engine != "": - param_engine = l.concat_param.engine - elif l.type == "Eltwise": - if l.eltwise_param.engine != "": - param_engine = l.eltwise_param.engine - elif l.type == "InnerProduct": - if l.inner_product_param.engine != "": - param_engine = l.inner_product_param.engine - elif l.type == "LRN": - if l.lrn_param.engine != "": - param_engine = l.lrn_param.engine - elif l.type == "Pooling": - if l.pooling_param.engine != "": - param_engine = l.pooling_param.engine - elif l.type == "ReLU": - if l.relu_param.engine != "": - param_engine = l.relu_param.engine - - if param_engine == 0 or param_engine == 1: - engine = "CAFFE" - elif param_engine == 3: - engine = "MKL2017" - elif param_engine == 4: - engine = "MKLDNN" - layer_model_map[l.name] = (index, engine, l) - - return (net, layer_model_map) +import utils def selectOptimalEngine(layers): optimal_layer = None @@ -140,9 +29,9 @@ def tuneEngine(logs, model): net = None for log in logs: log_name = os.path.basename(log) - (model_str, time_lines) = parseLog(log) - (net, layer_model_map) = parseModelStr(model_str) - layer_time_map = parseTimeLines(time_lines) + (model_str, time_lines) = utils.parseLog(log) + (net, layer_model_map) = utils.parseModelStr(model_str) + layer_time_map = utils.parseTimeLines(time_lines) for k, v in layer_model_map.items(): if k not in layer_map.keys(): layer_map[k] = [(v[0], v[1], layer_time_map[k], v[2])] @@ -187,4 +76,8 @@ def genModel(net, model, optimal_layer_map): parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0') params = parser.parse_args() + if params.output == "": + print "Please specify the output for tuned model with -o" + sys.exit(1) + tuneEngine(params.logs, params.output) diff --git a/examples/pycaffe/utils.py b/examples/pycaffe/utils.py new file mode 100755 index 000000000..91c32bba3 --- /dev/null +++ b/examples/pycaffe/utils.py @@ -0,0 +1,114 @@ +import os +import sys +from caffe.proto import caffe_pb2 +import google.protobuf.text_format as txtf + +def readFile(filePath): + lines = [] + file = open(filePath, 'r') + for line in file.readlines(): + lines.append(line) + file.close() + + return lines + +def writeFile(filePath, lines): + file = open(filePath, 'w+') + file.write(lines) + file.close() + +def parseLog(log): + lines = readFile(log) + model_start = False + time_start = False + model_lines = [] + time_lines = [] + for line in lines: + trim_line = line.strip() + if trim_line.endswith("Initializing net from parameters:"): + model_start = True + continue + if model_start: + if trim_line.find("Creating layer") <> -1: + model_start = False + continue + model_lines.append(line) + + if trim_line.endswith("Average time per layer:"): + time_start = True + continue + if time_start: + if trim_line.find("Average Forward pass") <> -1: + time_start = False + break + time_lines.append(line) + + model_lines = model_lines[1:] + model_str = "" + for line in model_lines: + model_str = model_str + line + + return (model_str, time_lines) + +def parseTimeLines(timeLines): + layer_map = {} + for line in timeLines: + trim_line = line.strip() + items = trim_line.split("\t") + layer_items = items[0].split(" ") + layer_name = layer_items[-1] + time_items = items[1].split(" ") + if layer_name not in layer_map.keys(): + layer_map[layer_name] = (float)(time_items[1]) + else: + layer_map[layer_name] = layer_map[layer_name] + (float)(time_items[1]) + + return layer_map + +def parseModelStr(modelStr): + net = caffe_pb2.NetParameter() + txtf.Merge(modelStr, net) + layer_model_map = {} + global_engine = "CAFFE" + if net.engine != "": + global_engine = net.engine + for index in range(0, len(net.layer)): + engine = global_engine + l = net.layer[index] + if l.engine != "": + engine = l.engine + param_engine = -1 + if l.type == "Convolution" or l.type == "Deconvolution": + if l.convolution_param.engine != "": + param_engine = l.convolution_param.engine + elif l.type == "BatchNorm": + if l.batch_norm_param.engine != "": + param_engine = l.batch_norm_param.engine + elif l.type == "Concat": + if l.concat_param.engine != "": + param_engine = l.concat_param.engine + elif l.type == "Eltwise": + if l.eltwise_param.engine != "": + param_engine = l.eltwise_param.engine + elif l.type == "InnerProduct": + if l.inner_product_param.engine != "": + param_engine = l.inner_product_param.engine + elif l.type == "LRN": + if l.lrn_param.engine != "": + param_engine = l.lrn_param.engine + elif l.type == "Pooling": + if l.pooling_param.engine != "": + param_engine = l.pooling_param.engine + elif l.type == "ReLU": + if l.relu_param.engine != "": + param_engine = l.relu_param.engine + + if param_engine == 0 or param_engine == 1: + engine = "CAFFE" + elif param_engine == 3: + engine = "MKL2017" + elif param_engine == 4: + engine = "MKLDNN" + layer_model_map[l.name] = (index, engine, l) + + return (net, layer_model_map) From 1a20241413906503b4b1de4bf91841098d4d11d3 Mon Sep 17 00:00:00 2001 From: "Yu, Chong" Date: Fri, 28 Jul 2017 11:52:24 -0400 Subject: [PATCH 14/22] Simplify the average pooling condition for GoogleNet-V2. --- include/caffe/layers/mkldnn_layers.hpp | 4 ++-- src/caffe/layers/mkldnn_pooling_layer.cpp | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/include/caffe/layers/mkldnn_layers.hpp b/include/caffe/layers/mkldnn_layers.hpp index 9e2f23b67..35a0b7c1a 100644 --- a/include/caffe/layers/mkldnn_layers.hpp +++ b/include/caffe/layers/mkldnn_layers.hpp @@ -275,7 +275,7 @@ class MKLDNNPoolingLayer : public MKLDNNLayer, public Layer { , kernel_w_(0), kernel_h_(0), stride_w_(0), stride_h_(0) , pad_t_(0),pad_b_(0), pad_l_(0), pad_r_(0) , global_pooling_(false) - , special_exclude_pooling_flag_(false) + , special_exclude_padding_flag_(false) { PERFORMANCE_EVENT_ID_RESET(perf_id_fw_); PERFORMANCE_EVENT_ID_RESET(perf_id_bw_); @@ -320,7 +320,7 @@ class MKLDNNPoolingLayer : public MKLDNNLayer, public Layer { int32_t pad_t_, pad_b_, pad_l_, pad_r_; Blob max_idx_; bool global_pooling_; - bool special_exclude_pooling_flag_; + bool special_exclude_padding_flag_; PERFORMANCE_EVENT_ID_DECL(perf_id_fw_); PERFORMANCE_EVENT_ID_DECL(perf_id_bw_); diff --git a/src/caffe/layers/mkldnn_pooling_layer.cpp b/src/caffe/layers/mkldnn_pooling_layer.cpp index 796e7cd0b..b1353cbb2 100644 --- a/src/caffe/layers/mkldnn_pooling_layer.cpp +++ b/src/caffe/layers/mkldnn_pooling_layer.cpp @@ -131,15 +131,8 @@ void MKLDNNPoolingLayer::LayerSetUp(const vector*>& bottom } else { - // If user did not define padding - if ((pool_param.pool() == PoolingParameter_PoolMethod_AVE) && - ((bottom[0]->height() < stride_h_ * (height_out_ - 1) + kernel_h_) || (bottom[0]->width() < stride_w_ * (width_out_ - 1) + kernel_w_))) - { - // average pooling - // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ - // use the exclude padding to align with the result of Caffe - special_exclude_pooling_flag_ = true; - } + // If user did not define padding, just use the exclude padding + special_exclude_padding_flag_ = true; } //Add the pad to make sure h/w + kernel_h/w_ can be exact division by stride_h/w_ @@ -196,7 +189,8 @@ void MKLDNNPoolingLayer::InitPoolingFwd(const vector*>& botto // If user did not define padding // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ // use the exclude padding to align with the result of Caffe - if (special_exclude_pooling_flag_ == true) + // for exact division situation, exclude padding and include padding will have the same results + if (special_exclude_padding_flag_ == true) { pooling_algorithm = algorithm::pooling_avg_exclude_padding; } From 8829136c9179a973208dd025a50c1debc6596950 Mon Sep 17 00:00:00 2001 From: "Yu, Chong" Date: Fri, 28 Jul 2017 12:42:11 -0400 Subject: [PATCH 15/22] Fix the average pooling of GoogleNet-V2, align the behaviours with MKL2017 and CAFFE engine --- src/caffe/layers/mkl_pooling_layer.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/caffe/layers/mkl_pooling_layer.cpp b/src/caffe/layers/mkl_pooling_layer.cpp index 1e654b63d..2338ae3ce 100644 --- a/src/caffe/layers/mkl_pooling_layer.cpp +++ b/src/caffe/layers/mkl_pooling_layer.cpp @@ -130,6 +130,7 @@ void MKLPoolingLayer::Init( bottom[0]->height() + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1; pooled_width_ = static_cast(ceil(static_cast( bottom[0]->width() + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1; + bool special_exclude_padding_flag_ = false; 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. @@ -142,6 +143,10 @@ void MKLPoolingLayer::Init( CHECK_LT((pooled_height_ - 1) * stride_h_, bottom[0]->height() + pad_h_); CHECK_LT((pooled_width_ - 1) * stride_w_, bottom[0]->width() + pad_w_); } + else + { + special_exclude_padding_flag_ = true; + } top[0]->Reshape(bottom[0]->num(), channels_, pooled_height_, pooled_width_); @@ -172,6 +177,14 @@ void MKLPoolingLayer::Init( else { this->algorithm = dnnAlgorithmPoolingAvgExcludePadding; } + // If user did not define padding + // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ + // use the exclude padding to align with the result of Caffe + // for exact division situation, exclude padding and include padding will have the same results + if (special_exclude_padding_flag_ == true) + { + this->algorithm = dnnAlgorithmPoolingAvgExcludePadding; + } break; case PoolingParameter_PoolMethod_STOCHASTIC: NOT_IMPLEMENTED; From 9675aa3d2b77804012d041105613e5d38bb0758b Mon Sep 17 00:00:00 2001 From: "Yu, Chong" Date: Fri, 28 Jul 2017 20:51:52 -0400 Subject: [PATCH 16/22] Rename special_exclude_padding_flag_ to force_exclude_padding_flag_ --- include/caffe/layers/mkldnn_layers.hpp | 4 ++-- src/caffe/layers/mkl_pooling_layer.cpp | 6 +++--- src/caffe/layers/mkldnn_pooling_layer.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/caffe/layers/mkldnn_layers.hpp b/include/caffe/layers/mkldnn_layers.hpp index 35a0b7c1a..f63301e2a 100644 --- a/include/caffe/layers/mkldnn_layers.hpp +++ b/include/caffe/layers/mkldnn_layers.hpp @@ -275,7 +275,7 @@ class MKLDNNPoolingLayer : public MKLDNNLayer, public Layer { , kernel_w_(0), kernel_h_(0), stride_w_(0), stride_h_(0) , pad_t_(0),pad_b_(0), pad_l_(0), pad_r_(0) , global_pooling_(false) - , special_exclude_padding_flag_(false) + , force_exclude_padding_flag_(false) { PERFORMANCE_EVENT_ID_RESET(perf_id_fw_); PERFORMANCE_EVENT_ID_RESET(perf_id_bw_); @@ -320,7 +320,7 @@ class MKLDNNPoolingLayer : public MKLDNNLayer, public Layer { int32_t pad_t_, pad_b_, pad_l_, pad_r_; Blob max_idx_; bool global_pooling_; - bool special_exclude_padding_flag_; + bool force_exclude_padding_flag_; PERFORMANCE_EVENT_ID_DECL(perf_id_fw_); PERFORMANCE_EVENT_ID_DECL(perf_id_bw_); diff --git a/src/caffe/layers/mkl_pooling_layer.cpp b/src/caffe/layers/mkl_pooling_layer.cpp index 2338ae3ce..8fd2a191d 100644 --- a/src/caffe/layers/mkl_pooling_layer.cpp +++ b/src/caffe/layers/mkl_pooling_layer.cpp @@ -130,7 +130,7 @@ void MKLPoolingLayer::Init( bottom[0]->height() + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1; pooled_width_ = static_cast(ceil(static_cast( bottom[0]->width() + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1; - bool special_exclude_padding_flag_ = false; + bool force_exclude_padding_flag_ = false; 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. @@ -145,7 +145,7 @@ void MKLPoolingLayer::Init( } else { - special_exclude_padding_flag_ = true; + force_exclude_padding_flag_ = true; } top[0]->Reshape(bottom[0]->num(), channels_, pooled_height_, @@ -181,7 +181,7 @@ void MKLPoolingLayer::Init( // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ // use the exclude padding to align with the result of Caffe // for exact division situation, exclude padding and include padding will have the same results - if (special_exclude_padding_flag_ == true) + if (force_exclude_padding_flag_ == true) { this->algorithm = dnnAlgorithmPoolingAvgExcludePadding; } diff --git a/src/caffe/layers/mkldnn_pooling_layer.cpp b/src/caffe/layers/mkldnn_pooling_layer.cpp index b1353cbb2..40f5cf228 100644 --- a/src/caffe/layers/mkldnn_pooling_layer.cpp +++ b/src/caffe/layers/mkldnn_pooling_layer.cpp @@ -132,7 +132,7 @@ void MKLDNNPoolingLayer::LayerSetUp(const vector*>& bottom else { // If user did not define padding, just use the exclude padding - special_exclude_padding_flag_ = true; + force_exclude_padding_flag_ = true; } //Add the pad to make sure h/w + kernel_h/w_ can be exact division by stride_h/w_ @@ -190,7 +190,7 @@ void MKLDNNPoolingLayer::InitPoolingFwd(const vector*>& botto // bottom[0]->height/width() + kernel_h/w_ cannot be exact division by stride_h/w_ // use the exclude padding to align with the result of Caffe // for exact division situation, exclude padding and include padding will have the same results - if (special_exclude_padding_flag_ == true) + if (force_exclude_padding_flag_ == true) { pooling_algorithm = algorithm::pooling_avg_exclude_padding; } From 3ee771f40cea0a5b53f62b8dfd9ed12c82afec26 Mon Sep 17 00:00:00 2001 From: "Gong, Jiong" Date: Sat, 29 Jul 2017 05:19:16 +0800 Subject: [PATCH 17/22] support random aspect ratio change Change-Id: I01aafd16d0ebf10eb3e0ceafde1ef574eee85e8c --- include/caffe/data_transformer.hpp | 2 + src/caffe/data_transformer.cpp | 95 +++++++++++++++++++++++++++--- src/caffe/proto/caffe.proto | 8 +++ 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/include/caffe/data_transformer.hpp b/include/caffe/data_transformer.hpp index f709a281b..e93599f83 100644 --- a/include/caffe/data_transformer.hpp +++ b/include/caffe/data_transformer.hpp @@ -400,6 +400,8 @@ class DataTransformer { #ifdef USE_OPENCV void RandomResizeImage(const Datum& datum, Datum *resized_datum); void RandomResizeImage(const cv::Mat& img, cv::Mat *resized_img); + void RandomAlterAspectRatio(const Datum& datum, Datum *resized_datum); + void RandomAlterAspectRatio(const cv::Mat& img, cv::Mat *resized_img); #endif }; diff --git a/src/caffe/data_transformer.cpp b/src/caffe/data_transformer.cpp index d824a4d18..1eadefd78 100644 --- a/src/caffe/data_transformer.cpp +++ b/src/caffe/data_transformer.cpp @@ -184,6 +184,13 @@ void DataTransformer::Transform(const Datum& datum_in, datum = &resized_datum; #else LOG(FATAL) << "Random image resizing requires OpenCV; compile with USE_OPENCV."; +#endif + } else if (param_.has_random_aspect_ratio_param()) { +#ifdef USE_OPENCV + RandomAlterAspectRatio(datum_in, &resized_datum); + datum = &resized_datum; +#else + LOG(FATAL) << "Aspect ratio changes require OpenCV; compile with USE_OPENCV."; #endif } const string& data = datum->data(); @@ -776,6 +783,13 @@ void DataTransformer::Transform(const cv::Mat& cv_img_in, cv_img = &resized_img; #else LOG(FATAL) << "Random image resizing requires OpenCV; compile with USE_OPENCV."; +#endif + } else if (param_.has_random_aspect_ratio_param()) { +#ifdef USE_OPENCV + RandomAlterAspectRatio(cv_img_in, &resized_img); + cv_img = &resized_img; +#else + LOG(FATAL) << "Aspect ratio changes require OpenCV; compile with USE_OPENCV."; #endif } const int crop_size = param_.crop_size(); @@ -1055,6 +1069,19 @@ void DataTransformer::ExpandImage(const cv::Mat& img, img.copyTo((*expand_img)(bbox_roi)); } +static cv::Mat ResizeImagePerShorterSize(const cv::Mat& img, int shorter_size, ResizeParameter resize_param) { + int h = img.size().height; + int w = img.size().width; + resize_param.set_height(shorter_size); + resize_param.set_width(shorter_size); + if (h < w) { + resize_param.set_width(int(float(w) / h * shorter_size)); + } else { + resize_param.set_height(int(float(h) / w * shorter_size)); + } + return ApplyResize(img, resize_param); +} + template void DataTransformer::RandomResizeImage(const Datum& datum, Datum *resized_datum) { shared_ptr img; @@ -1081,14 +1108,65 @@ void DataTransformer::RandomResizeImage(const cv::Mat& img, cv::Mat *resi if (min_size == 0) min_size = std::min(h,w); if (max_size == 0) max_size = std::max(h,w); int shorter_size = rand_num_(max_size - min_size + 1) + min_size; - resize_param.set_height(shorter_size); - resize_param.set_width(shorter_size); - if (h < w) { - resize_param.set_width(int(float(w) / h * shorter_size)); + *resized_img = ResizeImagePerShorterSize(img, shorter_size, resize_param); +} + +template +void DataTransformer::RandomAlterAspectRatio(const Datum& datum, Datum *resized_datum) { + shared_ptr img; + if (datum.encoded()) { + img = shared_ptr(new cv::Mat(DecodeDatumToCVMatNative(datum))); } else { - resize_param.set_height(int(float(h) / w * shorter_size)); + img = shared_ptr(new cv::Mat( + cv::Size(datum.width(), datum.height()), + CV_8UC(datum.channels()), + (void*)datum.data().data())); } - *resized_img = ApplyResize(img, resize_param); + cv::Mat resized_img; + RandomAlterAspectRatio(*img, &resized_img); + CVMatToDatum(resized_img, resized_datum); +} + +static float RandRatio(float min, float max, RandNumbers& rand_num) { + return (rand_num(int((max - min) * 1000 + 1)) + min * 1000) / 1000; +} + +template +void DataTransformer::RandomAlterAspectRatio(const cv::Mat& img, cv::Mat *resized_img) { + const int crop_size = param_.crop_size(); + const int h = img.size().height; + const int w = img.size().width; + const float area = h * w; + const float min_area_ratio = param_.random_aspect_ratio_param().min_area_ratio(); + const float max_area_ratio = param_.random_aspect_ratio_param().max_area_ratio(); + const float min_aspect_ratio_change = + param_.random_aspect_ratio_param().aspect_ratio_change(); + CHECK(crop_size > 0); + CHECK(max_area_ratio >= min_area_ratio); + ResizeParameter resize_param = param_.random_aspect_ratio_param().resize_param(); + int attempt = 0; + while (attempt++ < 10) { + float area_ratio = RandRatio(min_area_ratio, max_area_ratio, rand_num_); + float aspect_ratio_change = + RandRatio(min_aspect_ratio_change, 1 / min_aspect_ratio_change, rand_num_); + float new_area = area_ratio * area; + int new_h = int(sqrt(new_area) * aspect_ratio_change); + int new_w = int(sqrt(new_area) / aspect_ratio_change); + if (RandRatio(0, 1, rand_num_) < 0.5) { + int tmp = new_h; new_h = new_w; new_w = tmp; + } + if (new_h <= h && new_w <= w) { + int y = rand_num_(h - new_h + 1); + int x = rand_num_(w - new_w + 1); + cv::Rect roi(x, y, new_w, new_h); + cv::Mat croppedImg = img(roi); + resize_param.set_height(crop_size); + resize_param.set_width(crop_size); + *resized_img = ApplyResize(croppedImg, resize_param); + return; + } + } + *resized_img = ResizeImagePerShorterSize(img, crop_size, resize_param); } #endif // USE_OPENCV @@ -1273,7 +1351,9 @@ vector DataTransformer::InferBlobShape(const cv::Mat& cv_img) { // Check dimensions. CHECK_GT(img_channels, 0); - if (param_.has_random_resize_param() == false) { + if (param_.has_random_resize_param() || param_.has_random_aspect_ratio_param()) { + CHECK_GT(crop_size, 0); + } else { CHECK_GE(img_height, crop_size); CHECK_GE(img_width, crop_size); } @@ -1309,6 +1389,7 @@ template void DataTransformer::InitRand() { const bool needs_rand = param_.mirror() || param_.has_random_resize_param() || + param_.has_random_aspect_ratio_param() || (phase_ == TRAIN && param_.crop_size()); if (needs_rand) { diff --git a/src/caffe/proto/caffe.proto b/src/caffe/proto/caffe.proto index 44c3b2dbc..eaf9b6e6b 100644 --- a/src/caffe/proto/caffe.proto +++ b/src/caffe/proto/caffe.proto @@ -649,6 +649,7 @@ message TransformationParameter { optional EmitConstraint emit_constraint = 10; // Resize the input randomly optional RandomResizeParameter random_resize_param = 15; + optional RandomAspectRatioParameter random_aspect_ratio_param = 16; } message RandomResizeParameter { @@ -657,6 +658,13 @@ message RandomResizeParameter { optional ResizeParameter resize_param = 3; } +message RandomAspectRatioParameter { + optional float min_area_ratio = 1 [default = 0.5]; + optional float max_area_ratio = 2 [default = 1]; + optional float aspect_ratio_change = 3 [default = 1]; + optional ResizeParameter resize_param = 5; +} + // Message that stores parameters used by data transformer for resize policy message ResizeParameter { //Probability of using this resize policy From 7b75de1a75551a3105b63231c08c168055466bf6 Mon Sep 17 00:00:00 2001 From: Haihao Shen Date: Mon, 31 Jul 2017 11:40:50 +0800 Subject: [PATCH 18/22] Support winograd tuning after dynamic run --- examples/pycaffe/tune_model.py | 139 +++++++++++++++------------------ 1 file changed, 62 insertions(+), 77 deletions(-) diff --git a/examples/pycaffe/tune_model.py b/examples/pycaffe/tune_model.py index bb9e4bfdd..3f4f13c13 100644 --- a/examples/pycaffe/tune_model.py +++ b/examples/pycaffe/tune_model.py @@ -1,92 +1,77 @@ import os -import datetime -import copy +import sys import argparse - from caffe.proto import caffe_pb2 import google.protobuf.text_format as txtf -import caffe - -def isWinogradApplicable(ic, oc, stride, kernel_size): - if ic % 16 != 0: - return False - if oc % 16 != 0: - return False - if stride != 1: - return False - if kernel_size != 3: - return False - - return True - -def genHybridModel(net, winogradLayers, modelName): - newNet = copy.deepcopy(net) - newNetName = modelName.split(".")[0] + "_hybrid.prototxt" - for layer in winogradLayers: - newNet.layer[layer].convolution_param.conv_algorithm = "winograd" - with open(newNetName, 'w') as f: - f.write(str(newNet)) - print "[INFO] Complete model tuning with Winograd:", newNetName - -def tuneModelDefinition(model): - net = caffe_pb2.NetParameter() - with open(model) as f: - s = f.read() - txtf.Merge(s, net) +import copy +import utils - net.name = 'Tuned model of ' + net.name - output_layer_map = {} +def genOptimalModel(net, mkldnn_time_map, mkldnn_winograd_time_map, optimal_model): for index in range(0, len(net.layer)): l = net.layer[index] - if l.type == ("Convolution"): - stride = 0 - kernel_size = 0 - if len(l.convolution_param.stride) == 0: - stride = 1 - else: - stride = l.convolution_param.stride[0] - kernel_size = l.convolution_param.kernel_size[0] - ic = 0 - if l.bottom[0] in output_layer_map.keys(): - ic = output_layer_map[l.bottom[0]][4] - oc = l.convolution_param.num_output - output_layer_map[l.name] = (index, stride, kernel_size, ic, oc, True) - elif l.type == ("InnerProduct"): - oc = l.inner_product_param.num_output - ic = 0 - if l.bottom[0] in output_layer_map.keys(): - ic = output_layer_map[l.bottom[0]][4] - output_layer_map[l.name] = (index, 0, 0, ic, oc, False) - elif l.type.endswith("Data") or l.type.endswith("Input"): - # TODO: correct the output - # dynamic_net = caffe.Net(model, caffe.TEST) - # for k, v in dynamic_net.blobs.items(): - # dynamic_net_map[k] = v.data.shape - ic = oc = 3 - output_layer_map[l.name] = (index, 0, 0, ic, oc, False) - else: - ic = 0 - if l.bottom[0] in output_layer_map.keys(): - ic = output_layer_map[l.bottom[0]][4] - oc = ic - output_layer_map[l.name] = (index, 0, 0, ic, oc, False) - - winograd_convolutions = [] - for k,v in output_layer_map.items(): - if v[5] and isWinogradApplicable(v[3], v[4], v[1], v[2]): - winograd_convolutions.append(v[0]) - - if len(winograd_convolutions) > 0: - genHybridModel(net, winograd_convolutions, model) - else: - print "[INFO] No need to tune model with Winograd:", model - + if l.type == "Convolution": + if mkldnn_winograd_time_map[l.name] <= mkldnn_time_map[l.name]: + l.convolution_param.conv_algorithm = "winograd" + + with open(optimal_model, "w") as f: + f.write(txtf.MessageToString(net, float_format=".17g")) + +def tuneModelDefinition(model_path, iteration): + working_dir = sys.path[0] + caffe_path = os.path.join(working_dir, "..", "..", "build", "tools", "caffe") + if not os.path.exists(caffe_path): + print "Caffe binary does not exist; please build Caffe binary first." + sys,exit(1) + + base_model_name = os.path.basename(model_path) + model_dir = os.path.dirname(model_path) + winograd_model_name = base_model_name.split(".")[0] + "_winograd.prototxt" + winograd_model_path = os.path.join(model_dir, winograd_model_name) + + base_net = caffe_pb2.NetParameter() + with open(model_path) as f: + s = f.read() + txtf.Merge(s, base_net) + + net_copy = copy.deepcopy(base_net) + for index in range(0, len(base_net.layer)): + l = base_net.layer[index] + if l.type == "Convolution": + l.convolution_param.conv_algorithm = "winograd" + + with open(winograd_model_path, "w") as f: + f.write(txtf.MessageToString(base_net, float_format=".17g")) + + mkldnn_log = "mkldnn.log" + mkldnn_winograd_log = "mkldnn_winograd.log" + mkldnn_log_path = os.path.join(model_dir, mkldnn_log) + mkldnn_winograd_log_path = os.path.join(model_dir, mkldnn_winograd_log) + + mkldnn_command = caffe_path + " time -model " + model_path + " -engine MKLDNN -iterations " + str(iteration) + " >& " + mkldnn_log_path + os.system(mkldnn_command) + mkldnn_winograd_command = caffe_path + " time -model " + model_path + " -engine MKLDNN -iterations " + str(iteration) + " >& " + mkldnn_winograd_log_path + os.system(mkldnn_winograd_command) + + logs = [mkldnn_log_path, mkldnn_winograd_log_path] + + (model_str, mkldnn_time_lines) = utils.parseLog(mkldnn_log_path) + mkldnn_layer_time_map = utils.parseTimeLines(mkldnn_time_lines) + (model_str, mkldnn_winograd_time_lines) = utils.parseLog(mkldnn_winograd_log_path) + mkldnn_winograd_layer_time_map = utils.parseTimeLines(mkldnn_winograd_time_lines) + + hybrid_model_name = base_model_name.split(".")[0] + "_hybrid.prototxt" + hybrid_model_path = os.path.join(model_dir, hybrid_model_name) + genOptimalModel(net_copy, mkldnn_layer_time_map, mkldnn_winograd_layer_time_map, hybrid_model_path) + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-m', '--model', action='store', dest='model', default="", help='require the model definition (prototxt)') + parser.add_argument('-i', '--iteration', action='store', dest='iterations', type=int, default=10, + help='require iterations number to run the model') + parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0') params = parser.parse_args() @@ -96,4 +81,4 @@ def tuneModelDefinition(model): print "[ERROR] Please specify the model definition file with -m" exit(1) - tuneModelDefinition(model) + tuneModelDefinition(params.model, params.iterations) From 5581b10e17ab9cb085222416a28961835a573423 Mon Sep 17 00:00:00 2001 From: Haihao Shen Date: Tue, 1 Aug 2017 09:18:22 +0800 Subject: [PATCH 19/22] Force the origin prototxt with direct to compare with winograd --- examples/pycaffe/tune_model.py | 43 +++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/examples/pycaffe/tune_model.py b/examples/pycaffe/tune_model.py index 3f4f13c13..8305b081b 100644 --- a/examples/pycaffe/tune_model.py +++ b/examples/pycaffe/tune_model.py @@ -6,12 +6,14 @@ import copy import utils -def genOptimalModel(net, mkldnn_time_map, mkldnn_winograd_time_map, optimal_model): +def genOptimalModel(net, mkldnn_direct_time_map, mkldnn_winograd_time_map, optimal_model): for index in range(0, len(net.layer)): l = net.layer[index] if l.type == "Convolution": - if mkldnn_winograd_time_map[l.name] <= mkldnn_time_map[l.name]: + if mkldnn_winograd_time_map[l.name] < mkldnn_direct_time_map[l.name]: l.convolution_param.conv_algorithm = "winograd" + else: + l.convolution_param.conv_algorithm = "direct" with open(optimal_model, "w") as f: f.write(txtf.MessageToString(net, float_format=".17g")) @@ -27,41 +29,50 @@ def tuneModelDefinition(model_path, iteration): model_dir = os.path.dirname(model_path) winograd_model_name = base_model_name.split(".")[0] + "_winograd.prototxt" winograd_model_path = os.path.join(model_dir, winograd_model_name) + direct_model_name = base_model_name.split(".")[0] + "_direct.prototxt" + direct_model_path = os.path.join(model_dir, direct_model_name) base_net = caffe_pb2.NetParameter() with open(model_path) as f: s = f.read() txtf.Merge(s, base_net) - net_copy = copy.deepcopy(base_net) - for index in range(0, len(base_net.layer)): - l = base_net.layer[index] + direct_net = copy.deepcopy(base_net) + for index in range(0, len(direct_net.layer)): + l = direct_net.layer[index] + if l.type == "Convolution": + l.convolution_param.conv_algorithm = "direct" + + with open(direct_model_path, "w") as f: + f.write(txtf.MessageToString(direct_net, float_format=".17g")) + + winograd_net = copy.deepcopy(base_net) + for index in range(0, len(winograd_net.layer)): + l = winograd_net.layer[index] if l.type == "Convolution": l.convolution_param.conv_algorithm = "winograd" with open(winograd_model_path, "w") as f: - f.write(txtf.MessageToString(base_net, float_format=".17g")) + f.write(txtf.MessageToString(winograd_net, float_format=".17g")) - mkldnn_log = "mkldnn.log" + mkldnn_direct_log = "mkldnn_direct.log" mkldnn_winograd_log = "mkldnn_winograd.log" - mkldnn_log_path = os.path.join(model_dir, mkldnn_log) + mkldnn_direct_log_path = os.path.join(model_dir, mkldnn_direct_log) mkldnn_winograd_log_path = os.path.join(model_dir, mkldnn_winograd_log) - mkldnn_command = caffe_path + " time -model " + model_path + " -engine MKLDNN -iterations " + str(iteration) + " >& " + mkldnn_log_path - os.system(mkldnn_command) - mkldnn_winograd_command = caffe_path + " time -model " + model_path + " -engine MKLDNN -iterations " + str(iteration) + " >& " + mkldnn_winograd_log_path + mkldnn_direct_command = caffe_path + " time -model " + direct_model_path + " -engine MKLDNN -iterations " + str(iteration) + " >& " + mkldnn_direct_log_path + os.system(mkldnn_direct_command) + mkldnn_winograd_command = caffe_path + " time -model " + winograd_model_path + " -engine MKLDNN -iterations " + str(iteration) + " >& " + mkldnn_winograd_log_path os.system(mkldnn_winograd_command) - logs = [mkldnn_log_path, mkldnn_winograd_log_path] - - (model_str, mkldnn_time_lines) = utils.parseLog(mkldnn_log_path) - mkldnn_layer_time_map = utils.parseTimeLines(mkldnn_time_lines) + (model_str, mkldnn_direct_time_lines) = utils.parseLog(mkldnn_direct_log_path) + mkldnn_direct_layer_time_map = utils.parseTimeLines(mkldnn_direct_time_lines) (model_str, mkldnn_winograd_time_lines) = utils.parseLog(mkldnn_winograd_log_path) mkldnn_winograd_layer_time_map = utils.parseTimeLines(mkldnn_winograd_time_lines) hybrid_model_name = base_model_name.split(".")[0] + "_hybrid.prototxt" hybrid_model_path = os.path.join(model_dir, hybrid_model_name) - genOptimalModel(net_copy, mkldnn_layer_time_map, mkldnn_winograd_layer_time_map, hybrid_model_path) + genOptimalModel(base_net, mkldnn_direct_layer_time_map, mkldnn_winograd_layer_time_map, hybrid_model_path) if __name__ == '__main__': parser = argparse.ArgumentParser() From 40aa72f0f2c974630e2d98c847fc79d931d18061 Mon Sep 17 00:00:00 2001 From: Haihao Shen Date: Tue, 1 Aug 2017 10:04:18 +0800 Subject: [PATCH 20/22] Optimize the layer engine for SSD deploy --- .../ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkl2017.prototxt | 3 +++ .../ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkldnn.prototxt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkl2017.prototxt b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkl2017.prototxt index 7e2ddbbbb..6d03b44f3 100644 --- a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkl2017.prototxt +++ b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkl2017.prototxt @@ -948,6 +948,7 @@ layer { value: 0 } } + engine: "CAFFE" } layer { name: "conv4_3_norm_mbox_conf_perm" @@ -1065,6 +1066,7 @@ layer { value: 0 } } + engine: "CAFFE" } layer { name: "fc7_mbox_conf_perm" @@ -1183,6 +1185,7 @@ layer { value: 0 } } + engine: "CAFFE" } layer { name: "conv6_2_mbox_conf_perm" diff --git a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkldnn.prototxt b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkldnn.prototxt index 754549d27..7d34d1aa4 100644 --- a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkldnn.prototxt +++ b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy_mkldnn.prototxt @@ -948,6 +948,7 @@ layer { value: 0 } } + engine: "CAFFE" } layer { name: "conv4_3_norm_mbox_conf_perm" @@ -1065,6 +1066,7 @@ layer { value: 0 } } + engine: "CAFFE" } layer { name: "fc7_mbox_conf_perm" @@ -1183,6 +1185,7 @@ layer { value: 0 } } + engine: "CAFFE" } layer { name: "conv6_2_mbox_conf_perm" From 32c7288099d6a0fb0ff66455a1a26e663c3852ef Mon Sep 17 00:00:00 2001 From: Haihao Shen Date: Tue, 1 Aug 2017 13:58:48 +0800 Subject: [PATCH 21/22] Remove layer engine in SSD model definition --- .../VOC0712/SSD_300x300/deploy.prototxt | 60 +------------------ .../VGGNet/VOC0712/SSD_300x300/test.prototxt | 57 ------------------ .../VGGNet/VOC0712/SSD_300x300/train.prototxt | 57 ------------------ 3 files changed, 3 insertions(+), 171 deletions(-) diff --git a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy.prototxt b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy.prototxt index 9450cc65c..dfe14b516 100644 --- a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy.prototxt +++ b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/deploy.prototxt @@ -7,7 +7,6 @@ input_shape { dim: 300 } layer { - engine: "MKL2017" name: "conv1_1" type: "Convolution" bottom: "data" @@ -34,14 +33,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu1_1" type: "ReLU" bottom: "conv1_1" top: "conv1_1" } layer { - engine: "MKL2017" name: "conv1_2" type: "Convolution" bottom: "conv1_1" @@ -68,14 +65,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu1_2" type: "ReLU" bottom: "conv1_2" top: "conv1_2" } layer { - engine: "MKL2017" name: "pool1" type: "Pooling" bottom: "conv1_2" @@ -87,7 +82,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv2_1" type: "Convolution" bottom: "pool1" @@ -114,14 +108,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu2_1" type: "ReLU" bottom: "conv2_1" top: "conv2_1" } layer { - engine: "MKL2017" name: "conv2_2" type: "Convolution" bottom: "conv2_1" @@ -148,14 +140,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu2_2" type: "ReLU" bottom: "conv2_2" top: "conv2_2" } layer { - engine: "MKL2017" name: "pool2" type: "Pooling" bottom: "conv2_2" @@ -167,7 +157,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv3_1" type: "Convolution" bottom: "pool2" @@ -194,14 +183,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_1" type: "ReLU" bottom: "conv3_1" top: "conv3_1" } layer { - engine: "MKL2017" name: "conv3_2" type: "Convolution" bottom: "conv3_1" @@ -228,14 +215,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_2" type: "ReLU" bottom: "conv3_2" top: "conv3_2" } layer { - engine: "MKL2017" name: "conv3_3" type: "Convolution" bottom: "conv3_2" @@ -262,14 +247,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_3" type: "ReLU" bottom: "conv3_3" top: "conv3_3" } layer { - engine: "MKL2017" name: "pool3" type: "Pooling" bottom: "conv3_3" @@ -281,7 +264,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv4_1" type: "Convolution" bottom: "pool3" @@ -308,14 +290,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_1" type: "ReLU" bottom: "conv4_1" top: "conv4_1" } layer { - engine: "MKL2017" name: "conv4_2" type: "Convolution" bottom: "conv4_1" @@ -342,14 +322,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_2" type: "ReLU" bottom: "conv4_2" top: "conv4_2" } layer { - engine: "MKL2017" name: "conv4_3" type: "Convolution" bottom: "conv4_2" @@ -376,14 +354,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_3" type: "ReLU" bottom: "conv4_3" top: "conv4_3" } layer { - engine: "MKL2017" name: "pool4" type: "Pooling" bottom: "conv4_3" @@ -395,7 +371,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv5_1" type: "Convolution" bottom: "pool4" @@ -423,14 +398,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_1" type: "ReLU" bottom: "conv5_1" top: "conv5_1" } layer { - engine: "MKL2017" name: "conv5_2" type: "Convolution" bottom: "conv5_1" @@ -458,14 +431,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_2" type: "ReLU" bottom: "conv5_2" top: "conv5_2" } layer { - engine: "MKL2017" name: "conv5_3" type: "Convolution" bottom: "conv5_2" @@ -493,14 +464,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_3" type: "ReLU" bottom: "conv5_3" top: "conv5_3" } layer { - engine: "MKL2017" name: "pool5" type: "Pooling" bottom: "conv5_3" @@ -513,7 +482,6 @@ layer { } } layer { - engine: "MKL2017" name: "fc6" type: "Convolution" bottom: "pool5" @@ -541,14 +509,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu6" type: "ReLU" bottom: "fc6" top: "fc6" } layer { - engine: "MKL2017" name: "fc7" type: "Convolution" bottom: "fc6" @@ -574,14 +540,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu7" type: "ReLU" bottom: "fc7" top: "fc7" } layer { - engine: "MKL2017" name: "conv6_1" type: "Convolution" bottom: "fc7" @@ -609,14 +573,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_1_relu" type: "ReLU" bottom: "conv6_1" top: "conv6_1" } layer { - engine: "MKL2017" name: "conv6_2" type: "Convolution" bottom: "conv6_1" @@ -644,14 +606,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_2_relu" type: "ReLU" bottom: "conv6_2" top: "conv6_2" } layer { - engine: "MKL2017" name: "conv7_1" type: "Convolution" bottom: "conv6_2" @@ -679,14 +639,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_1_relu" type: "ReLU" bottom: "conv7_1" top: "conv7_1" } layer { - engine: "MKL2017" name: "conv7_2" type: "Convolution" bottom: "conv7_1" @@ -714,14 +672,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_2_relu" type: "ReLU" bottom: "conv7_2" top: "conv7_2" } layer { - engine: "MKL2017" name: "conv8_1" type: "Convolution" bottom: "conv7_2" @@ -749,14 +705,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_1_relu" type: "ReLU" bottom: "conv8_1" top: "conv8_1" } layer { - engine: "MKL2017" name: "conv8_2" type: "Convolution" bottom: "conv8_1" @@ -784,14 +738,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_relu" type: "ReLU" bottom: "conv8_2" top: "conv8_2" } layer { - engine: "MKL2017" name: "conv9_1" type: "Convolution" bottom: "conv8_2" @@ -819,14 +771,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_1_relu" type: "ReLU" bottom: "conv9_1" top: "conv9_1" } layer { - engine: "MKL2017" name: "conv9_2" type: "Convolution" bottom: "conv9_1" @@ -854,7 +804,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_2_relu" type: "ReLU" bottom: "conv9_2" @@ -991,7 +940,6 @@ layer { } } layer { - engine: "MKL2017" name: "fc7_mbox_loc" type: "Convolution" bottom: "fc7" @@ -1109,7 +1057,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_2_mbox_loc" type: "Convolution" bottom: "conv6_2" @@ -1275,7 +1222,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_2_mbox_conf" type: "Convolution" bottom: "conv7_2" @@ -1345,7 +1291,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_mbox_loc" type: "Convolution" bottom: "conv8_2" @@ -1394,7 +1339,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_mbox_conf" type: "Convolution" bottom: "conv8_2" @@ -1511,7 +1455,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_2_mbox_conf" type: "Convolution" bottom: "conv9_2" @@ -1592,6 +1535,7 @@ layer { concat_param { axis: 1 } + engine: "CAFFE" } layer { name: "mbox_conf" @@ -1606,6 +1550,7 @@ layer { concat_param { axis: 1 } + engine: "CAFFE" } layer { name: "mbox_priorbox" @@ -1620,6 +1565,7 @@ layer { concat_param { axis: 2 } + engine: "CAFFE" } layer { name: "mbox_conf_reshape" diff --git a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/test.prototxt b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/test.prototxt index 0a29f708b..38152e56a 100644 --- a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/test.prototxt +++ b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/test.prototxt @@ -31,7 +31,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv1_1" type: "Convolution" bottom: "data" @@ -58,14 +57,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu1_1" type: "ReLU" bottom: "conv1_1" top: "conv1_1" } layer { - engine: "MKL2017" name: "conv1_2" type: "Convolution" bottom: "conv1_1" @@ -92,14 +89,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu1_2" type: "ReLU" bottom: "conv1_2" top: "conv1_2" } layer { - engine: "MKL2017" name: "pool1" type: "Pooling" bottom: "conv1_2" @@ -111,7 +106,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv2_1" type: "Convolution" bottom: "pool1" @@ -138,14 +132,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu2_1" type: "ReLU" bottom: "conv2_1" top: "conv2_1" } layer { - engine: "MKL2017" name: "conv2_2" type: "Convolution" bottom: "conv2_1" @@ -172,14 +164,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu2_2" type: "ReLU" bottom: "conv2_2" top: "conv2_2" } layer { - engine: "MKL2017" name: "pool2" type: "Pooling" bottom: "conv2_2" @@ -191,7 +181,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv3_1" type: "Convolution" bottom: "pool2" @@ -218,14 +207,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_1" type: "ReLU" bottom: "conv3_1" top: "conv3_1" } layer { - engine: "MKL2017" name: "conv3_2" type: "Convolution" bottom: "conv3_1" @@ -252,14 +239,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_2" type: "ReLU" bottom: "conv3_2" top: "conv3_2" } layer { - engine: "MKL2017" name: "conv3_3" type: "Convolution" bottom: "conv3_2" @@ -286,14 +271,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_3" type: "ReLU" bottom: "conv3_3" top: "conv3_3" } layer { - engine: "MKL2017" name: "pool3" type: "Pooling" bottom: "conv3_3" @@ -305,7 +288,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv4_1" type: "Convolution" bottom: "pool3" @@ -332,14 +314,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_1" type: "ReLU" bottom: "conv4_1" top: "conv4_1" } layer { - engine: "MKL2017" name: "conv4_2" type: "Convolution" bottom: "conv4_1" @@ -366,14 +346,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_2" type: "ReLU" bottom: "conv4_2" top: "conv4_2" } layer { - engine: "MKL2017" name: "conv4_3" type: "Convolution" bottom: "conv4_2" @@ -400,14 +378,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_3" type: "ReLU" bottom: "conv4_3" top: "conv4_3" } layer { - engine: "MKL2017" name: "pool4" type: "Pooling" bottom: "conv4_3" @@ -419,7 +395,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv5_1" type: "Convolution" bottom: "pool4" @@ -447,14 +422,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_1" type: "ReLU" bottom: "conv5_1" top: "conv5_1" } layer { - engine: "MKL2017" name: "conv5_2" type: "Convolution" bottom: "conv5_1" @@ -482,14 +455,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_2" type: "ReLU" bottom: "conv5_2" top: "conv5_2" } layer { - engine: "MKL2017" name: "conv5_3" type: "Convolution" bottom: "conv5_2" @@ -517,14 +488,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_3" type: "ReLU" bottom: "conv5_3" top: "conv5_3" } layer { - engine: "MKL2017" name: "pool5" type: "Pooling" bottom: "conv5_3" @@ -537,7 +506,6 @@ layer { } } layer { - engine: "MKL2017" name: "fc6" type: "Convolution" bottom: "pool5" @@ -565,14 +533,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu6" type: "ReLU" bottom: "fc6" top: "fc6" } layer { - engine: "MKL2017" name: "fc7" type: "Convolution" bottom: "fc6" @@ -598,14 +564,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu7" type: "ReLU" bottom: "fc7" top: "fc7" } layer { - engine: "MKL2017" name: "conv6_1" type: "Convolution" bottom: "fc7" @@ -633,14 +597,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_1_relu" type: "ReLU" bottom: "conv6_1" top: "conv6_1" } layer { - engine: "MKL2017" name: "conv6_2" type: "Convolution" bottom: "conv6_1" @@ -668,14 +630,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_2_relu" type: "ReLU" bottom: "conv6_2" top: "conv6_2" } layer { - engine: "MKL2017" name: "conv7_1" type: "Convolution" bottom: "conv6_2" @@ -703,14 +663,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_1_relu" type: "ReLU" bottom: "conv7_1" top: "conv7_1" } layer { - engine: "MKL2017" name: "conv7_2" type: "Convolution" bottom: "conv7_1" @@ -738,14 +696,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_2_relu" type: "ReLU" bottom: "conv7_2" top: "conv7_2" } layer { - engine: "MKL2017" name: "conv8_1" type: "Convolution" bottom: "conv7_2" @@ -773,14 +729,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_1_relu" type: "ReLU" bottom: "conv8_1" top: "conv8_1" } layer { - engine: "MKL2017" name: "conv8_2" type: "Convolution" bottom: "conv8_1" @@ -808,14 +762,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_relu" type: "ReLU" bottom: "conv8_2" top: "conv8_2" } layer { - engine: "MKL2017" name: "conv9_1" type: "Convolution" bottom: "conv8_2" @@ -843,14 +795,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_1_relu" type: "ReLU" bottom: "conv9_1" top: "conv9_1" } layer { - engine: "MKL2017" name: "conv9_2" type: "Convolution" bottom: "conv9_1" @@ -878,7 +828,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_2_relu" type: "ReLU" bottom: "conv9_2" @@ -1015,7 +964,6 @@ layer { } } layer { - engine: "MKL2017" name: "fc7_mbox_loc" type: "Convolution" bottom: "fc7" @@ -1133,7 +1081,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_2_mbox_loc" type: "Convolution" bottom: "conv6_2" @@ -1299,7 +1246,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_2_mbox_conf" type: "Convolution" bottom: "conv7_2" @@ -1369,7 +1315,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_mbox_loc" type: "Convolution" bottom: "conv8_2" @@ -1418,7 +1363,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_mbox_conf" type: "Convolution" bottom: "conv8_2" @@ -1535,7 +1479,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_2_mbox_conf" type: "Convolution" bottom: "conv9_2" diff --git a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/train.prototxt b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/train.prototxt index 88bd9fba3..451a5bad9 100644 --- a/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/train.prototxt +++ b/models/intel_optimized_models/ssd/VGGNet/VOC0712/SSD_300x300/train.prototxt @@ -136,7 +136,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv1_1" type: "Convolution" bottom: "data" @@ -163,14 +162,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu1_1" type: "ReLU" bottom: "conv1_1" top: "conv1_1" } layer { - engine: "MKL2017" name: "conv1_2" type: "Convolution" bottom: "conv1_1" @@ -197,14 +194,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu1_2" type: "ReLU" bottom: "conv1_2" top: "conv1_2" } layer { - engine: "MKL2017" name: "pool1" type: "Pooling" bottom: "conv1_2" @@ -216,7 +211,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv2_1" type: "Convolution" bottom: "pool1" @@ -243,14 +237,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu2_1" type: "ReLU" bottom: "conv2_1" top: "conv2_1" } layer { - engine: "MKL2017" name: "conv2_2" type: "Convolution" bottom: "conv2_1" @@ -277,14 +269,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu2_2" type: "ReLU" bottom: "conv2_2" top: "conv2_2" } layer { - engine: "MKL2017" name: "pool2" type: "Pooling" bottom: "conv2_2" @@ -296,7 +286,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv3_1" type: "Convolution" bottom: "pool2" @@ -323,14 +312,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_1" type: "ReLU" bottom: "conv3_1" top: "conv3_1" } layer { - engine: "MKL2017" name: "conv3_2" type: "Convolution" bottom: "conv3_1" @@ -357,14 +344,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_2" type: "ReLU" bottom: "conv3_2" top: "conv3_2" } layer { - engine: "MKL2017" name: "conv3_3" type: "Convolution" bottom: "conv3_2" @@ -391,14 +376,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu3_3" type: "ReLU" bottom: "conv3_3" top: "conv3_3" } layer { - engine: "MKL2017" name: "pool3" type: "Pooling" bottom: "conv3_3" @@ -410,7 +393,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv4_1" type: "Convolution" bottom: "pool3" @@ -437,14 +419,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_1" type: "ReLU" bottom: "conv4_1" top: "conv4_1" } layer { - engine: "MKL2017" name: "conv4_2" type: "Convolution" bottom: "conv4_1" @@ -471,14 +451,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_2" type: "ReLU" bottom: "conv4_2" top: "conv4_2" } layer { - engine: "MKL2017" name: "conv4_3" type: "Convolution" bottom: "conv4_2" @@ -505,14 +483,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu4_3" type: "ReLU" bottom: "conv4_3" top: "conv4_3" } layer { - engine: "MKL2017" name: "pool4" type: "Pooling" bottom: "conv4_3" @@ -524,7 +500,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv5_1" type: "Convolution" bottom: "pool4" @@ -552,14 +527,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_1" type: "ReLU" bottom: "conv5_1" top: "conv5_1" } layer { - engine: "MKL2017" name: "conv5_2" type: "Convolution" bottom: "conv5_1" @@ -587,14 +560,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_2" type: "ReLU" bottom: "conv5_2" top: "conv5_2" } layer { - engine: "MKL2017" name: "conv5_3" type: "Convolution" bottom: "conv5_2" @@ -622,14 +593,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu5_3" type: "ReLU" bottom: "conv5_3" top: "conv5_3" } layer { - engine: "MKL2017" name: "pool5" type: "Pooling" bottom: "conv5_3" @@ -642,7 +611,6 @@ layer { } } layer { - engine: "MKL2017" name: "fc6" type: "Convolution" bottom: "pool5" @@ -670,14 +638,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu6" type: "ReLU" bottom: "fc6" top: "fc6" } layer { - engine: "MKL2017" name: "fc7" type: "Convolution" bottom: "fc6" @@ -703,14 +669,12 @@ layer { } } layer { - engine: "MKL2017" name: "relu7" type: "ReLU" bottom: "fc7" top: "fc7" } layer { - engine: "MKL2017" name: "conv6_1" type: "Convolution" bottom: "fc7" @@ -738,14 +702,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_1_relu" type: "ReLU" bottom: "conv6_1" top: "conv6_1" } layer { - engine: "MKL2017" name: "conv6_2" type: "Convolution" bottom: "conv6_1" @@ -773,14 +735,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_2_relu" type: "ReLU" bottom: "conv6_2" top: "conv6_2" } layer { - engine: "MKL2017" name: "conv7_1" type: "Convolution" bottom: "conv6_2" @@ -808,14 +768,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_1_relu" type: "ReLU" bottom: "conv7_1" top: "conv7_1" } layer { - engine: "MKL2017" name: "conv7_2" type: "Convolution" bottom: "conv7_1" @@ -843,14 +801,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_2_relu" type: "ReLU" bottom: "conv7_2" top: "conv7_2" } layer { - engine: "MKL2017" name: "conv8_1" type: "Convolution" bottom: "conv7_2" @@ -878,14 +834,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_1_relu" type: "ReLU" bottom: "conv8_1" top: "conv8_1" } layer { - engine: "MKL2017" name: "conv8_2" type: "Convolution" bottom: "conv8_1" @@ -913,14 +867,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_relu" type: "ReLU" bottom: "conv8_2" top: "conv8_2" } layer { - engine: "MKL2017" name: "conv9_1" type: "Convolution" bottom: "conv8_2" @@ -948,14 +900,12 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_1_relu" type: "ReLU" bottom: "conv9_1" top: "conv9_1" } layer { - engine: "MKL2017" name: "conv9_2" type: "Convolution" bottom: "conv9_1" @@ -983,7 +933,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_2_relu" type: "ReLU" bottom: "conv9_2" @@ -1120,7 +1069,6 @@ layer { } } layer { - engine: "MKL2017" name: "fc7_mbox_loc" type: "Convolution" bottom: "fc7" @@ -1238,7 +1186,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv6_2_mbox_loc" type: "Convolution" bottom: "conv6_2" @@ -1404,7 +1351,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv7_2_mbox_conf" type: "Convolution" bottom: "conv7_2" @@ -1474,7 +1420,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_mbox_loc" type: "Convolution" bottom: "conv8_2" @@ -1523,7 +1468,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv8_2_mbox_conf" type: "Convolution" bottom: "conv8_2" @@ -1640,7 +1584,6 @@ layer { } } layer { - engine: "MKL2017" name: "conv9_2_mbox_conf" type: "Convolution" bottom: "conv9_2" From 0da457c7fa2688e8a6bacf603f259a34e4107a2d Mon Sep 17 00:00:00 2001 From: fzou1 Date: Fri, 4 Aug 2017 11:16:19 +0800 Subject: [PATCH 22/22] add random resizing param for test net Change-Id: I0f1e7e2b758e666f6eec8c8c71a1cd905de7b1e1 --- .../resnet_50_256_nodes_8k_batch/train_val.prototxt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt b/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt index e5c7a9128..d98323ed6 100644 --- a/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt +++ b/models/intel_optimized_models/multinode/resnet_50_256_nodes_8k_batch/train_val.prototxt @@ -14,8 +14,10 @@ layer { mean_value: 104 mean_value: 117 mean_value: 123 - random_resize_param { - min_size: 256 max_size: 480 + random_aspect_ratio_param { + min_area_ratio: 0.08 + max_area_ratio: 1 + aspect_ratio_change: 0.75 resize_param { interp_mode: CUBIC } @@ -44,6 +46,13 @@ layer { mean_value: 104 mean_value: 117 mean_value: 123 + random_resize_param { + min_size: 256 + max_size: 256 + resize_param { + interp_mode: CUBIC + } + } } data_param { source: "examples/imagenet/ilsvrc12_val_lmdb"