summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Donahue <jeff.donahue@gmail.com>2017-04-13 13:32:28 -0700
committerJeff Donahue <jeff.donahue@gmail.com>2017-04-13 13:32:28 -0700
commitc560658464886d761e4c7a53b993b35368540a1b (patch)
treef3b6bc915792ed7a5231ae949d0ca613ff6e1550
parentfecee6c3ff93d3fb6b55175d2232ad1bdf5be03a (diff)
parent1c15d94f7da736945450e6ed321077f3045445b1 (diff)
downloadcaffe-c560658464886d761e4c7a53b993b35368540a1b.tar.gz
caffe-c560658464886d761e4c7a53b993b35368540a1b.tar.bz2
caffe-c560658464886d761e4c7a53b993b35368540a1b.zip
Merge pull request #5136 from pfollmann/fix_batchnorm_layer
-rw-r--r--include/caffe/util/math_functions.hpp6
-rw-r--r--src/caffe/layers/batch_norm_layer.cpp6
-rw-r--r--src/caffe/layers/batch_norm_layer.cu8
-rw-r--r--src/caffe/util/math_functions.cpp10
-rw-r--r--src/caffe/util/math_functions.cu21
5 files changed, 44 insertions, 7 deletions
diff --git a/include/caffe/util/math_functions.hpp b/include/caffe/util/math_functions.hpp
index 37abce5e..e549120a 100644
--- a/include/caffe/util/math_functions.hpp
+++ b/include/caffe/util/math_functions.hpp
@@ -53,6 +53,9 @@ template <typename Dtype>
void caffe_sqr(const int N, const Dtype* a, Dtype* y);
template <typename Dtype>
+void caffe_sqrt(const int N, const Dtype* a, Dtype* y);
+
+template <typename Dtype>
void caffe_add(const int N, const Dtype* a, const Dtype* b, Dtype* y);
template <typename Dtype>
@@ -214,6 +217,9 @@ void caffe_gpu_log(const int n, const Dtype* a, Dtype* y);
template <typename Dtype>
void caffe_gpu_powx(const int n, const Dtype* a, const Dtype b, Dtype* y);
+template <typename Dtype>
+void caffe_gpu_sqrt(const int n, const Dtype* a, Dtype* y);
+
// caffe_gpu_rng_uniform with two arguments generates integers in the range
// [0, UINT_MAX].
void caffe_gpu_rng_uniform(const int n, unsigned int* r);
diff --git a/src/caffe/layers/batch_norm_layer.cpp b/src/caffe/layers/batch_norm_layer.cpp
index 0a08ed4c..c6a1d5b1 100644
--- a/src/caffe/layers/batch_norm_layer.cpp
+++ b/src/caffe/layers/batch_norm_layer.cpp
@@ -124,8 +124,8 @@ void BatchNormLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
if (!use_global_stats_) {
// compute variance using var(X) = E((X-EX)^2)
- caffe_powx(top[0]->count(), top_data, Dtype(2),
- temp_.mutable_cpu_data()); // (X-EX)^2
+ caffe_sqr<Dtype>(top[0]->count(), top_data,
+ temp_.mutable_cpu_data()); // (X-EX)^2
caffe_cpu_gemv<Dtype>(CblasNoTrans, channels_ * num, spatial_dim,
1. / (num * spatial_dim), temp_.cpu_data(),
spatial_sum_multiplier_.cpu_data(), 0.,
@@ -148,7 +148,7 @@ void BatchNormLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
// normalize variance
caffe_add_scalar(variance_.count(), eps_, variance_.mutable_cpu_data());
- caffe_powx(variance_.count(), variance_.cpu_data(), Dtype(0.5),
+ caffe_sqrt(variance_.count(), variance_.cpu_data(),
variance_.mutable_cpu_data());
// replicate variance to input size
diff --git a/src/caffe/layers/batch_norm_layer.cu b/src/caffe/layers/batch_norm_layer.cu
index c21713c8..a35e778e 100644
--- a/src/caffe/layers/batch_norm_layer.cu
+++ b/src/caffe/layers/batch_norm_layer.cu
@@ -48,14 +48,14 @@ void BatchNormLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
if (!use_global_stats_) {
// compute variance using var(X) = E((X-EX)^2)
- caffe_gpu_powx(top[0]->count(), top_data, Dtype(2),
+ caffe_gpu_mul(top[0]->count(), top[0]->gpu_data(), top[0]->gpu_data(),
temp_.mutable_gpu_data()); // (X-EX)^2
caffe_gpu_gemv<Dtype>(CblasNoTrans, channels_ * num, spatial_dim,
1. / (num * spatial_dim), temp_.gpu_data(),
spatial_sum_multiplier_.gpu_data(), 0.,
num_by_chans_.mutable_gpu_data());
- caffe_gpu_gemv<Dtype>(CblasTrans, num, channels_, 1.,
- num_by_chans_.gpu_data(), batch_sum_multiplier_.gpu_data(), 0.,
+ caffe_gpu_gemv<Dtype>(CblasTrans, num, channels_, Dtype(1.),
+ num_by_chans_.gpu_data(), batch_sum_multiplier_.gpu_data(), Dtype(0.),
variance_.mutable_gpu_data()); // E((X_EX)^2)
// compute and save moving average
@@ -72,7 +72,7 @@ void BatchNormLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
// normalize variance
caffe_gpu_add_scalar(variance_.count(), eps_, variance_.mutable_gpu_data());
- caffe_gpu_powx(variance_.count(), variance_.gpu_data(), Dtype(0.5),
+ caffe_gpu_sqrt(variance_.count(), variance_.gpu_data(),
variance_.mutable_gpu_data());
// replicate variance to input size
diff --git a/src/caffe/util/math_functions.cpp b/src/caffe/util/math_functions.cpp
index 71c02274..59625bc0 100644
--- a/src/caffe/util/math_functions.cpp
+++ b/src/caffe/util/math_functions.cpp
@@ -197,6 +197,16 @@ void caffe_sqr<double>(const int n, const double* a, double* y) {
}
template <>
+void caffe_sqrt<float>(const int n, const float* a, float* y) {
+ vsSqrt(n, a, y);
+}
+
+template <>
+void caffe_sqrt<double>(const int n, const double* a, double* y) {
+ vdSqrt(n, a, y);
+}
+
+template <>
void caffe_exp<float>(const int n, const float* a, float* y) {
vsExp(n, a, y);
}
diff --git a/src/caffe/util/math_functions.cu b/src/caffe/util/math_functions.cu
index 6d001026..314e6ba0 100644
--- a/src/caffe/util/math_functions.cu
+++ b/src/caffe/util/math_functions.cu
@@ -387,6 +387,27 @@ void caffe_gpu_powx<double>(const int N, const double* a,
N, a, alpha, y);
}
+template <typename Dtype>
+__global__ void sqrt_kernel(const int n, const Dtype* a, Dtype* y) {
+ CUDA_KERNEL_LOOP(index, n) {
+ y[index] = sqrt(a[index]);
+ }
+}
+
+template <>
+void caffe_gpu_sqrt<float>(const int N, const float* a, float* y) {
+ // NOLINT_NEXT_LINE(whitespace/operators)
+ sqrt_kernel<float><<<CAFFE_GET_BLOCKS(N), CAFFE_CUDA_NUM_THREADS>>>(
+ N, a, y);
+}
+
+template <>
+void caffe_gpu_sqrt<double>(const int N, const double* a, double* y) {
+ // NOLINT_NEXT_LINE(whitespace/operators)
+ sqrt_kernel<double><<<CAFFE_GET_BLOCKS(N), CAFFE_CUDA_NUM_THREADS>>>(
+ N, a, y);
+}
+
DEFINE_AND_INSTANTIATE_GPU_UNARY_FUNC(sign, y[index] = (Dtype(0) < x[index])
- (x[index] < Dtype(0)));
DEFINE_AND_INSTANTIATE_GPU_UNARY_FUNC(sgnbit, y[index] = signbit(x[index]));