示例#1
0
void ReshapeLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
    const vector<Blob<Dtype>*>& top) {
  const int input_start_axis = this->layer_param_.reshape_param().axis();
  const int start_axis = (input_start_axis >= 0) ? input_start_axis :
      bottom[0]->num_axes() + input_start_axis + 1;
  CHECK_GE(start_axis, 0) << "axis " << input_start_axis << " out of range";
  CHECK_LE(start_axis, bottom[0]->num_axes()) << "axis " << input_start_axis
      << " out of range for " << bottom[0]->num_axes() << "-D input blob";
  const int num_axes = this->layer_param_.reshape_param().num_axes();
  CHECK_GE(num_axes, -1) << "num_axes must be >= 0, or -1 for all";
  const int end_axis =
      (num_axes == -1) ? bottom[0]->num_axes() : (start_axis + num_axes);
  CHECK_LE(end_axis, bottom[0]->num_axes())
      << "end_axis = axis + num_axes is out of range";
  const int num_axes_replaced = end_axis - start_axis;
  const int num_axes_retained = bottom[0]->num_axes() - num_axes_replaced;
  const BlobShape& top_blob_shape = this->layer_param_.reshape_param().shape();
  const int num_new_axes = top_blob_shape.dim_size();
  vector<int> top_shape(num_axes_retained + num_new_axes);
  int top_shape_index = 0;
  for (int i = 0; i < start_axis; ++i) {
    top_shape[top_shape_index++] = bottom[0]->shape(i);
  }
  for (int i = 0; i < num_new_axes; ++i) {
    top_shape[top_shape_index++] = top_blob_shape.dim(i);
  }
  for (int i = end_axis; i < bottom[0]->num_axes(); ++i) {
    top_shape[top_shape_index++] = bottom[0]->shape(i);
  }
  CHECK_EQ(top_shape_index, top_shape.size());
  for (int i = 0; i < copy_axes_.size(); ++i) {
    const int copy_axis_index = copy_axes_[i];
    CHECK_GT(bottom[0]->num_axes(), start_axis + copy_axis_index)
        << "new shape contains a 0, but there was no corresponding bottom axis "
        << "to copy";
    top_shape[start_axis + copy_axis_index] =
        bottom[0]->shape(start_axis + copy_axis_index);
  }
  if (inferred_axis_ >= 0) {
    // A -1 dim was specified; infer the correct dimension by computing the
    // product of the other dimensions.
    int explicit_count = constant_count_;
    explicit_count *= bottom[0]->count(0, start_axis);
    explicit_count *= bottom[0]->count(end_axis);
    for (int i = 0; i < copy_axes_.size(); ++i) {
      const int copy_axis_index = copy_axes_[i];
      explicit_count *= top_shape[start_axis + copy_axis_index];
    }
    CHECK_EQ(0, bottom[0]->count() % explicit_count) << "bottom count ("
        << bottom[0]->count() << ") must be divisible by the product of "
        << "the specified dimensions (" << explicit_count << ")";
    const int inferred_dim = bottom[0]->count() / explicit_count;
    top_shape[start_axis + inferred_axis_] = inferred_dim;
  }
  top[0]->Reshape(top_shape);
  CHECK_EQ(top[0]->count(), bottom[0]->count())
      << "output count must match input count";
  top[0]->ShareData(*bottom[0]);
  top[0]->ShareDiff(*bottom[0]);
}
示例#2
0
void ReductionLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  axis_ = bottom[0]->CanonicalAxisIndex(
      this->layer_param_.reduction_param().axis());
  // In the output, we'll keep all axes up to the reduction axis, but
  // throw away any after that.
  // Note: currently reducing along non-tail axes is not supported; otherwise,
  // we'd need to also copy any axes following an "end_axis".
  vector<int> top_shape(bottom[0]->shape().begin(),
                        bottom[0]->shape().begin() + axis_);
  top[0]->Reshape(top_shape);
  num_ = bottom[0]->count(0, axis_);
  dim_ = bottom[0]->count(axis_);
  CHECK_EQ(num_, top[0]->count());
  if (op_ == ReductionParameter_ReductionOp_SUM ||
      op_ == ReductionParameter_ReductionOp_MEAN) {
    vector<int> sum_mult_shape(1, dim_);
    sum_multiplier_.Reshape(sum_mult_shape);
    caffe_set(dim_, Dtype(1), sum_multiplier_.mutable_cpu_data());
  }
  coeff_ = this->layer_param().reduction_param().coeff();
  if (op_ == ReductionParameter_ReductionOp_MEAN) {
    coeff_ /= dim_;
  }
}
示例#3
0
void AccuracyLayer<Dtype>::Reshape(
  const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
  CHECK_LE(top_k_, bottom[0]->count() / bottom[1]->count())
      << "top_k must be less than or equal to the number of classes.";
  label_axis_ =
      bottom[0]->CanonicalAxisIndex(this->layer_param_.accuracy_param().axis());
  outer_num_ = bottom[0]->count(0, label_axis_);
  inner_num_ = bottom[0]->count(label_axis_ + 1);
  CHECK_EQ(outer_num_ * inner_num_, bottom[1]->count())
      << "Number of labels must match number of predictions; "
      << "e.g., if label axis == 1 and prediction shape is (N, C, H, W), "
      << "label count (number of labels) must be N*H*W, "
      << "with integer values in {0, 1, ..., C-1}.";
  if (bottom.size() == 3) {
    CHECK_EQ(outer_num_ * inner_num_, bottom[2]->count())
      << "Number of loss weights must match number of label.";
  }
  vector<int> top_shape(0);  // Accuracy is a scalar; 0 axes.
  top[0]->Reshape(top_shape);
  if (top.size() > 1) {
    // Per-class accuracy is a vector; 1 axes.
    vector<int> top_shape_per_class(1);
    top_shape_per_class[0] = bottom[0]->shape(label_axis_);
    top[1]->Reshape(top_shape_per_class);
    nums_buffer_.Reshape(top_shape_per_class);
  }
}
void EvalDetectionLayer<Dtype>::Reshape(
    const vector<Blob<Dtype>*>& bottom, 
    const vector<Blob<Dtype>*>& top) 
{
  int input_count = bottom[0]->count(1); //13*13*125 / 13*13*425 网络输出
  int label_count = bottom[1]->count(1); //30*5      标签 预设30个物体 4边框+1类别
  // outputs: classes, iou, coordinates
  //int tmp_input_count = side_ * side_ * (num_class_ + (1 + 4) * num_object_);
  int tmp_input_count = side_ * side_ * num_object_ *( num_class_ + 4 + 1 ); //13*13*5*25
  // label: isobj, class_label, coordinates
  //int tmp_label_count = side_ * side_ * (1 + 1 + 1 + 4);
  int tmp_label_count = 30 * 5;// 

 // LOG(INFO) << " label[0] : " << bottom[1]->count(0) << "================================";
  
  
  CHECK_EQ(input_count, tmp_input_count);// 确保网络输出 每张图片为 13*13*5*25 大小 
                                         // 13*13个格子,每个格子预测5种边框,每种边框预测 20类概率+4边框参数+1置信度
  CHECK_EQ(label_count, tmp_label_count);// 而标签输入   每张图片为 30*5       大小 30个物体边框,4个边框参数+1个类别标签

   vector<int> top_shape(2, 1);// 两行一列 全1
  //vector<int> top_shape(3, 1);// 三行一列  添加一列 存储mAP
  top_shape[0] = bottom[0]->num();// 图片数量
  //top_shape[1] = num_class_ + side_ * side_ * num_object_ * 4; 
  // 20 + 13*13*5*4 标签 得分 TP FP 
 // top_shape[1] = num_class_ + side_ * side_ * num_object_ * 4 + 1; 
  // 各个类别预测数量,  20类检测数量 + 13*13*5*(label + score + tp + fp) + 该图片mAP
  
   top_shape[1] = side_ * side_ * num_object_ * 4 + 1; 
  // 13*13*5*(label + score + tp + fp) + 该图片mAP
  
  //top_shape[2] = 1;// 添加一列 存储mAP
  top[0]->Reshape(top_shape);

}
void EuclideanAccuracyLayer<Dtype>::Reshape(
  const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {

  batch_size_ = bottom[0]->shape(0);

  CHECK_EQ(batch_size_ , bottom[1]->count())
      << "Number of labels must match number of predictions; ";
  vector<int> top_shape(0);  // Accuracy is a scalar; 0 axes.
  top[0]->Reshape(top_shape);
}
示例#6
0
void MyAccuracyLayer<Dtype>::Reshape(
  const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {

  CHECK_EQ(bottom[0]->num() , bottom[1]->num());
  CHECK_EQ(bottom[0]->channels() , bottom[1]->channels());
  CHECK_EQ(bottom[0]->height() , bottom[1]->height());
  CHECK_EQ(bottom[0]->width() , bottom[1]->width());

  vector<int> top_shape(0);  // Accuracy is a scalar; 0 axes.
  top[0]->Reshape(top_shape);
}
void ContextDataLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
 
  // Initialize with the first blob.
  vector<int> top_shape(2);
  
  top_shape[0] = bottom[0]->shape(0);
  top_shape[1] = bottom[1]->shape(1);
  top[0]->Reshape(top_shape);   //1x500 the context vector input to the lstm2
  //CHECK_EQ(bottom_count_sum, top[0]->count());
}
示例#8
0
void LastRowLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
	CHECK_EQ(3, bottom[0]->num_axes());
	vector<int> top_shape(3);

	top_shape[0] = bottom[0]->shape(1);
	top_shape[1] = 1;
	top_shape[2] = bottom[0]->shape(2);

	top[0]->Reshape(top_shape);
	
}
示例#9
0
void AccuracyLayer<Dtype>::Reshape(
    const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
    CHECK_LE(top_k_, bottom[0]->count() / bottom[1]->count())
            << "top_k must be less than or equal to the number of classes.";
    CHECK_GE(bottom[0]->num_axes(), bottom[1]->num_axes());
    for (int i = 0; i < bottom[1]->num_axes(); ++i) {
        CHECK_LE(bottom[0]->shape(i), bottom[1]->shape(i))
                << "Dimension mismatch between predictions and label.";
    }
    vector<int> top_shape(0);  // Accuracy is a scalar; 0 axes.
    top[0]->Reshape(top_shape);
}
void SparseInnerProductLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  // The top shape will M_ * N_
  vector<int> top_shape(2, M_);
  top_shape[1] = N_;
  top[0]->Reshape(top_shape);
  // Set up the bias multiplier
  if (bias_term_) {
    vector<int> bias_shape(1, M_);
    bias_multiplier_.Reshape(bias_shape);
    caffe_set(M_, Dtype(1), bias_multiplier_.mutable_cpu_data());
  }
}
示例#11
0
void MultiClassAccuracyLayer<Dtype>::Reshape(
  const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
  label_axis_ =
      bottom[0]->CanonicalAxisIndex(this->layer_param_.accuracy_param().axis());
  vector<int> top_shape(0);  // Accuracy is a scalar; 0 axes.
  top[0]->Reshape(top_shape);
  top[1]->Reshape(top_shape);
  top[2]->Reshape(top_shape);
  top[3]->Reshape(top_shape);
  top[4]->Reshape(top_shape);
  CHECK_EQ(bottom[0]->count(), bottom[1]->count());
  this->threshold_ = this->layer_param_.accuracy_param().bag_threshold();
}
示例#12
0
void Pooling3DLayer<Dtype>::Reshape(const vector<Blob<Dtype> *> &bottom, const vector<Blob<Dtype> *> &top)
{
    CHECK_EQ(5, bottom[0]->num_axes()) << "Input must have 5 axes, "
                                       << "corresponding to (num, channels, length, height, width)";
    int num = bottom[0]->shape()[0];
    int vv[5] = {num, channels_, pooled_length_, pooled_height_, pooled_width_};
    vector<int> top_shape(vv, vv+5);
    top[0]->Reshape(top_shape);

    // If stochastic pooling, we will initialize the random index part.
    if (this->layer_param_.pooling3d_param().pool() ==
        Pooling3DParameter_PoolMethod_STOCHASTIC) {
      rand_idx_.Reshape(top_shape);
    }
}
示例#13
0
void ConvolutionLayerSpatial<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
                                             const vector<Blob<Dtype>*>& top) {
  BaseConvolutionLayer<Dtype>::Reshape(bottom, top);
  height_ = bottom[0]->shape(this->channel_axis_ + 1);
  width_ = bottom[0]->shape(this->channel_axis_ + 2);
  output_h_ = (height_ + 2 * pad_h_ - kernel_h_) / stride_h_ + 1;
  output_w_ = (width_ + 2 * pad_w_ - kernel_w_) / stride_w_ + 1;
  padded_width_ = width_ + 2 * pad_w_;
  padded_height_ = height_ + 2 * pad_h_;

  // Shape the tops.
  vector<int_tp> top_shape(bottom[0]->shape().begin(),
                           bottom[0]->shape().begin() + this->channel_axis_);
  top_shape.push_back(this->num_output_);
  for (int_tp i = 0; i < this->num_spatial_axes_; ++i) {
    top_shape.push_back(this->output_shape_[i]);
  }

  for (int_tp top_id = 0; top_id < top.size(); ++top_id) {
    top[top_id]->Reshape(top_shape);
  }

  CHECK_EQ(2, this->num_spatial_axes_)
    << "ConvolutionSpatial input must have 2 spatial axes "
    << "(e.g., height and width). ";

  const int_tp height_out = top[0]->shape(this->channel_axis_ + 1);
  const int_tp width_out = top[0]->shape(this->channel_axis_ + 2);
  N_ = height_out * width_out;
  // The im2col result buffer will only hold one image at a time to avoid
  // overly large memory usage.
  spatial_col_buffer_.Reshape(this->num_, this->channels_, height_ + 2 * pad_h_,
                      width_ + 2 * pad_w_);
  swizzled_weights_.Reshape(this->num_output_, this->channels_,
                            kernel_h_ + 2 * pad_h_, kernel_w_ + 2 * pad_w_);
  // Set up the all ones "bias multiplier" for adding biases by BLAS
  if (this->bias_term_) {
    bias_multiplier_.Reshape(1, 1, 1, N_);
    caffe_set(N_, Dtype(1), bias_multiplier_.mutable_cpu_data());
  }

  if (std::is_same<Dtype, float>::value) {
    this->num_ = bottom[0]->count(0, this->channel_axis_);
    SetUp(bottom, top, Caffe::GetDefaultDevice()->backend());
  }
}
void AccuracyLayer<Dtype>::Reshape(
  const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
  CHECK_LE(top_k_, bottom[0]->count() / bottom[1]->count())
      << "top_k must be less than or equal to the number of classes.";
  label_axis_ =
      bottom[0]->CanonicalAxisIndex(this->layer_param_.accuracy_param().axis());
  outer_num_ = bottom[0]->count(0, label_axis_);
  inner_num_ = bottom[0]->count(label_axis_ + 1);
  CHECK_EQ(outer_num_ * inner_num_, bottom[1]->count())
      << "Number of labels must match number of predictions; "
      << "e.g., if label axis == 1 and prediction shape is (N, C, H, W), "
      << "label count (number of labels) must be N*H*W, "
      << "with integer values in {0, 1, ..., C-1}.";
  //vector<int> top_shape(0);  // Accuracy is a scalar; 0 axes.
  vector<int> top_shape(1);
  top_shape[0] = 7;
  top[0]->Reshape(top_shape);
}
示例#15
0
  void PermuteLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
                                       const vector<Blob<Dtype>*>& top) {
    PermuteParameter permute_param = this->layer_param_.permute_param();
    CHECK_EQ(bottom.size(), 1);
    num_axes_ = bottom[0]->num_axes();
    vector<int> orders;
    // Push the specified new orders.
    for (int i = 0; i < permute_param.order_size(); ++i) {
      int order = permute_param.order(i);
      CHECK_LT(order, num_axes_)
        << "order should be less than the input dimension.";
      if (std::find(orders.begin(), orders.end(), order) != orders.end()) {
        LOG(FATAL) << "there are duplicate orders";
      }
      orders.push_back(order);
    }
    // Push the rest orders. And save original step sizes for each axis.
    for (int i = 0; i < num_axes_; ++i) {
      if (std::find(orders.begin(), orders.end(), i) == orders.end()) {
        orders.push_back(i);
      }
    }
    CHECK_EQ(num_axes_, orders.size());
    // Check if we need to reorder the data or keep it.
    need_permute_ = false;
    for (int i = 0; i < num_axes_; ++i) {
      if (orders[i] != i) {
        // As long as there is one order which is different from the natural order
        // of the data, we need to permute. Otherwise, we share the data and diff.
        need_permute_ = true;
        break;
      }
    }

    vector<int> top_shape(num_axes_, 1);
    permute_order_.Reshape(num_axes_, 1, 1, 1);
    old_steps_.Reshape(num_axes_, 1, 1, 1);
    new_steps_.Reshape(num_axes_, 1, 1, 1);
    for (int i = 0; i < num_axes_; ++i) {
      permute_order_.mutable_cpu_data()[i] = orders[i];
      top_shape[i] = bottom[0]->shape(orders[i]);
    }
    top[0]->Reshape(top_shape);
  }
示例#16
0
void ReformLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, 
    const vector<Blob<Dtype>*>& top) {

    CHECK_EQ(bottom[0]->shape(2), bottom[0]->shape(3)) << "only support square for now";
    const BlobShape& tbs = this->layer_param_.reform_param().shape();
    const int top_num_axes = tbs.dim_size();
    vector<int> patch_dim(top_num_axes);
    patch_dim[0] = 1;
    patch_dim[1] = 1;
    patch_dim[2] = patch_size_;
    patch_dim[3] = patch_size_;
    top_shape_ = vector<int>(top_num_axes,0);
    int top_shape_index = 0;
    vector<int> top_shape(top_num_axes, 0);
    for (int i = 0; i < top_num_axes; ++i) {
        top_shape_[top_shape_index++] = tbs.dim(i) * patch_dim[i];
    }
    top[0]->Reshape(top_shape_);
    CHECK_EQ(top[0]->shape(0), 1)<<"1";
    CHECK_EQ(top[0]->shape(1), 2)<<"2";
    CHECK_EQ(top[0]->shape(2), 384)<<"3";
    CHECK_EQ(top[0]->shape(3), 512)<<"4";
}
示例#17
0
void BaseConvolutionLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
	if (is_direct_connect_ && !is_direct_intialized_)
	{
		direct_num_ = std::min((int)((direct_ratio_)*(num_output_ / (1 - direct_ratio_))), bottom[0]->channels());
		this->blobs_.push_back(shared_ptr<Blob<Dtype> >());
		vector<int> idx_shape;
		idx_shape.push_back(direct_num_);
		int idx_param_idx = this->blobs_.size() - 1;
		this->blobs_[idx_param_idx].reset(new Blob<Dtype>(idx_shape));

		vector<int> idx_tmp;
		for (int i = 0; i < bottom[0]->channels(); i++)
			idx_tmp.push_back(i);
		std::random_shuffle(idx_tmp.begin(), idx_tmp.end());
		for (int i = 0; i < direct_num_; i++)
			//direct_idx_.push_back(idx_tmp[i]);
			this->blobs_[idx_param_idx]->mutable_cpu_data()[i] = idx_tmp[i];
		is_direct_intialized_ = true;
	}

  const int first_spatial_axis = channel_axis_ + 1;
  CHECK_EQ(bottom[0]->num_axes(), first_spatial_axis + num_spatial_axes_)
      << "bottom num_axes may not change.";
  num_ = bottom[0]->count(0, channel_axis_);
  CHECK_EQ(bottom[0]->shape(channel_axis_), channels_)
      << "Input size incompatible with convolution kernel.";
  // TODO: generalize to handle inputs of different shapes.
  for (int bottom_id = 1; bottom_id < bottom.size(); ++bottom_id) {
    CHECK(bottom[0]->shape() == bottom[bottom_id]->shape())
        << "All inputs must have the same shape.";
  }
  // Shape the tops.
  bottom_shape_ = &bottom[0]->shape();
  compute_output_shape();
  vector<int> top_shape(bottom[0]->shape().begin(),
      bottom[0]->shape().begin() + channel_axis_);
  if (is_direct_connect_)
	  top_shape.push_back(num_output_ + direct_num_);
  else
  top_shape.push_back(num_output_);
  for (int i = 0; i < num_spatial_axes_; ++i) {
    top_shape.push_back(output_shape_[i]);
  }
  for (int top_id = 0; top_id < top.size(); ++top_id) {
    top[top_id]->Reshape(top_shape);
  }
  if (reverse_dimensions()) {
    conv_out_spatial_dim_ = bottom[0]->count(first_spatial_axis);
  } else {
    conv_out_spatial_dim_ = top[0]->count(first_spatial_axis);
  }
  col_offset_ = kernel_dim_ * conv_out_spatial_dim_;
  output_offset_ = conv_out_channels_ * conv_out_spatial_dim_ / group_;
  // Setup input dimensions (conv_input_shape_).
  vector<int> bottom_dim_blob_shape(1, num_spatial_axes_ + 1);
  conv_input_shape_.Reshape(bottom_dim_blob_shape);
  int* conv_input_shape_data = conv_input_shape_.mutable_cpu_data();
  for (int i = 0; i < num_spatial_axes_ + 1; ++i) {
    if (reverse_dimensions()) {
      conv_input_shape_data[i] = top[0]->shape(channel_axis_ + i);
    } else {
      conv_input_shape_data[i] = bottom[0]->shape(channel_axis_ + i);
    }
  }
  // The im2col result buffer will only hold one image at a time to avoid
  // overly large memory usage. In the special case of 1x1 convolution
  // it goes lazily unused to save memory.
  col_buffer_shape_.clear();
  col_buffer_shape_.push_back(kernel_dim_ * group_);
  for (int i = 0; i < num_spatial_axes_; ++i) {
    if (reverse_dimensions()) {
      col_buffer_shape_.push_back(input_shape(i + 1));
    } else {
      col_buffer_shape_.push_back(output_shape_[i]);
    }
  }
  col_buffer_.Reshape(col_buffer_shape_);
  bottom_dim_ = bottom[0]->count(channel_axis_);
  if (is_direct_connect_)
	  top_dim_ = top[0]->count(channel_axis_) * num_output_ / (direct_num_ + num_output_);
  else
  top_dim_ = top[0]->count(channel_axis_);
  num_kernels_im2col_ = conv_in_channels_ * conv_out_spatial_dim_;
  num_kernels_col2im_ = reverse_dimensions() ? top_dim_ : bottom_dim_;
  // Set up the all ones "bias multiplier" for adding biases by BLAS
  out_spatial_dim_ = top[0]->count(first_spatial_axis);
  if (bias_term_) {
    vector<int> bias_multiplier_shape(1, out_spatial_dim_);
    bias_multiplier_.Reshape(bias_multiplier_shape);
    caffe_set(bias_multiplier_.count(), Dtype(1),
        bias_multiplier_.mutable_cpu_data());
  }
}
示例#18
0
void BaseConvolutionLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
                                          const vector<Blob<Dtype>*>& top) {
  const int_tp first_spatial_axis = channel_axis_ + 1;
  CHECK_EQ(bottom[0]->num_axes(), first_spatial_axis + num_spatial_axes_)
    << "bottom num_axes may not change.";
  num_ = bottom[0]->count(0, channel_axis_);
  CHECK_EQ(bottom[0]->shape(channel_axis_), channels_)
    << "Input size incompatible with convolution kernel.";
  // TODO: generalize to handle inputs of different shapes.
  for (int_tp bottom_id = 1; bottom_id < bottom.size(); ++bottom_id) {
    CHECK(bottom[0]->shape() == bottom[bottom_id]->shape())
        << "All inputs must have the same shape.";
  }
  // Shape the tops.
  bottom_shape_ = &bottom[0]->shape();
  compute_output_shape();
  vector<int_tp> top_shape(bottom[0]->shape().begin(),
                        bottom[0]->shape().begin() + channel_axis_);
  top_shape.push_back(num_output_);
  for (int_tp i = 0; i < num_spatial_axes_; ++i) {
    top_shape.push_back(output_shape_[i]);
  }
  for (int_tp top_id = 0; top_id < top.size(); ++top_id) {
    top[top_id]->Reshape(top_shape);
  }
  if (reverse_dimensions()) {
    conv_out_spatial_dim_ = bottom[0]->count(first_spatial_axis);
  } else {
    conv_out_spatial_dim_ = top[0]->count(first_spatial_axis);
  }
  col_offset_ = kernel_dim_ * conv_out_spatial_dim_;
  output_offset_ = conv_out_channels_ * conv_out_spatial_dim_ / group_;
  // Setup input dimensions (conv_input_shape_).
  vector<int_tp> bottom_dim_blob_shape(1, num_spatial_axes_ + 1);
  conv_input_shape_.Reshape(bottom_dim_blob_shape);
  int_tp* conv_input_shape_data = conv_input_shape_.mutable_cpu_data();
  for (int_tp i = 0; i < num_spatial_axes_ + 1; ++i) {
    if (reverse_dimensions()) {
      conv_input_shape_data[i] = top[0]->shape(channel_axis_ + i);
    } else {
      conv_input_shape_data[i] = bottom[0]->shape(channel_axis_ + i);
    }
  }
  // The im2col result buffer will only hold one image at a time to avoid
  // overly large memory usage. In the special case of 1x1 convolution
  // it goes lazily unused to save memory.

  col_buffer_shape_.clear();
  col_buffer_shape_.push_back(kernel_dim_ * group_);
  for (int_tp i = 0; i < num_spatial_axes_; ++i) {
    if (reverse_dimensions()) {
      col_buffer_shape_.push_back(input_shape(i + 1));
    } else {
      col_buffer_shape_.push_back(output_shape_[i]);
    }
  }

  col_buffer_.Reshape(col_buffer_shape_);
  if (Caffe::mode() == Caffe::Brew::GPU) {
    // Shared column buffer per device-queue across all layers on that device
    for (int_tp i = 0; i < this->device_->num_queues(); ++i) {
      shared_ptr<Blob<Dtype> > buffer = this->device_
          ->template Buffer<Dtype>(i);
      buffer->Reshape(col_buffer_shape_);
    }
  }

  bottom_dim_ = bottom[0]->count(channel_axis_);
  top_dim_ = top[0]->count(channel_axis_);
  num_kernels_im2col_ = conv_in_channels_ * conv_out_spatial_dim_;
  num_kernels_col2im_ = reverse_dimensions() ? top_dim_ : bottom_dim_;

  // Set up the all ones "bias multiplier" for adding biases by BLAS
  out_spatial_dim_ = top[0]->count(first_spatial_axis);
  if (bias_term_) {
    vector<int_tp> bias_multiplier_shape(1, out_spatial_dim_);
    bool reshaped = bias_multiplier_.Reshape(bias_multiplier_shape);
    // This will trigger a memory copy if in GPU mode,
    // which may not be necessary.
    // Thus omit to set the values if not necessary.
    if (reshaped) {
      caffe_set(bias_multiplier_.count(), Dtype(1),
                bias_multiplier_.mutable_cpu_data());
    }
  }
}
示例#19
0
void BaseConvolutionLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  const int num_axes = bottom[0]->num_axes();
  // Setting forced_3d_ in LayerSetup() alone is not sufficient as that can be
  // skipped and Reshape() is directed called.
  if (num_axes == 5 && channel_axis_ == 1 && bottom[0]->shape(2) == 1) {
    forced_3d_ = true;
  } else {
    forced_3d_ = false;
  }
  const int first_spatial_axis = channel_axis_ + 1 + forced_3d_;
  CHECK_EQ(num_axes, first_spatial_axis + num_spatial_axes_)
      << "bottom num_axes may not change.";
  num_ = bottom[0]->count(0, channel_axis_);
  CHECK_EQ(bottom[0]->shape(channel_axis_), channels_)
      << "Input size incompatible with convolution kernel.";
  // TODO: generalize to handle inputs of different shapes.
  for (int bottom_id = 1; bottom_id < bottom.size(); ++bottom_id) {
    CHECK(bottom[0]->shape() == bottom[bottom_id]->shape())
        << "shape mismatch - bottom[0]: " << bottom[0]->shape_string()
        << " vs. bottom[" << bottom_id << "]: "
        << bottom[bottom_id]->shape_string();
  }
  // Shape the tops.
  bottom_shape_ = &bottom[0]->shape();
  compute_output_shape();
  vector<int> top_shape(bottom[0]->shape().begin(),
      bottom[0]->shape().begin() + channel_axis_);
  top_shape.push_back(num_output_);
  if (forced_3d_)
    top_shape.push_back(1);  // in place of length
  for (int i = 0; i < num_spatial_axes_; ++i) {
    top_shape.push_back(output_shape_[i]);
  }
  for (int top_id = 0; top_id < top.size(); ++top_id) {
    top[top_id]->Reshape(top_shape);
  }
  if (reverse_dimensions()) {
    conv_out_spatial_dim_ = bottom[0]->count(first_spatial_axis);
  } else {
    conv_out_spatial_dim_ = top[0]->count(first_spatial_axis);
  }
  col_offset_ = kernel_dim_ * conv_out_spatial_dim_;
  output_offset_ = conv_out_channels_ * conv_out_spatial_dim_ / group_;
  // Setup input dimensions (conv_input_shape_).
  vector<int> bottom_dim_blob_shape(1, num_spatial_axes_ + 1);
  conv_input_shape_.Reshape(bottom_dim_blob_shape);
  int* conv_input_shape_data = conv_input_shape_.mutable_cpu_data();
  for (int i = 0; i < num_spatial_axes_ + 1; ++i) {
    if (reverse_dimensions()) {
      conv_input_shape_data[i] = top[0]->shape(channel_axis_ + i + forced_3d_);
    } else {
      conv_input_shape_data[i] = bottom[0]->shape(channel_axis_ + i +
          forced_3d_);
    }
  }
  // The im2col result buffer will only hold one image at a time to avoid
  // overly large memory usage. In the special case of 1x1 convolution
  // it goes lazily unused to save memory.
  col_buffer_shape_.clear();
  col_buffer_shape_.push_back(kernel_dim_ * group_);
  for (int i = 0; i < num_spatial_axes_; ++i) {
    if (reverse_dimensions()) {
      col_buffer_shape_.push_back(input_shape(i + 1));
    } else {
      col_buffer_shape_.push_back(output_shape_[i]);
    }
  }
  col_buffer_.Reshape(col_buffer_shape_);
  bottom_dim_ = bottom[0]->count(channel_axis_);
  top_dim_ = top[0]->count(channel_axis_);
  num_kernels_im2col_ = conv_in_channels_ * conv_out_spatial_dim_;
  num_kernels_col2im_ = reverse_dimensions() ? top_dim_ : bottom_dim_;
  // Set up the all ones "bias multiplier" for adding biases by BLAS
  out_spatial_dim_ = top[0]->count(first_spatial_axis);
  if (bias_term_) {
    vector<int> bias_multiplier_shape(1, out_spatial_dim_);
    bias_multiplier_.Reshape(bias_multiplier_shape);
    caffe_set(bias_multiplier_.count(), Dtype(1),
        bias_multiplier_.mutable_cpu_data());
  }
}
示例#20
0
void ReshapeOp::Forward() {
  const auto *bottom = bottoms<float>(0);
  auto *top = mutable_tops<float>(0);

  CHECK_NE(bottom, top);

  int inferred_axis = -1, constant_count = 1;
  VecInt copy_axes;
  for (int d = 0; d < shape_.size(); ++d) {
    int top_dim = shape_[d];
    if (top_dim == 0) {
      copy_axes.push_back(d);
    } else if (top_dim == -1) {
      CHECK_EQ(inferred_axis, -1);
      inferred_axis = d;
    } else {
      constant_count *= top_dim;
    }
  }

  int start_axis = (axis_ >= 0) ? axis_ : (bottom->num_axes() + axis_ + 1);
  CHECK_GE(start_axis, 0);
  CHECK_LE(start_axis, bottom->num_axes());
  int end_axis =
      (num_axes_ == -1) ? bottom->num_axes() : (start_axis + num_axes_);
  CHECK_LE(end_axis, bottom->num_axes());
  int num_axes_replaced = end_axis - start_axis;
  int num_axes_retained = bottom->num_axes() - num_axes_replaced;

  VecInt top_shape(num_axes_retained + shape_.size());
  int top_shape_index = 0;
  for (int d = 0; d < start_axis; ++d) {
    top_shape[top_shape_index++] = bottom->shape(d);
  }
  for (auto dim : shape_) {
    top_shape[top_shape_index++] = dim;
  }
  for (int d = end_axis; d < bottom->num_axes(); ++d) {
    top_shape[top_shape_index++] = bottom->shape(d);
  }
  CHECK_EQ(top_shape_index, top_shape.size());

  for (auto d : copy_axes) {
    CHECK_GT(bottom->num_axes(), start_axis + d);
    top_shape[start_axis + d] = bottom->shape(start_axis + d);
  }

  if (inferred_axis >= 0) {
    int explicit_count = constant_count;
    explicit_count *= bottom->count(0, start_axis);
    explicit_count *= bottom->count(end_axis);
    for (auto d : copy_axes) {
      explicit_count *= top_shape[start_axis + d];
    }
    CHECK_EQ(0, bottom->count() % explicit_count);
    top_shape[start_axis + inferred_axis] = bottom->count() / explicit_count;
  }

  top->clear();
  top->set_shape(top_shape);
  CHECK_EQ(top->count(), bottom->count());

  top->share_data(*bottom);
}