add message ParamSpec to replace param name, blobs_lr, weight_decay, ...
authorJeff Donahue <jeff.donahue@gmail.com>
Thu, 15 Jan 2015 04:17:26 +0000 (20:17 -0800)
committerJeff Donahue <jeff.donahue@gmail.com>
Thu, 5 Feb 2015 22:49:22 +0000 (14:49 -0800)
src/caffe/net.cpp
src/caffe/proto/caffe.proto
src/caffe/test/test_gradient_based_solver.cpp
src/caffe/test/test_net.cpp
src/caffe/test/test_solver.cpp
src/caffe/test/test_split_layer.cpp
src/caffe/test/test_upgrade_proto.cpp
src/caffe/util/upgrade_proto.cpp

index 4461fa8..b3e1194 100644 (file)
@@ -113,36 +113,19 @@ void Net<Dtype>::Init(const NetParameter& in_param) {
       memory_used_ += top_vecs_[layer_id][top_id]->count();
     }
     DLOG(INFO) << "Memory required for data: " << memory_used_ * sizeof(Dtype);
-    const int blobs_lr_size = layer_param.blobs_lr_size();
+    const int param_size = layer_param.param_size();
     const int num_param_blobs = layers_[layer_id]->blobs().size();
-    CHECK(blobs_lr_size == num_param_blobs || blobs_lr_size == 0)
-        << "Incorrect blobs lr size: should be either 0 "
-        << "or the same as the number of the layer's parameter blobs.";
-    if (blobs_lr_size) {
-      // Check if this layer needs backward operation itself
-      for (int param_id = 0; param_id < blobs_lr_size; ++param_id) {
-        const bool param_need_backward = layer_param.blobs_lr(param_id) > 0;
-        need_backward |= param_need_backward;
-        layers_[layer_id]->set_param_propagate_down(param_id,
-                                                    param_need_backward);
-      }
-    } else if (layers_[layer_id]->blobs().size()) {
-      // catch: if a layer param does not specify blobs_lr, we should assume the
-      // learning rate to be 1. Thus we will need to perform backward.
-      need_backward = true;
-      for (int param_id = 0; param_id < blobs_lr_size; ++param_id) {
-        layers_[layer_id]->set_param_propagate_down(param_id, true);
-      }
+    CHECK_LE(param_size, num_param_blobs)
+        << "Too many params specified for layer " << layer_param.name();
+    ParamSpec default_param_spec;
+    for (int param_id = 0; param_id < num_param_blobs; ++param_id) {
+      const ParamSpec* param_spec = (param_id < param_size) ?
+          &layer_param.param(param_id) : &default_param_spec;
+      const bool param_need_backward = param_spec->lr_mult() > 0;
+      need_backward |= param_need_backward;
+      layers_[layer_id]->set_param_propagate_down(param_id,
+                                                  param_need_backward);
     }
-    const int param_size = layer_param.param_size();
-    CHECK(param_size == num_param_blobs || param_size == 0)
-        << "Incorrect param size: should be either 0 or the same as "
-           "the number of the layer's parameter blobs: " << num_param_blobs;
-    const int param_share_mode_size = layer_param.param_share_mode_size();
-    CHECK(param_share_mode_size == num_param_blobs ||
-          param_share_mode_size == 0)
-        << "Incorrect param_share_mode size: should be either 0 or the same as "
-           "the number of the layer's parameter blobs: " << num_param_blobs;
     for (int param_id = 0; param_id < num_param_blobs; ++param_id) {
       AppendParam(param, layer_id, param_id);
     }
@@ -407,7 +390,8 @@ void Net<Dtype>::AppendParam(const NetParameter& param, const int layer_id,
                              const int param_id) {
   const LayerParameter& layer_param = layers_[layer_id]->layer_param();
   const int param_size = layer_param.param_size();
-  string param_name = param_size ? layer_param.param(param_id) : "";
+  string param_name =
+      (param_size > param_id) ? layer_param.param(param_id).name() : "";
   if (param_name.size()) {
     param_display_names_.push_back(param_name);
   } else {
@@ -442,10 +426,9 @@ void Net<Dtype>::AppendParam(const NetParameter& param, const int layer_id,
     Blob<Dtype>* this_blob = layers_[layer_id]->blobs()[param_id].get();
     Blob<Dtype>* owner_blob =
         layers_[owner_layer_id]->blobs()[owner_param_id].get();
-    const int param_share_mode_size = layer_param.param_share_mode_size();
-    if (param_share_mode_size > param_id &&
-        (layer_param.param_share_mode(param_id) ==
-         LayerParameter_DimCheckMode_PERMISSIVE)) {
+    const int param_size = layer_param.param_size();
+    if (param_size > param_id && (layer_param.param(param_id).share_mode() ==
+                                  ParamSpec_DimCheckMode_PERMISSIVE)) {
       // Permissive dimension checking -- only check counts are the same.
       CHECK_EQ(this_blob->count(), owner_blob->count())
           << "Shared parameter blobs must have the same count.";
@@ -468,34 +451,15 @@ void Net<Dtype>::AppendParam(const NetParameter& param, const int layer_id,
 template <typename Dtype>
 void Net<Dtype>::GetLearningRateAndWeightDecay() {
   LOG(INFO) << "Collecting Learning Rate and Weight Decay.";
+  ParamSpec default_param_spec;
   for (int i = 0; i < layers_.size(); ++i) {
     vector<shared_ptr<Blob<Dtype> > >& layer_blobs = layers_[i]->blobs();
-    // push the learning rate mutlipliers
-    if (layers_[i]->layer_param().blobs_lr_size()) {
-      CHECK_EQ(layers_[i]->layer_param().blobs_lr_size(), layer_blobs.size());
-      for (int j = 0; j < layer_blobs.size(); ++j) {
-        float local_lr = layers_[i]->layer_param().blobs_lr(j);
-        CHECK_GE(local_lr, 0.);
-        params_lr_.push_back(local_lr);
-      }
-    } else {
-      for (int j = 0; j < layer_blobs.size(); ++j) {
-        params_lr_.push_back(1.);
-      }
-    }
-    // push the weight decay multipliers
-    if (layers_[i]->layer_param().weight_decay_size()) {
-      CHECK_EQ(layers_[i]->layer_param().weight_decay_size(),
-          layer_blobs.size());
-      for (int j = 0; j < layer_blobs.size(); ++j) {
-        float local_decay = layers_[i]->layer_param().weight_decay(j);
-        CHECK_GE(local_decay, 0.);
-        params_weight_decay_.push_back(local_decay);
-      }
-    } else {
-      for (int j = 0; j < layer_blobs.size(); ++j) {
-        params_weight_decay_.push_back(1.);
-      }
+    for (int j = 0; j < layer_blobs.size(); ++j) {
+      const ParamSpec* param_spec =
+          (layers_[i]->layer_param().param_size() > j) ?
+          &layers_[i]->layer_param().param(j) : &default_param_spec;
+      params_lr_.push_back(param_spec->lr_mult());
+      params_weight_decay_.push_back(param_spec->decay_mult());
     }
   }
 }
index 1178efe..453bf7f 100644 (file)
@@ -213,6 +213,31 @@ message NetStateRule {
   repeated string not_stage = 5;
 }
 
+// Specifies training parameters (multipliers on global learning constants,
+// and the name and other settings used for weight sharing).
+message ParamSpec {
+  // The names of the parameter blobs -- useful for sharing parameters among
+  // layers, but never required otherwise.  To share a parameter between two
+  // layers, give it a (non-empty) name.
+  optional string name = 1;
+
+  // Whether to require shared weights to have the same shape, or just the same
+  // count -- defaults to STRICT if unspecified.
+  optional DimCheckMode share_mode = 2;
+  enum DimCheckMode {
+    // STRICT (default) requires that num, channels, height, width each match.
+    STRICT = 0;
+    // PERMISSIVE requires only the count (num*channels*height*width) to match.
+    PERMISSIVE = 1;
+  }
+
+  // The multiplier on the global learning rate for this parameter.
+  optional float lr_mult = 3 [default = 1.0];
+
+  // The multiplier on the global weight decay for this parameter.
+  optional float decay_mult = 4 [default = 1.0];
+}
+
 // NOTE
 // Update the next available ID when you add a new LayerParameter field.
 //
@@ -228,29 +253,12 @@ message LayerParameter {
   // to each top blob.
   repeated float loss_weight = 5;
 
-  // The blobs containing the numeric parameters of the layer
-  repeated BlobProto blobs = 6;
+  // Specifies training parameters (multipliers on global learning constants,
+  // and the name and other settings used for weight sharing).
+  repeated ParamSpec param = 6;
 
-  // The names of the parameter blobs -- useful for sharing parameters among
-  // layers (but never required).
-  repeated string param = 7;
-
-  // Whether to require shared weights to have the same shape, or just the same
-  // count -- defaults to STRICT if unspecified.
-  repeated DimCheckMode param_share_mode = 8;
-  enum DimCheckMode {
-    // STRICT (default) requires that num, channels, height, width each match.
-    STRICT = 0;
-    // PERMISSIVE requires only the count (num*channels*height*width) to match.
-    PERMISSIVE = 1;
-  }
-
-  // The ratio that is multiplied on the global learning rate. If you want to
-  // set the learning ratio for one blob, you need to set it for all blobs.
-  repeated float blobs_lr = 9;
-
-  // The weight decay that is multiplied on the global weight decay.
-  repeated float weight_decay = 10;
+  // The blobs containing the numeric parameters of the layer.
+  repeated BlobProto blobs = 7;
 
   // Rules controlling whether and when a layer is included in the network,
   // based on the current NetState.  You may specify a non-zero number of rules
index 1d8192a..eb2569c 100644 (file)
@@ -64,7 +64,7 @@ class GradientBasedSolverTest : public MultiDeviceTest<TypeParam> {
        "lr_policy: 'fixed' "
        "net_param { "
        "  name: 'TestNetwork' "
-       "  layers: { "
+       "  layer { "
        "    name: 'data' "
        "    type: 'DummyData' "
        "    dummy_data_param { "
@@ -83,7 +83,7 @@ class GradientBasedSolverTest : public MultiDeviceTest<TypeParam> {
        "    top: 'data' "
        "    top: 'targets' "
        "  } "
-       "  layers: { "
+       "  layer { "
        "    name: 'innerprod' "
        "    type: 'InnerProduct' "
        "    inner_product_param { "
@@ -100,7 +100,7 @@ class GradientBasedSolverTest : public MultiDeviceTest<TypeParam> {
        "    bottom: 'data' "
        "    top: 'innerprod' "
        "  } "
-       "  layers: { "
+       "  layer { "
        "    name: 'loss' "
        "    type: 'EuclideanLoss' "
        "    bottom: 'innerprod' "
index a4e14f9..bc0dae3 100644 (file)
@@ -59,7 +59,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
                            const bool accuracy_layer = false) {
     string proto =
         "name: 'TinyTestNetwork' "
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -83,7 +83,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  top: 'data' "
         "  top: 'label' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -97,14 +97,18 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0 "
         "    } "
         "  } "
-        "  blobs_lr: 1. "
-        "  blobs_lr: 2. "
-        "  weight_decay: 1. "
-        "  weight_decay: 0. "
+        "  param { "
+        "    lr_mult: 1 "
+        "    decay_mult: 1 "
+        "  } "
+        "  param { "
+        "    lr_mult: 2 "
+        "    decay_mult: 0 "
+        "  } "
         "  bottom: 'data' "
         "  top: 'innerproduct' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'SoftmaxWithLoss' "
         "  bottom: 'innerproduct' "
@@ -113,7 +117,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "} ";
     if (accuracy_layer) {
       proto +=
-          "layers: { "
+          "layer { "
           "  name: 'loss' "
           "  type: 'Accuracy' "
           "  bottom: 'innerproduct' "
@@ -130,7 +134,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
   virtual void InitTinyNetEuclidean(const bool force_backward = false) {
     string proto =
         "name: 'TinyTestEuclidLossNetwork' "
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -150,7 +154,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  top: 'data' "
         "  top: 'label' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -164,14 +168,18 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0 "
         "    } "
         "  } "
-        "  blobs_lr: 1. "
-        "  blobs_lr: 2. "
-        "  weight_decay: 1. "
-        "  weight_decay: 0. "
+        "  param { "
+        "    lr_mult: 1 "
+        "    decay_mult: 1 "
+        "  } "
+        "  param { "
+        "    lr_mult: 2 "
+        "    decay_mult: 0 "
+        "  } "
         "  bottom: 'data' "
         "  top: 'innerproduct' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'EuclideanLoss' "
         "  bottom: 'innerproduct' "
@@ -190,7 +198,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
     }
     const string& proto =
         "name: 'TrickyTestNetwork' "
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -210,7 +218,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  top: 'data' "
         "  top: 'label' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -224,14 +232,18 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0 "
         "    } "
         "  } "
-        "  blobs_lr: 1. "
-        "  blobs_lr: 2. "
-        "  weight_decay: 1. "
-        "  weight_decay: 0. "
+        "  param { "
+        "    lr_mult: 1 "
+        "    decay_mult: 1 "
+        "  } "
+        "  param { "
+        "    lr_mult: 2 "
+        "    decay_mult: 0 "
+        "  } "
         "  bottom: 'data' "
         "  top: 'transformed_data' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -245,14 +257,18 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0 "
         "    } "
         "  } "
-        "  blobs_lr: 1. "
-        "  blobs_lr: 2. "
-        "  weight_decay: 1. "
-        "  weight_decay: 0. "
+        "  param { "
+        "    lr_mult: 1 "
+        "    decay_mult: 1 "
+        "  } "
+        "  param { "
+        "    lr_mult: 2 "
+        "    decay_mult: 0 "
+        "  } "
         "  bottom: 'label' "
         "  top: 'transformed_label' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'SoftmaxWithLoss' " +
         loss_weight_stream.str() +
@@ -277,7 +293,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
       proto << "force_backward: true ";
     }
     proto <<
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -292,9 +308,9 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  } "
         "  top: 'data' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct1' "
-       "  type: 'InnerProduct' "
+        "  type: 'InnerProduct' "
         "  inner_product_param { "
         "    num_output: 10 "
         "    bias_term: " << bias_term <<
@@ -303,14 +319,12 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      std: 10 "
         "    } "
         "  } "
-        "  param: 'unsharedweights1' ";
+        "  param { "
+        "    name: 'unsharedweights1' "
+        "    lr_mult: " << blobs_lr_w1 <<
+        "  } ";
     if (bias_term) {
-      proto << "  param: '' ";
-    }
-    proto <<
-        "  blobs_lr: " << blobs_lr_w1;
-    if (bias_term) {
-      proto << "  blobs_lr: " << blobs_lr_b1;
+      proto << "  param { lr_mult: " << blobs_lr_b1 << " } ";
     }
     proto <<
         "  bottom: 'data' "
@@ -320,7 +334,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
     }
     proto <<
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct2' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -331,20 +345,18 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      std: 10 "
         "    } "
         "  } "
-        "  param: 'unsharedweights2' ";
+        "  param { "
+        "    name: 'unsharedweights2' "
+        "    lr_mult: " << blobs_lr_w2 <<
+        "  } ";
     if (bias_term) {
-      proto << "  param: '' ";
+      proto << "  param { lr_mult: " << blobs_lr_b2 << " } ";
     }
     proto <<
         "  bottom: 'data' "
-        "  blobs_lr: " << blobs_lr_w2;
-    if (bias_term) {
-      proto << "  blobs_lr: " << blobs_lr_b2;
-    }
-    proto <<
         "  top: 'innerproduct2' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'EuclideanLoss' ";
     if (loss_weight) {
@@ -360,7 +372,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
   virtual void InitSharedWeightsNet() {
     const string& proto =
         "name: 'SharedWeightsNetwork' "
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -375,7 +387,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  } "
         "  top: 'data' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct1' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -386,11 +398,11 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      std: 10 "
         "    } "
         "  } "
-        "  param: 'sharedweights' "
+        "  param { name: 'sharedweights' } "
         "  bottom: 'data' "
         "  top: 'innerproduct1' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct2' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -401,11 +413,11 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      std: 10 "
         "    } "
         "  } "
-        "  param: 'sharedweights' "
+        "  param { name: 'sharedweights' } "
         "  bottom: 'data' "
         "  top: 'innerproduct2' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'EuclideanLoss' "
         "  bottom: 'innerproduct1' "
@@ -417,7 +429,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
   virtual void InitDiffDataUnsharedWeightsNet() {
     const string& proto =
         "name: 'DiffDataUnsharedWeightsNetwork' "
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -437,7 +449,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  top: 'data1' "
         "  top: 'data2' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct1' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -448,11 +460,11 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0.5 "
         "    } "
         "  } "
-        "  param: 'unsharedweights1' "
+        "  param { name: 'unsharedweights1' } "
         "  bottom: 'data1' "
         "  top: 'innerproduct1' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct2' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -463,11 +475,11 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0.5 "
         "    } "
         "  } "
-        "  param: 'unsharedweights2' "
+        "  param { name: 'unsharedweights2' } "
         "  bottom: 'innerproduct1' "
         "  top: 'innerproduct2' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'EuclideanLoss' "
         "  bottom: 'data2' "
@@ -479,7 +491,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
   virtual void InitDiffDataSharedWeightsNet() {
     const string& proto =
         "name: 'DiffDataSharedWeightsNetwork' "
-        "layers: { "
+        "layer { "
         "  name: 'data' "
         "  type: 'DummyData' "
         "  dummy_data_param { "
@@ -499,7 +511,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "  top: 'data1' "
         "  top: 'data2' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct1' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -510,11 +522,11 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0.5 "
         "    } "
         "  } "
-        "  param: 'sharedweights' "
+        "  param { name: 'sharedweights' } "
         "  bottom: 'data1' "
         "  top: 'innerproduct1' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'innerproduct2' "
         "  type: 'InnerProduct' "
         "  inner_product_param { "
@@ -525,11 +537,11 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "      value: 0.5 "
         "    } "
         "  } "
-        "  param: 'sharedweights' "
+        "  param { name: 'sharedweights' } "
         "  bottom: 'innerproduct1' "
         "  top: 'innerproduct2' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'loss' "
         "  type: 'EuclideanLoss' "
         "  bottom: 'data2' "
@@ -546,7 +558,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "input_dim: 3 "
         "input_dim: 100 "
         "input_dim: 100 "
-        "layers: { "
+        "layer { "
         "  name: 'conv1' "
         "  type: 'Convolution' "
         "  bottom: 'data' "
@@ -565,13 +577,13 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "    } "
         "  } "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'relu1' "
         "  type: 'ReLU' "
         "  bottom: 'conv1' "
         "  top: 'conv1' "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'pool1' "
         "  type: 'Pooling' "
         "  bottom: 'conv1' "
@@ -582,7 +594,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "    stride: 2 "
         "  } "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'norm1' "
         "  type: 'LRN' "
         "  bottom: 'pool1' "
@@ -591,7 +603,7 @@ class NetTest : public MultiDeviceTest<TypeParam> {
         "    local_size: 3 "
         "  } "
         "} "
-        "layers: { "
+        "layer { "
         "  name: 'softmax' "
         "  type: 'Softmax' "
         "  bottom: 'norm1' "
@@ -1261,19 +1273,19 @@ class FilterNetTest : public ::testing::Test {
 TEST_F(FilterNetTest, TestNoFilter) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1285,7 +1297,7 @@ TEST_F(FilterNetTest, TestNoFilter) {
 TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
   const string& input_proto =
       "name: 'LeNet' "
-      "layers { "
+      "layer { "
       "  name: 'mnist' "
       "  type: 'Data' "
       "  top: 'data' "
@@ -1299,7 +1311,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "  } "
       "  include: { phase: TRAIN } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'mnist' "
       "  type: 'Data' "
       "  top: 'data' "
@@ -1313,13 +1325,17 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "  } "
       "  include: { phase: TEST } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv1' "
       "  type: 'Convolution' "
       "  bottom: 'data' "
       "  top: 'conv1' "
-      "  blobs_lr: 1 "
-      "  blobs_lr: 2 "
+      "  param { "
+      "    lr_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "  } "
       "  convolution_param { "
       "    num_output: 20 "
       "    kernel_size: 5 "
@@ -1332,13 +1348,17 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "    } "
       "  } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'ip1' "
       "  type: 'InnerProduct' "
       "  bottom: 'conv1' "
       "  top: 'ip1' "
-      "  blobs_lr: 1 "
-      "  blobs_lr: 2 "
+      "  param { "
+      "    lr_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "  } "
       "  inner_product_param { "
       "    num_output: 10 "
       "    weight_filler { "
@@ -1349,7 +1369,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "    } "
       "  } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'accuracy' "
       "  type: 'Accuracy' "
       "  bottom: 'ip1' "
@@ -1357,7 +1377,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "  top: 'accuracy' "
       "  include: { phase: TEST } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'ip2' "
@@ -1368,7 +1388,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
   const string input_proto_test = "state: { phase: TEST } " + input_proto;
   const string output_proto_train =
       "name: 'LeNet' "
-      "layers { "
+      "layer { "
       "  name: 'mnist' "
       "  type: 'Data' "
       "  top: 'data' "
@@ -1382,13 +1402,17 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "  } "
       "  include: { phase: TRAIN } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv1' "
       "  type: 'Convolution' "
       "  bottom: 'data' "
       "  top: 'conv1' "
-      "  blobs_lr: 1 "
-      "  blobs_lr: 2 "
+      "  param { "
+      "    lr_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "  } "
       "  convolution_param { "
       "    num_output: 20 "
       "    kernel_size: 5 "
@@ -1401,13 +1425,17 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "    } "
       "  } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'ip1' "
       "  type: 'InnerProduct' "
       "  bottom: 'conv1' "
       "  top: 'ip1' "
-      "  blobs_lr: 1 "
-      "  blobs_lr: 2 "
+      "  param { "
+      "    lr_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "  } "
       "  inner_product_param { "
       "    num_output: 10 "
       "    weight_filler { "
@@ -1418,7 +1446,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "    } "
       "  } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'ip2' "
@@ -1427,7 +1455,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "} ";
   const string& output_proto_test =
       "name: 'LeNet' "
-      "layers { "
+      "layer { "
       "  name: 'mnist' "
       "  type: 'Data' "
       "  top: 'data' "
@@ -1441,13 +1469,17 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "  } "
       "  include: { phase: TEST } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv1' "
       "  type: 'Convolution' "
       "  bottom: 'data' "
       "  top: 'conv1' "
-      "  blobs_lr: 1 "
-      "  blobs_lr: 2 "
+      "  param { "
+      "    lr_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "  } "
       "  convolution_param { "
       "    num_output: 20 "
       "    kernel_size: 5 "
@@ -1460,13 +1492,17 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "    } "
       "  } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'ip1' "
       "  type: 'InnerProduct' "
       "  bottom: 'conv1' "
       "  top: 'ip1' "
-      "  blobs_lr: 1 "
-      "  blobs_lr: 2 "
+      "  param { "
+      "    lr_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "  } "
       "  inner_product_param { "
       "    num_output: 10 "
       "    weight_filler { "
@@ -1477,7 +1513,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "    } "
       "  } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'accuracy' "
       "  type: 'Accuracy' "
       "  bottom: 'ip1' "
@@ -1485,7 +1521,7 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
       "  top: 'accuracy' "
       "  include: { phase: TEST } "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'ip2' "
@@ -1517,20 +1553,20 @@ TEST_F(FilterNetTest, TestFilterLeNetTrainTest) {
 TEST_F(FilterNetTest, TestFilterOutByStage) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "  include: { stage: 'mystage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1538,13 +1574,13 @@ TEST_F(FilterNetTest, TestFilterOutByStage) {
       "} ";
   const string& output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1556,20 +1592,20 @@ TEST_F(FilterNetTest, TestFilterOutByStage) {
 TEST_F(FilterNetTest, TestFilterOutByStage2) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { stage: 'mystage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1577,13 +1613,13 @@ TEST_F(FilterNetTest, TestFilterOutByStage2) {
       "} ";
   const string& output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1596,20 +1632,20 @@ TEST_F(FilterNetTest, TestFilterInByStage) {
   const string& input_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { stage: 'mystage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1621,20 +1657,20 @@ TEST_F(FilterNetTest, TestFilterInByStage) {
 TEST_F(FilterNetTest, TestFilterInByStage2) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  exclude: { stage: 'mystage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1647,20 +1683,20 @@ TEST_F(FilterNetTest, TestFilterOutByMultipleStage) {
   const string& input_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { stage: 'mystage' stage: 'myotherstage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1670,13 +1706,13 @@ TEST_F(FilterNetTest, TestFilterOutByMultipleStage) {
   const string& output_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1690,13 +1726,13 @@ TEST_F(FilterNetTest, TestFilterInByMultipleStage) {
   const string& input_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
@@ -1704,7 +1740,7 @@ TEST_F(FilterNetTest, TestFilterInByMultipleStage) {
       "  include: { stage: 'myotherstage' } "
       "  include: { stage: 'mystage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1718,20 +1754,20 @@ TEST_F(FilterNetTest, TestFilterInByMultipleStage2) {
   const string& input_proto =
       "state: { stage: 'mystage' stage: 'myotherstage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { stage: 'mystage' stage: 'myotherstage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1745,20 +1781,20 @@ TEST_F(FilterNetTest, TestFilterInByNotStage) {
   const string& input_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { not_stage: 'myotherstage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1772,20 +1808,20 @@ TEST_F(FilterNetTest, TestFilterOutByNotStage) {
   const string& input_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { not_stage: 'mystage' } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1795,7 +1831,7 @@ TEST_F(FilterNetTest, TestFilterOutByNotStage) {
   const string& output_proto =
       "state: { stage: 'mystage' } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
@@ -1807,20 +1843,20 @@ TEST_F(FilterNetTest, TestFilterOutByNotStage) {
 TEST_F(FilterNetTest, TestFilterOutByMinLevel) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { min_level: 3 } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1828,13 +1864,13 @@ TEST_F(FilterNetTest, TestFilterOutByMinLevel) {
       "} ";
   const string& output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1846,20 +1882,20 @@ TEST_F(FilterNetTest, TestFilterOutByMinLevel) {
 TEST_F(FilterNetTest, TestFilterOutByMaxLevel) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { max_level: -3 } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1867,13 +1903,13 @@ TEST_F(FilterNetTest, TestFilterOutByMaxLevel) {
       "} ";
   const string& output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1885,20 +1921,20 @@ TEST_F(FilterNetTest, TestFilterOutByMaxLevel) {
 TEST_F(FilterNetTest, TestFilterInByMinLevel) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { min_level: 0 } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1911,20 +1947,20 @@ TEST_F(FilterNetTest, TestFilterInByMinLevel2) {
   const string& input_proto =
       "state: { level: 7 } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { min_level: 3 } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1936,20 +1972,20 @@ TEST_F(FilterNetTest, TestFilterInByMinLevel2) {
 TEST_F(FilterNetTest, TestFilterInByMaxLevel) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { max_level: 0 } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1962,20 +1998,20 @@ TEST_F(FilterNetTest, TestFilterInByMaxLevel2) {
   const string& input_proto =
       "state: { level: -7 } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { max_level: -3 } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -1987,20 +2023,20 @@ TEST_F(FilterNetTest, TestFilterInByMaxLevel2) {
 TEST_F(FilterNetTest, TestFilterInOutByIncludeMultiRule) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  include: { min_level: 2  phase: TRAIN } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -2014,13 +2050,13 @@ TEST_F(FilterNetTest, TestFilterInOutByIncludeMultiRule) {
   const string& output_proto_train =
       "state: { level: 4  phase: TRAIN } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
@@ -2030,13 +2066,13 @@ TEST_F(FilterNetTest, TestFilterInOutByIncludeMultiRule) {
   const string& output_proto_test =
       "state: { level: 4  phase: TEST } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -2050,13 +2086,13 @@ TEST_F(FilterNetTest, TestFilterInOutByIncludeMultiRule) {
 TEST_F(FilterNetTest, TestFilterInByIncludeMultiRule) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
@@ -2064,7 +2100,7 @@ TEST_F(FilterNetTest, TestFilterInByIncludeMultiRule) {
       "  include: { min_level: 2  phase: TRAIN } "
       "  include: { phase: TEST } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -2083,20 +2119,20 @@ TEST_F(FilterNetTest, TestFilterInByIncludeMultiRule) {
 TEST_F(FilterNetTest, TestFilterInOutByExcludeMultiRule) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "  exclude: { min_level: 2  phase: TRAIN } "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -2110,13 +2146,13 @@ TEST_F(FilterNetTest, TestFilterInOutByExcludeMultiRule) {
   const string& output_proto_train =
       "state: { level: 4  phase: TRAIN } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -2126,13 +2162,13 @@ TEST_F(FilterNetTest, TestFilterInOutByExcludeMultiRule) {
   const string& output_proto_test =
       "state: { level: 4  phase: TEST } "
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
index d3f646c..1c2c9bb 100644 (file)
@@ -51,7 +51,7 @@ TYPED_TEST(SolverTest, TestInitTrainTestNets) {
      "test_state: {}"
      "net_param { "
      "  name: 'TestNetwork' "
-     "  layers: { "
+     "  layer { "
      "    name: 'data' "
      "    type: 'DummyData' "
      "    dummy_data_param { "
@@ -67,7 +67,7 @@ TYPED_TEST(SolverTest, TestInitTrainTestNets) {
      "    top: 'data' "
      "    top: 'label' "
      "  } "
-     "  layers: { "
+     "  layer { "
      "    name: 'innerprod' "
      "    type: 'InnerProduct' "
      "    inner_product_param { "
@@ -76,7 +76,7 @@ TYPED_TEST(SolverTest, TestInitTrainTestNets) {
      "    bottom: 'data' "
      "    top: 'innerprod' "
      "  } "
-     "  layers: { "
+     "  layer { "
      "    name: 'accuracy' "
      "    type: 'Accuracy' "
      "    bottom: 'innerprod' "
@@ -84,7 +84,7 @@ TYPED_TEST(SolverTest, TestInitTrainTestNets) {
      "    top: 'accuracy' "
      "    exclude: { phase: TRAIN } "
      "  } "
-     "  layers: { "
+     "  layer { "
      "    name: 'loss' "
      "    type: 'SoftmaxWithLoss' "
      "    bottom: 'innerprod' "
index 584d0a4..be5204b 100644 (file)
@@ -114,19 +114,19 @@ class SplitLayerInsertionTest : public ::testing::Test {
 TEST_F(SplitLayerInsertionTest, TestNoInsertion1) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -138,32 +138,32 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertion1) {
 TEST_F(SplitLayerInsertionTest, TestNoInsertion2) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'data_split' "
       "  type: 'Split' "
       "  bottom: 'data' "
       "  top: 'data_split_0' "
       "  top: 'data_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_split_0' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_split_1' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
@@ -175,7 +175,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertion2) {
 TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
   const string& input_proto =
       "name: 'CaffeNet' "
-      "layers { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  data_param { "
@@ -190,7 +190,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv1' "
       "  type: 'Convolution' "
       "  convolution_param { "
@@ -206,20 +206,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 0. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'data' "
       "  top: 'conv1' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu1' "
       "  type: 'ReLU' "
       "  bottom: 'conv1' "
       "  top: 'conv1' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'pool1' "
       "  type: 'Pooling' "
       "  pooling_param { "
@@ -230,7 +234,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'conv1' "
       "  top: 'pool1' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'norm1' "
       "  type: 'LRN' "
       "  lrn_param { "
@@ -241,7 +245,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'pool1' "
       "  top: 'norm1' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv2' "
       "  type: 'Convolution' "
       "  convolution_param { "
@@ -258,20 +262,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'norm1' "
       "  top: 'conv2' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu2' "
       "  type: 'ReLU' "
       "  bottom: 'conv2' "
       "  top: 'conv2' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'pool2' "
       "  type: 'Pooling' "
       "  pooling_param { "
@@ -282,7 +290,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'conv2' "
       "  top: 'pool2' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'norm2' "
       "  type: 'LRN' "
       "  lrn_param { "
@@ -293,7 +301,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'pool2' "
       "  top: 'norm2' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv3' "
       "  type: 'Convolution' "
       "  convolution_param { "
@@ -309,20 +317,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 0. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'norm2' "
       "  top: 'conv3' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu3' "
       "  type: 'ReLU' "
       "  bottom: 'conv3' "
       "  top: 'conv3' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv4' "
       "  type: 'Convolution' "
       "  convolution_param { "
@@ -339,20 +351,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'conv3' "
       "  top: 'conv4' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu4' "
       "  type: 'ReLU' "
       "  bottom: 'conv4' "
       "  top: 'conv4' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'conv5' "
       "  type: 'Convolution' "
       "  convolution_param { "
@@ -369,20 +385,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'conv4' "
       "  top: 'conv5' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu5' "
       "  type: 'ReLU' "
       "  bottom: 'conv5' "
       "  top: 'conv5' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'pool5' "
       "  type: 'Pooling' "
       "  pooling_param { "
@@ -393,7 +413,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'conv5' "
       "  top: 'pool5' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'fc6' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -407,20 +427,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'pool5' "
       "  top: 'fc6' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu6' "
       "  type: 'ReLU' "
       "  bottom: 'fc6' "
       "  top: 'fc6' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'drop6' "
       "  type: 'Dropout' "
       "  dropout_param { "
@@ -429,7 +453,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'fc6' "
       "  top: 'fc6' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'fc7' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -443,20 +467,24 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'fc6' "
       "  top: 'fc7' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'relu7' "
       "  type: 'ReLU' "
       "  bottom: 'fc7' "
       "  top: 'fc7' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'drop7' "
       "  type: 'Dropout' "
       "  dropout_param { "
@@ -465,7 +493,7 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "  bottom: 'fc7' "
       "  top: 'fc7' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'fc8' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -479,14 +507,18 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
       "      value: 0 "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'fc7' "
       "  top: 'fc8' "
       "} "
-      "layers { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'fc8' "
@@ -498,25 +530,25 @@ TEST_F(SplitLayerInsertionTest, TestNoInsertionImageNet) {
 TEST_F(SplitLayerInsertionTest, TestNoInsertionWithInPlace) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'relu' "
       "  type: 'ReLU' "
       "  bottom: 'innerprod' "
       "  top: 'innerprod' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'SoftmaxWithLoss' "
       "  bottom: 'innerprod' "
@@ -529,7 +561,7 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
   const string& input_proto =
       "name: 'UnsharedWeightsNetwork' "
       "force_backward: true "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'DummyData' "
       "  dummy_data_param { "
@@ -544,7 +576,7 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "  } "
       "  top: 'data' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerproduct1' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -555,12 +587,12 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "      std: 10 "
       "    } "
       "  } "
-      "  param: 'unsharedweights1' "
+      "  param { name: 'unsharedweights1' } "
       "  bottom: 'data' "
       "  top: 'innerproduct1' "
       "  loss_weight: 2.5 "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerproduct2' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -571,11 +603,11 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "      std: 10 "
       "    } "
       "  } "
-      "  param: 'unsharedweights2' "
+      "  param { name: 'unsharedweights2' } "
       "  bottom: 'data' "
       "  top: 'innerproduct2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerproduct1' "
@@ -584,7 +616,7 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
   const string& expected_output_proto =
       "name: 'UnsharedWeightsNetwork' "
       "force_backward: true "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'DummyData' "
       "  dummy_data_param { "
@@ -599,14 +631,14 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "  } "
       "  top: 'data' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'data_data_0_split' "
       "  type: 'Split' "
       "  bottom: 'data' "
       "  top: 'data_data_0_split_0' "
       "  top: 'data_data_0_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerproduct1' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -617,11 +649,11 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "      std: 10 "
       "    } "
       "  } "
-      "  param: 'unsharedweights1' "
+      "  param { name: 'unsharedweights1' } "
       "  bottom: 'data_data_0_split_0' "
       "  top: 'innerproduct1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerproduct1_innerproduct1_0_split' "
       "  type: 'Split' "
       "  bottom: 'innerproduct1' "
@@ -630,7 +662,7 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "  loss_weight: 2.5 "
       "  loss_weight: 0 "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerproduct2' "
       "  type: 'InnerProduct' "
       "  inner_product_param { "
@@ -641,11 +673,11 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
       "      std: 10 "
       "    } "
       "  } "
-      "  param: 'unsharedweights2' "
+      "  param { name: 'unsharedweights2' } "
       "  bottom: 'data_data_0_split_1' "
       "  top: 'innerproduct2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerproduct1_innerproduct1_0_split_1' "
@@ -657,37 +689,37 @@ TEST_F(SplitLayerInsertionTest, TestLossInsertion) {
 TEST_F(SplitLayerInsertionTest, TestInsertion) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod3' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod3' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss1' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
       "  bottom: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss2' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod2' "
@@ -695,13 +727,13 @@ TEST_F(SplitLayerInsertionTest, TestInsertion) {
       "} ";
   const string& expected_output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'data_data_0_split' "
       "  type: 'Split' "
       "  bottom: 'data' "
@@ -709,38 +741,38 @@ TEST_F(SplitLayerInsertionTest, TestInsertion) {
       "  top: 'data_data_0_split_1' "
       "  top: 'data_data_0_split_2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_data_0_split_0' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_data_0_split_1' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2_innerprod2_0_split' "
       "  type: 'Split' "
       "  bottom: 'innerprod2' "
       "  top: 'innerprod2_innerprod2_0_split_0' "
       "  top: 'innerprod2_innerprod2_0_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod3' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_data_0_split_2' "
       "  top: 'innerprod3' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss1' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
       "  bottom: 'innerprod2_innerprod2_0_split_0' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss2' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod2_innerprod2_0_split_1' "
@@ -752,43 +784,43 @@ TEST_F(SplitLayerInsertionTest, TestInsertion) {
 TEST_F(SplitLayerInsertionTest, TestInsertionTwoTop) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'label' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod3' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod3' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod4' "
       "  type: 'InnerProduct' "
       "  bottom: 'label' "
       "  top: 'innerprod4' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss1' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
       "  bottom: 'innerprod3' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss2' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod2' "
@@ -796,57 +828,57 @@ TEST_F(SplitLayerInsertionTest, TestInsertionTwoTop) {
       "} ";
   const string& expected_output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'data_data_0_split' "
       "  type: 'Split' "
       "  bottom: 'data' "
       "  top: 'data_data_0_split_0' "
       "  top: 'data_data_0_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'label_data_1_split' "
       "  type: 'Split' "
       "  bottom: 'label' "
       "  top: 'label_data_1_split_0' "
       "  top: 'label_data_1_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_data_0_split_0' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'label_data_1_split_0' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod3' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_data_0_split_1' "
       "  top: 'innerprod3' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod4' "
       "  type: 'InnerProduct' "
       "  bottom: 'label_data_1_split_1' "
       "  top: 'innerprod4' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss1' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
       "  bottom: 'innerprod3' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss2' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod2' "
@@ -863,19 +895,19 @@ TEST_F(SplitLayerInsertionTest, TestInputInsertion) {
       "input_dim: 3 "
       "input_dim: 227 "
       "input_dim: 227 "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
@@ -888,26 +920,26 @@ TEST_F(SplitLayerInsertionTest, TestInputInsertion) {
       "input_dim: 3 "
       "input_dim: 227 "
       "input_dim: 227 "
-      "layers: { "
+      "layer { "
       "  name: 'data_input_0_split' "
       "  type: 'Split' "
       "  bottom: 'data' "
       "  top: 'data_input_0_split_0' "
       "  top: 'data_input_0_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_input_0_split_0' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_input_0_split_1' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
@@ -919,37 +951,37 @@ TEST_F(SplitLayerInsertionTest, TestInputInsertion) {
 TEST_F(SplitLayerInsertionTest, TestWithInPlace) {
   const string& input_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'relu1' "
       "  type: 'ReLU' "
       "  bottom: 'innerprod1' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'innerprod1' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss1' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1' "
       "  bottom: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss2' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod2' "
@@ -957,51 +989,51 @@ TEST_F(SplitLayerInsertionTest, TestWithInPlace) {
       "} ";
   const string& expected_output_proto =
       "name: 'TestNetwork' "
-      "layers: { "
+      "layer { "
       "  name: 'data' "
       "  type: 'Data' "
       "  top: 'data' "
       "  top: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'data_data_0_split' "
       "  type: 'Split' "
       "  bottom: 'data' "
       "  top: 'data_data_0_split_0' "
       "  top: 'data_data_0_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1' "
       "  type: 'InnerProduct' "
       "  bottom: 'data_data_0_split_0' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'relu1' "
       "  type: 'ReLU' "
       "  bottom: 'innerprod1' "
       "  top: 'innerprod1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod1_relu1_0_split' "
       "  type: 'Split' "
       "  bottom: 'innerprod1' "
       "  top: 'innerprod1_relu1_0_split_0' "
       "  top: 'innerprod1_relu1_0_split_1' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'innerprod2' "
       "  type: 'InnerProduct' "
       "  bottom: 'innerprod1_relu1_0_split_0' "
       "  top: 'innerprod2' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss1' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod1_relu1_0_split_1' "
       "  bottom: 'label' "
       "} "
-      "layers: { "
+      "layer { "
       "  name: 'loss2' "
       "  type: 'EuclideanLoss' "
       "  bottom: 'innerprod2' "
index 8cff961..7094055 100644 (file)
@@ -1302,10 +1302,14 @@ TEST_F(NetUpgradeTest, TestSimple) {
       "      value: 0. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'data' "
       "  top: 'conv1' "
       "} "
@@ -1323,10 +1327,14 @@ TEST_F(NetUpgradeTest, TestSimple) {
       "      value: 0 "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'conv1' "
       "  top: 'fc8' "
       "} "
@@ -2560,10 +2568,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 0. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'data' "
       "  top: 'conv1' "
       "} "
@@ -2612,10 +2624,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'norm1' "
       "  top: 'conv2' "
       "} "
@@ -2663,10 +2679,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 0. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'norm2' "
       "  top: 'conv3' "
       "} "
@@ -2693,10 +2713,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'conv3' "
       "  top: 'conv4' "
       "} "
@@ -2723,10 +2747,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'conv4' "
       "  top: 'conv5' "
       "} "
@@ -2761,10 +2789,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'pool5' "
       "  top: 'fc6' "
       "} "
@@ -2797,10 +2829,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 1. "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'fc6' "
       "  top: 'fc7' "
       "} "
@@ -2833,10 +2869,14 @@ TEST_F(NetUpgradeTest, TestImageNet) {
       "      value: 0 "
       "    } "
       "  } "
-      "  blobs_lr: 1. "
-      "  blobs_lr: 2. "
-      "  weight_decay: 1. "
-      "  weight_decay: 0. "
+      "  param { "
+      "    lr_mult: 1 "
+      "    decay_mult: 1 "
+      "  } "
+      "  param { "
+      "    lr_mult: 2 "
+      "    decay_mult: 0 "
+      "  } "
       "  bottom: 'fc7' "
       "  top: 'fc8' "
       "} "
index 575d7a7..6b401b5 100644 (file)
@@ -659,6 +659,7 @@ bool UpgradeV1Net(const NetParameter& v1_net_param, NetParameter* net_param) {
   }
   net_param->CopyFrom(v1_net_param);
   net_param->clear_layers();
+  net_param->clear_layer();
   for (int i = 0; i < v1_net_param.layers_size(); ++i) {
     if (!UpgradeV1LayerParameter(v1_net_param.layers(i),
                                  net_param->add_layer())) {
@@ -695,27 +696,34 @@ bool UpgradeV1LayerParameter(const V1LayerParameter& v1_layer_param,
     layer_param->add_blobs()->CopyFrom(v1_layer_param.blobs(i));
   }
   for (int i = 0; i < v1_layer_param.param_size(); ++i) {
-    layer_param->add_param(v1_layer_param.param(i));
+    while (layer_param->param_size() <= i) { layer_param->add_param(); }
+    layer_param->mutable_param(i)->set_name(v1_layer_param.param(i));
   }
+  ParamSpec_DimCheckMode mode;
   for (int i = 0; i < v1_layer_param.blob_share_mode_size(); ++i) {
+    while (layer_param->param_size() <= i) { layer_param->add_param(); }
     switch (v1_layer_param.blob_share_mode(i)) {
     case V1LayerParameter_DimCheckMode_STRICT:
-      layer_param->add_param_share_mode(LayerParameter_DimCheckMode_STRICT);
+      mode = ParamSpec_DimCheckMode_STRICT;
       break;
     case V1LayerParameter_DimCheckMode_PERMISSIVE:
-      layer_param->add_param_share_mode(LayerParameter_DimCheckMode_PERMISSIVE);
+      mode = ParamSpec_DimCheckMode_PERMISSIVE;
       break;
     default:
       LOG(FATAL) << "Unknown blob_share_mode: "
                  << v1_layer_param.blob_share_mode(i);
       break;
     }
+    layer_param->mutable_param(i)->set_share_mode(mode);
   }
   for (int i = 0; i < v1_layer_param.blobs_lr_size(); ++i) {
-    layer_param->add_blobs_lr(v1_layer_param.blobs_lr(i));
+    while (layer_param->param_size() <= i) { layer_param->add_param(); }
+    layer_param->mutable_param(i)->set_lr_mult(v1_layer_param.blobs_lr(i));
   }
   for (int i = 0; i < v1_layer_param.weight_decay_size(); ++i) {
-    layer_param->add_weight_decay(v1_layer_param.weight_decay(i));
+    while (layer_param->param_size() <= i) { layer_param->add_param(); }
+    layer_param->mutable_param(i)->set_decay_mult(
+        v1_layer_param.weight_decay(i));
   }
   for (int i = 0; i < v1_layer_param.loss_weight_size(); ++i) {
     layer_param->add_loss_weight(v1_layer_param.loss_weight(i));