| 10 | |
| 11 | template <typename Dtype> |
| 12 | void ScaleLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, |
| 13 | const vector<Blob<Dtype>*>& top) { |
| 14 | const ScaleParameter& param = this->layer_param_.scale_param(); |
| 15 | if (bottom.size() == 1 && this->blobs_.size() > 0) { |
| 16 | LOG(INFO) << "Skipping parameter initialization"; |
| 17 | } else if (bottom.size() == 1) { |
| 18 | // scale is a learned parameter; initialize it |
| 19 | axis_ = bottom[0]->CanonicalAxisIndex(param.axis()); |
| 20 | const int num_axes = param.num_axes(); |
| 21 | CHECK_GE(num_axes, -1) << "num_axes must be non-negative, " |
| 22 | << "or -1 to extend to the end of bottom[0]"; |
| 23 | if (num_axes >= 0) { |
| 24 | CHECK_GE(bottom[0]->num_axes(), axis_ + num_axes) |
| 25 | << "scale blob's shape extends past bottom[0]'s shape when applied " |
| 26 | << "starting with bottom[0] axis = " << axis_; |
| 27 | } |
| 28 | this->blobs_.resize(1); |
| 29 | const vector<int>::const_iterator& shape_start = |
| 30 | bottom[0]->shape().begin() + axis_; |
| 31 | const vector<int>::const_iterator& shape_end = |
| 32 | (num_axes == -1) ? bottom[0]->shape().end() : (shape_start + num_axes); |
| 33 | vector<int> scale_shape(shape_start, shape_end); |
| 34 | this->blobs_[0].reset(new Blob<Dtype>(scale_shape)); |
| 35 | FillerParameter filler_param(param.filler()); |
| 36 | if (!param.has_filler()) { |
| 37 | // Default to unit (1) filler for identity operation. |
| 38 | filler_param.set_type("constant"); |
| 39 | filler_param.set_value(1); |
| 40 | } |
| 41 | shared_ptr<Filler<Dtype> > filler(GetFiller<Dtype>(filler_param)); |
| 42 | filler->Fill(this->blobs_[0].get()); |
| 43 | } |
| 44 | if (param.bias_term()) { |
| 45 | LayerParameter layer_param(this->layer_param_); |
| 46 | layer_param.set_type("Bias"); |
| 47 | BiasParameter* bias_param = layer_param.mutable_bias_param(); |
| 48 | bias_param->set_axis(param.axis()); |
| 49 | if (bottom.size() > 1) { |
| 50 | bias_param->set_num_axes(bottom[1]->num_axes()); |
| 51 | } else { |
| 52 | bias_param->set_num_axes(param.num_axes()); |
| 53 | } |
| 54 | bias_param->mutable_filler()->CopyFrom(param.bias_filler()); |
| 55 | bias_layer_ = LayerRegistry<Dtype>::CreateLayer(layer_param); |
| 56 | bias_bottom_vec_.resize(1); |
| 57 | bias_bottom_vec_[0] = bottom[0]; |
| 58 | bias_layer_->SetUp(bias_bottom_vec_, top); |
| 59 | if (this->blobs_.size() + bottom.size() < 3) { |
| 60 | // case: blobs.size == 1 && bottom.size == 1 |
| 61 | // or blobs.size == 0 && bottom.size == 2 |
| 62 | bias_param_id_ = this->blobs_.size(); |
| 63 | this->blobs_.resize(bias_param_id_ + 1); |
| 64 | this->blobs_[bias_param_id_] = bias_layer_->blobs()[0]; |
| 65 | } else { |
| 66 | // bias param already initialized |
| 67 | bias_param_id_ = this->blobs_.size() - 1; |
| 68 | bias_layer_->blobs()[0] = this->blobs_[bias_param_id_]; |
| 69 | } |