Skip to content

Commit c998518

Browse files
committed
can also use values stored in caffemodel as 2nd input
1 parent 14c2dae commit c998518

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

include/caffe/layers/add_layer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class AddLayer : public Layer<Dtype> {
2525
const vector<Blob<Dtype>*>& top);
2626

2727
virtual inline const char* type() const { return "Add"; }
28-
virtual inline int ExactNumBottomBlobs() const { return 2; }
28+
virtual inline int MinBottomBlobs() const { return 1; }
2929
virtual inline int ExactNumTopBlobs() const { return 1; }
3030

3131
protected:

src/caffe/layers/add_layer.cpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,22 @@ void AddLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
1111
const vector<Blob<Dtype>*>& top) {
1212
CHECK_NE(top[0], bottom[0]) << this->type() << " Layer does not allow in-place computation.";
1313
is_scalar_=false;
14-
if(bottom[0]->num_axes()==0 || bottom[1]->num_axes()==0)
14+
Blob<Dtype>* addend = (bottom.size() > 1) ? bottom[1] : this->blobs_[0].get();
15+
16+
if(bottom[0]->num_axes()==0 || addend->num_axes()==0)
1517
is_scalar_=true;
16-
dim_diff_ = bottom[0]->num_axes() - bottom[1]->num_axes();
17-
dim_ = bottom[0]->num_axes() >= bottom[1]->num_axes() ? bottom[0]->num_axes() : bottom[1]->num_axes();
18+
dim_diff_ = bottom[0]->num_axes() - addend->num_axes();
19+
dim_ = bottom[0]->num_axes() >= addend->num_axes() ? bottom[0]->num_axes() : addend->num_axes();
1820
vector<int> top_shape(dim_, 1);
1921
if(dim_diff_ == 0)
2022
{
2123
if(!is_scalar_)
2224
{
2325
for(int i=0;i<dim_;i++)
2426
{
25-
CHECK(bottom[0]->shape(i)==bottom[1]->shape(i) || bottom[0]->shape(i)==1 || bottom[1]->shape(i)==1)
27+
CHECK(bottom[0]->shape(i)==addend->shape(i) || bottom[0]->shape(i)==1 || addend->shape(i)==1)
2628
<< "Dimensions must be equal or 1 in the bottoms!";
27-
top_shape[i] = bottom[0]->shape(i) >= bottom[1]->shape(i) ? bottom[0]->shape(i): bottom[1]->shape(i);
29+
top_shape[i] = bottom[0]->shape(i) >= addend->shape(i) ? bottom[0]->shape(i): addend->shape(i);
2830
}
2931
}
3032
}
@@ -35,7 +37,7 @@ void AddLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
3537
for(int i=0;i<dim_diff_;i++)
3638
top_shape[i] = bottom[0]->shape(i);
3739
for(int i=dim_diff_; i<dim_; i++)
38-
top_shape[i] = bottom[0]->shape(i) >= bottom[1]->shape(i-dim_diff_) ? bottom[0]->shape(i): bottom[1]->shape(i-dim_diff_);
40+
top_shape[i] = bottom[0]->shape(i) >= addend->shape(i-dim_diff_) ? bottom[0]->shape(i): addend->shape(i-dim_diff_);
3941
}
4042
else //bottom1 is a scalar
4143
{
@@ -48,24 +50,26 @@ void AddLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
4850
if(!is_scalar_)
4951
{
5052
for(int i=0;i<-dim_diff_;i++)
51-
top_shape[i] = bottom[1]->shape(i);
53+
top_shape[i] = addend->shape(i);
5254
for(int i=-dim_diff_; i<dim_; i++)
53-
top_shape[i] = bottom[0]->shape(i+dim_diff_) >= bottom[1]->shape(i) ? bottom[0]->shape(i+dim_diff_): bottom[1]->shape(i);
55+
top_shape[i] = bottom[0]->shape(i+dim_diff_) >= addend->shape(i) ? bottom[0]->shape(i+dim_diff_): addend->shape(i);
5456
}
5557
else //bottom0 is a scalar
5658
{
5759
for(int i=0;i<dim_;i++)
58-
top_shape[i] = bottom[1]->shape(i);
60+
top_shape[i] = addend->shape(i);
5961
}
6062
}
63+
6164
top[0]->Reshape(top_shape);
6265
}
6366

6467
template <typename Dtype>
6568
void AddLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
6669
const vector<Blob<Dtype>*>& top) {
6770
const Dtype* bottom0_data = bottom[0]->cpu_data();
68-
const Dtype* bottom1_data = bottom[1]->cpu_data();
71+
Blob<Dtype>* addend = (bottom.size() > 1) ? bottom[1] : this->blobs_[0].get();
72+
const Dtype* bottom1_data = addend->cpu_data();
6973
Dtype* top_data = top[0]->mutable_cpu_data();
7074
int count = top[0]->count();
7175

@@ -90,13 +94,13 @@ void AddLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
9094
{
9195
int num = (d % top[0]->count(i)) / top[0]->count(i+1);
9296
int n0 = 1 == bottom[0]->shape(i) ? 0 : num;
93-
int n1 = 1 == bottom[1]->shape(i) ? 0 : num;
97+
int n1 = 1 == addend->shape(i) ? 0 : num;
9498
offset0 += n0 * bottom[0]->count(i+1);
95-
offset1 += n1 * bottom[1]->count(i+1);
99+
offset1 += n1 * addend->count(i+1);
96100
}
97101
int z = d % top[0]->shape(dim_-1);
98102
int z0 = 1 == bottom[0]->shape(dim_-1) ? 0 : z;
99-
int z1 = 1 == bottom[1]->shape(dim_-1) ? 0 : z;
103+
int z1 = 1 == addend->shape(dim_-1) ? 0 : z;
100104
offset0 += z0;
101105
offset1 += z1;
102106
}
@@ -112,13 +116,13 @@ void AddLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
112116
{
113117
int num = (d % top[0]->count(i)) / top[0]->count(i+1);
114118
int n0 = 1 == bottom[0]->shape(i) ? 0 : num;
115-
int n1 = 1 == bottom[1]->shape(i-dim_diff_) ? 0 : num;
119+
int n1 = 1 == addend->shape(i-dim_diff_) ? 0 : num;
116120
offset0 += n0 * bottom[0]->count(i+1);
117-
offset1 += n1 * bottom[1]->count(i-dim_diff_+1);
121+
offset1 += n1 * addend->count(i-dim_diff_+1);
118122
}
119123
int z = d % top[0]->shape(dim_-1);
120124
int z0 = 1 == bottom[0]->shape(dim_-1) ? 0 : z;
121-
int z1 = 1 == bottom[1]->shape(dim_-dim_diff_-1) ? 0 : z;
125+
int z1 = 1 == addend->shape(dim_-dim_diff_-1) ? 0 : z;
122126
offset0 += z0;
123127
offset1 += z1;
124128
}
@@ -127,30 +131,30 @@ void AddLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
127131
for(int i=0;i<-dim_diff_;i++)
128132
{
129133
int num = (d % top[0]->count(i)) / top[0]->count(i+1);
130-
int n1 = 1 == bottom[1]->shape(i) ? 0 : num;
131-
offset1 += n1 * bottom[1]->count(i+1);
134+
int n1 = 1 == addend->shape(i) ? 0 : num;
135+
offset1 += n1 * addend->count(i+1);
132136
}
133137
for(int i=-dim_diff_;i<dim_-1;i++)
134138
{
135139
int num = (d % top[0]->count(i)) / top[0]->count(i+1);
136140
int n0 = 1 == bottom[0]->shape(i+dim_diff_) ? 0 : num;
137-
int n1 = 1 == bottom[1]->shape(i) ? 0 : num;
141+
int n1 = 1 == addend->shape(i) ? 0 : num;
138142
offset0 += n0 * bottom[0]->count(i+dim_diff_+1);
139-
offset1 += n1 * bottom[1]->count(i+1);
143+
offset1 += n1 * addend->count(i+1);
140144
}
141145
int z = d % top[0]->shape(dim_-1);
142146
int z0 = 1 == bottom[0]->shape(dim_+dim_diff_-1) ? 0 : z;
143-
int z1 = 1 == bottom[1]->shape(dim_-1) ? 0 : z;
147+
int z1 = 1 == addend->shape(dim_-1) ? 0 : z;
144148
offset0 += z0;
145149
offset1 += z1;
146150
}
147151

148152
top_data[d] = bottom0_data[offset0] + bottom1_data[offset1];
149153
}
150154
}
151-
else //has scalar
155+
else //is scalar with shape ()
152156
{
153-
if(bottom[1]->num_axes()==0) //bottom1 is a scalar
157+
if(addend->num_axes()==0) //bottom1 is a scalar
154158
{
155159
caffe_copy(count, bottom0_data, top_data);
156160
Dtype scalar = bottom1_data[0];

0 commit comments

Comments
 (0)