@@ -20,8 +20,7 @@ void BatchNormLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
2020
2121
2222 if (use_global_stats_) {
23- // use the stored mean/variance estimates. TODO(cdoersch): allow an option
24- // to use an unbiased variance estimate, like the paper does.
23+ // use the stored mean/variance estimates.
2524 const Dtype scale_factor = this ->blobs_ [2 ]->cpu_data ()[0 ] == 0 ?
2625 0 : 1 / this ->blobs_ [2 ]->cpu_data ()[0 ];
2726 caffe_gpu_scale (variance_.count (), scale_factor,
@@ -94,16 +93,19 @@ template <typename Dtype>
9493void BatchNormLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
9594 const vector<bool >& propagate_down,
9695 const vector<Blob<Dtype>*>& bottom) {
97- CHECK (!use_global_stats_);
9896 const Dtype* top_diff;
9997 if (bottom[0 ] != top[0 ]) {
10098 top_diff = top[0 ]->gpu_diff ();
10199 } else {
102100 caffe_copy (x_norm_.count (), top[0 ]->gpu_diff (), x_norm_.mutable_gpu_diff ());
103101 top_diff = x_norm_.gpu_diff ();
104102 }
105- const Dtype* top_data = x_norm_.gpu_data ();
106103 Dtype* bottom_diff = bottom[0 ]->mutable_gpu_diff ();
104+ if (use_global_stats_) {
105+ caffe_gpu_div (temp_.count (), top_diff, temp_.gpu_data (), bottom_diff);
106+ return ;
107+ }
108+ const Dtype* top_data = x_norm_.gpu_data ();
107109 int num = bottom[0 ]->shape ()[0 ];
108110 int spatial_dim = bottom[0 ]->count ()/(channels_*bottom[0 ]->shape (0 ));
109111 // if Y = (X-mean(X))/(sqrt(var(X)+eps)), then
0 commit comments