Dtype caffe_cpu_dot(const int n, const Dtype* x, const Dtype* y) { return caffe_cpu_strided_dot(n, x, 1, y, 1); }
float caffe_cpu_dot<float>(const int n, const float* x, const float* y){ return caffe_cpu_strided_dot(n, x, 1, y, 1); }
double caffe_cpu_dot<double>(const int n, const double* x, const double* y){ return caffe_cpu_strided_dot(n, x, 1, y, 1); }
void NormalizeLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { const Dtype* top_diff = top[0]->cpu_diff(); const Dtype* top_data = top[0]->cpu_data(); const Dtype* bottom_data = bottom[0]->cpu_data(); const Dtype* square_data = squared_.cpu_data(); const Dtype* norm_data = (top.size() == 2) ? top[1]->cpu_data() : norm_.cpu_data(); Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); int num = bottom[0]->num(); int channels = bottom[0]->channels(); int spatial_dim = bottom[0]->height() * bottom[0]->width(); if (propagate_down[0]) { if (normalize_type_ == "L2") { for (int n = 0; n < num; ++n) { for (int s = 0; s < spatial_dim; s++) { Dtype a = caffe_cpu_strided_dot(channels, top_data + n*channels*spatial_dim + s, spatial_dim, top_diff + n*channels*spatial_dim + s, spatial_dim); for (int c = 0; c < channels; c++) { bottom_diff[(n * channels + c) * spatial_dim + s] = (top_diff[(n * channels + c) * spatial_dim + s] - top_data[(n * channels + c) * spatial_dim + s] * a) / norm_data[n*spatial_dim + s]; } } } } else if (normalize_type_ == "L1") { for (int n = 0; n < num; ++n) { for (int s = 0; s < spatial_dim; s++) { Dtype a = caffe_cpu_strided_dot(channels, top_data + n*channels*spatial_dim + s, spatial_dim, top_diff + n*channels*spatial_dim + s, spatial_dim); for (int c = 0; c < channels; c++) { bottom_diff[(n * channels + c) * spatial_dim + s] = (top_diff[(n * channels + c) * spatial_dim + s] - sign(bottom_data[(n * channels + c) * spatial_dim + s]) * a) / norm_data[n*spatial_dim + s]; } } } } else { NOT_IMPLEMENTED; } } if (bp_norm_) { const Dtype* norm_diff =top[1]->cpu_diff(); if (normalize_type_ == "L2") { for (int n = 0; n < num; ++n) { for (int s = 0; s < spatial_dim; s++) { for (int c = 0; c < channels; c++) { bottom_diff[(n * channels + c) * spatial_dim + s] += norm_diff[n*spatial_dim + s] * top_data[(n * channels + c) * spatial_dim + s]; } } } } else if (normalize_type_ == "L1") { for (int n = 0; n < num; ++n) { for (int s = 0; s < spatial_dim; s++) { for (int c = 0; c < channels; c++) { bottom_diff[(n * channels + c) * spatial_dim + s] += norm_diff[n*spatial_dim + s] * sign(bottom_data[(n * channels + c) * spatial_dim + s]); } } } } } }