void DropoutLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  NeuronLayer<Dtype>::LayerSetUp(bottom, top);
  const DropoutParameter& param = this->layer_param_.dropout_param();
  threshold_ = param.dropout_ratio();
  DCHECK(threshold_ > 0.);
  DCHECK(threshold_ < 1.);
  scale_ = 1. / (1. - threshold_);
  drop_type_ = param.drop_type();
  a_ = param.a();
  b_ = param.b();
  CHECK_LT(a_, b_);
  mu_ = param.mu();
  sigma_ = param.sigma();
  CHECK_GT(sigma_, 0);
  switch (drop_type_){
  case DropoutParameter_DropType_UNIFORM:
	  scale_ = 2. / (b_ + a_);
	  break;
  case DropoutParameter_DropType_GAUSSIAN:
	  scale_ = 1. / mu_;
	  break;
  case DropoutParameter_DropType_BERNOULLI:
	  scale_ = 1. / (1. - threshold_);
	  break;
  default:
	  LOG(FATAL) << "unknown dropout type";
  }
  // layer-wise or element wise dropout parameters
  num_axes_ = param.num_axes() == -1 ? bottom[0]->num_axes() : param.num_axes();
  drop_batch_ = num_axes_ == 0;
  CHECK_LE(num_axes_, bottom[0]->num_axes());
  CHECK_GE(num_axes_, 0);
  if (drop_batch_){
	  vector<int> mask_shape(0);
	  rand_vec_ = new Blob<Dtype>(mask_shape);
  }
  else{
	  vector<int> mask_shape = bottom[0]->shape();
	  mask_shape.resize(num_axes_);
	  //only need [0, ..., axis_] mask variables
	  rand_vec_ = new Blob<Dtype>(mask_shape);
	  LayerParameter scale_param;
	  scale_param.mutable_scale_param()->set_axis(0);
	  scale_param.mutable_scale_param()->set_num_axes(num_axes_);
	  scale_layer_.reset(new ScaleLayer<Dtype>(scale_param));
	  vector<Blob<Dtype>*> scale_bottom(2, NULL);
	  scale_bottom[0] = bottom[0];
	  scale_bottom[1] = rand_vec_;
	  const vector<Blob<Dtype>*> scale_top(1, top[0]);
	  scale_layer_->SetUp(scale_bottom, scale_top);
  }
}
void CmpInnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  const int num_output = this->layer_param_.inner_product_param().num_output();
  bias_term_ = this->layer_param_.inner_product_param().bias_term();
  transpose_ = this->layer_param_.inner_product_param().transpose();
  N_ = num_output;
  const int axis = bottom[0]->CanonicalAxisIndex(
      this->layer_param_.inner_product_param().axis());
  // Dimensions starting from "axis" are "flattened" into a single
  // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W),
  // and axis == 1, N inner products with dimension CHW are performed.
  K_ = bottom[0]->count(axis);
  // Check if we need to set up the weights
  if (this->blobs_.size() > 0) {
    LOG(INFO) << "Skipping parameter initialization";
  } else {
    if (bias_term_) {
      this->blobs_.resize(2);
    } else {
      this->blobs_.resize(1);
    }
    // Initialize the weights
    vector<int> weight_shape(2);
    if (transpose_) {
      weight_shape[0] = K_;
      weight_shape[1] = N_;
    } else {
      weight_shape[0] = N_;
      weight_shape[1] = K_;
    }
    this->blobs_[0].reset(new Blob<Dtype>(weight_shape));
    // fill the weights
    shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>(
        this->layer_param_.inner_product_param().weight_filler()));
    weight_filler->Fill(this->blobs_[0].get());
    // If necessary, intiialize and fill the bias term
    if (bias_term_) {
      vector<int> bias_shape(1, N_);
      this->blobs_[1].reset(new Blob<Dtype>(bias_shape));
      shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>(
          this->layer_param_.inner_product_param().bias_filler()));
      bias_filler->Fill(this->blobs_[1].get());
    }
  }  // parameter initialization
  this->param_propagate_down_.resize(this->blobs_.size(), true);
  
  this->sparse_ratio_ = this->layer_param_.inner_product_param().sparse_ratio();
  this->class_num_ = this->layer_param_.inner_product_param().class_num();
  this->quantize_term_ = this->layer_param_.inner_product_param().quantize_term();
  int count = this->blobs_[0]->count() ; 
  vector<int> mask_shape(1,count);
  this->masks_.Reshape(mask_shape);
  int *mask_data = this->masks_.mutable_cpu_data();
  caffe_set(count, 1, this->masks_.mutable_cpu_data());


  if(quantize_term_)
  {   
    this->indices_.Reshape(mask_shape);
    vector<int> cen_shape(1,class_num_);
    this->centroids_.Reshape(cen_shape);
    this->tmpDiff_.Reshape(cen_shape);
    this->freq_.Reshape(cen_shape);
  } 

}