MCPcopy Create free account
hub / github.com/BVLC/caffe / Backward_cpu

Method Backward_cpu

src/caffe/layers/scale_layer.cpp:145–218  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

143
144template <typename Dtype>
145void ScaleLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
146 const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
147 if (bias_layer_ &&
148 this->param_propagate_down_[this->param_propagate_down_.size() - 1]) {
149 bias_layer_->Backward(top, bias_propagate_down_, bias_bottom_vec_);
150 }
151 const bool scale_param = (bottom.size() == 1);
152 Blob<Dtype>* scale = scale_param ? this->blobs_[0].get() : bottom[1];
153 if ((!scale_param && propagate_down[1]) ||
154 (scale_param && this->param_propagate_down_[0])) {
155 const Dtype* top_diff = top[0]->cpu_diff();
156 const bool in_place = (bottom[0] == top[0]);
157 const Dtype* bottom_data = (in_place ? &temp_ : bottom[0])->cpu_data();
158 // Hack: store big eltwise product in bottom[0] diff, except in the special
159 // case where this layer itself does the eltwise product, in which case we
160 // can store it directly in the scale diff, and we're done.
161 // If we're computing in-place (and not doing eltwise computation), this
162 // hack doesn't work and we store the product in temp_.
163 const bool is_eltwise = (bottom[0]->count() == scale->count());
164 Dtype* product = (is_eltwise ? scale->mutable_cpu_diff() :
165 (in_place ? temp_.mutable_cpu_data() : bottom[0]->mutable_cpu_diff()));
166 caffe_mul(top[0]->count(), top_diff, bottom_data, product);
167 if (!is_eltwise) {
168 Dtype* sum_result = NULL;
169 if (inner_dim_ == 1) {
170 sum_result = product;
171 } else if (sum_result_.count() == 1) {
172 const Dtype* sum_mult = sum_multiplier_.cpu_data();
173 Dtype* scale_diff = scale->mutable_cpu_diff();
174 if (scale_param) {
175 Dtype result = caffe_cpu_dot(inner_dim_, product, sum_mult);
176 *scale_diff += result;
177 } else {
178 *scale_diff = caffe_cpu_dot(inner_dim_, product, sum_mult);
179 }
180 } else {
181 const Dtype* sum_mult = sum_multiplier_.cpu_data();
182 sum_result = (outer_dim_ == 1) ?
183 scale->mutable_cpu_diff() : sum_result_.mutable_cpu_data();
184 caffe_cpu_gemv(CblasNoTrans, sum_result_.count(), inner_dim_,
185 Dtype(1), product, sum_mult, Dtype(0), sum_result);
186 }
187 if (outer_dim_ != 1) {
188 const Dtype* sum_mult = sum_multiplier_.cpu_data();
189 Dtype* scale_diff = scale->mutable_cpu_diff();
190 if (scale_dim_ == 1) {
191 if (scale_param) {
192 Dtype result = caffe_cpu_dot(outer_dim_, sum_mult, sum_result);
193 *scale_diff += result;
194 } else {
195 *scale_diff = caffe_cpu_dot(outer_dim_, sum_mult, sum_result);
196 }
197 } else {
198 caffe_cpu_gemv(CblasTrans, outer_dim_, scale_dim_,
199 Dtype(1), sum_result, sum_mult, Dtype(scale_param),
200 scale_diff);
201 }
202 }

Callers

nothing calls this directly

Calls 9

caffe_cpu_dotFunction · 0.85
cpu_diffMethod · 0.80
countMethod · 0.80
mutable_cpu_diffMethod · 0.80
sizeMethod · 0.45
BackwardMethod · 0.45
getMethod · 0.45
cpu_dataMethod · 0.45
mutable_cpu_dataMethod · 0.45

Tested by

no test coverage detected