|
7 | 7 | namespace caffe { |
8 | 8 |
|
9 | 9 | template <typename Dtype> |
10 | | -void UnstackLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, |
11 | | - const vector<Blob<Dtype>*>& top) { |
12 | | - const UnstackParameter& unstack_param = this->layer_param_.unstack_param(); |
| 10 | +void UnstackLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype> *> &bottom, |
| 11 | + const vector<Blob<Dtype> *> &top) { |
| 12 | + const UnstackParameter &unstack_param = this->layer_param_.unstack_param(); |
13 | 13 | unstack_axis_ = bottom[0]->CanonicalAxisIndex(unstack_param.axis()); |
14 | | - const int num = unstack_param.num(); |
15 | | - if (num != 0) { |
16 | | - CHECK_EQ(num, bottom[0]->shape(unstack_axis_)) |
17 | | - << "num should equal to the shape in axis!"; |
18 | | - } |
19 | | - unstack_num_ = bottom[0]->shape(unstack_axis_); |
20 | | - CHECK_EQ(unstack_num_, top.size())<< "Number of top blobs (" |
21 | | - << top.size() << ") should euqal to "<< "shape in axis (" |
22 | | - << unstack_num_ << ")"; |
| 14 | + unstack_num_ = unstack_param.num(); |
| 15 | + if (unstack_num_ == 0) |
| 16 | + unstack_num_ = bottom[0]->shape(unstack_axis_); |
23 | 17 | } |
24 | 18 |
|
25 | 19 | template <typename Dtype> |
26 | | -void UnstackLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, |
27 | | - const vector<Blob<Dtype>*>& top) { |
28 | | - const int num_axes = bottom[0]->num_axes(); |
29 | | - //const UnstackParameter& unstack_param = this->layer_param_.unstack_param(); |
30 | | - vector<int> bottom_shape = bottom[0]->shape(); |
| 20 | +void UnstackLayer<Dtype>::Reshape(const vector<Blob<Dtype> *> &bottom, |
| 21 | + const vector<Blob<Dtype> *> &top) { |
| 22 | + // const UnstackParameter& unstack_param = this->layer_param_.unstack_param(); |
31 | 23 | vector<int> top_shape = bottom[0]->shape(); |
32 | | - top_shape.resize(num_axes - 1); |
33 | | - num_unstack_ = bottom[0]->count(0, unstack_axis_); |
34 | | - unstack_size_ = bottom[0]->count(unstack_axis_ + 1); |
35 | | - int count = 0; |
36 | | - for (int i = unstack_axis_; i < num_axes - 1; ++i) { |
37 | | - top_shape[i] = bottom_shape[i + 1]; |
38 | | - } |
39 | | - for (int i = 0; i < top.size(); ++i) { |
40 | | - top[i]->Reshape(top_shape); |
41 | | - count += top[i]->count(); |
42 | | - } |
43 | | - CHECK_EQ(count, bottom[0]->count()); |
44 | | - if (top.size() == 1) { |
45 | | - top[0]->ShareData(*bottom[0]); |
46 | | - top[0]->ShareDiff(*bottom[0]); |
47 | | - } |
| 24 | + top_shape.erase(top_shape.begin() + unstack_axis_); |
| 25 | + for (int i = 0; i < top.size(); ++i) |
| 26 | + top[i]->Reshape(top_shape); |
48 | 27 | } |
49 | 28 |
|
50 | 29 | template <typename Dtype> |
51 | | -void UnstackLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, |
52 | | - const vector<Blob<Dtype>*>& top) { |
53 | | - if (top.size() == 1) { return; } |
54 | | - int offset_unstack_axis = 0; |
55 | | - const Dtype* bottom_data = bottom[0]->cpu_data(); |
56 | | - const int bottom_unstack_axis = bottom[0]->shape(unstack_axis_); |
| 30 | +void UnstackLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype> *> &bottom, |
| 31 | + const vector<Blob<Dtype> *> &top) { |
| 32 | + const Dtype *bottom_data = bottom[0]->cpu_data(); |
| 33 | + const int size_unstack_axis = bottom[0]->shape(unstack_axis_); |
| 34 | + vector<int> bottom_shape = bottom[0]->shape(); |
| 35 | + int strides = 1; |
| 36 | + for (int i = unstack_axis_ + 1; i < bottom_shape.size(); i++) |
| 37 | + strides *= bottom_shape[i]; |
| 38 | + int num_unstack_ = bottom[0]->count() / strides / size_unstack_axis; |
| 39 | + // num_unstack_ /= size_unstack_axis; |
57 | 40 | for (int i = 0; i < top.size(); ++i) { |
58 | | - Dtype* top_data = top[i]->mutable_cpu_data(); |
| 41 | + Dtype *top_data = top[i]->mutable_cpu_data(); |
59 | 42 | for (int n = 0; n < num_unstack_; ++n) { |
60 | | - const int top_offset = n * unstack_size_; |
61 | | - const int bottom_offset = |
62 | | - (n * bottom_unstack_axis + offset_unstack_axis) * unstack_size_; |
63 | | - caffe_copy(unstack_size_, |
64 | | - bottom_data + bottom_offset, top_data + top_offset); |
| 43 | + const int top_offset = n * strides; |
| 44 | + const int bottom_offset = (n * size_unstack_axis + i) * strides; |
| 45 | + caffe_copy(strides, bottom_data + bottom_offset, top_data + top_offset); |
65 | 46 | } |
66 | | - offset_unstack_axis += 1; |
67 | 47 | } |
68 | 48 | } |
69 | 49 |
|
70 | | - |
71 | | - |
72 | 50 | INSTANTIATE_CLASS(UnstackLayer); |
73 | 51 | REGISTER_LAYER_CLASS(Unstack); |
74 | 52 |
|
75 | | -} // namespace caffe |
76 | | - |
| 53 | +} // namespace caffe |
0 commit comments