Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions src/caffe/test/test_random_number_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ class RandomNumberGeneratorTest : public ::testing::Test {
return sum / sample_size;
}

Dtype sample_mean(const int* const seqs, const size_t sample_size)
{
Dtype sum = 0;
for (int i = 0; i < sample_size; ++i) {
sum += Dtype(seqs[i]);
}
return sum / sample_size;
}

Dtype mean_bound(const Dtype std, const size_t sample_size)
{
return std/sqrt((double)sample_size);
Expand All @@ -40,28 +49,47 @@ TYPED_TEST(RandomNumberGeneratorTest, TestRngGaussian) {
Caffe::set_random_seed(1701);
TypeParam mu = 0;
TypeParam sigma = 1;
caffe_vRngGaussian(sample_size, (TypeParam*)data_a.mutable_cpu_data(), mu, sigma);
caffe_vRngGaussian(sample_size,
(TypeParam*)data_a.mutable_cpu_data(), mu, sigma);
TypeParam true_mean = mu;
TypeParam true_std = sigma;
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam real_mean = this->sample_mean((TypeParam*)data_a.cpu_data(), sample_size);
EXPECT_NEAR(real_mean, true_mean, bound);
TypeParam empirical_mean =
this->sample_mean((TypeParam*)data_a.cpu_data(), sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
}


TYPED_TEST(RandomNumberGeneratorTest, TestRngUniform) {
size_t sample_size = 10000;
SyncedMemory data_a(sample_size * sizeof(TypeParam));
Caffe::set_random_seed(1701);
TypeParam lower = 0;
TypeParam upper = 1;
caffe_vRngUniform(sample_size, (TypeParam*)data_a.mutable_cpu_data(), lower, upper);
caffe_vRngUniform(sample_size,
(TypeParam*)data_a.mutable_cpu_data(), lower, upper);
TypeParam true_mean = (lower + upper) / 2;
TypeParam true_std = (upper - lower) / sqrt(12);
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam real_mean = this->sample_mean((TypeParam*)data_a.cpu_data(), sample_size);
EXPECT_NEAR(real_mean, true_mean, bound);
TypeParam empirical_mean =
this->sample_mean((TypeParam*)data_a.cpu_data(), sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
}


TYPED_TEST(RandomNumberGeneratorTest, TestRngBernoulli) {
size_t sample_size = 10000;
SyncedMemory data_a(sample_size * sizeof(int));
Caffe::set_random_seed(1701);
double p = 0.3;
caffe_vRngBernoulli(sample_size, (int*)data_a.mutable_cpu_data(), p);
TypeParam true_mean = p;
TypeParam true_std = sqrt(p * (1 - p));
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam empirical_mean =
this->sample_mean((const int *)data_a.cpu_data(), sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
}


} // namespace caffe
5 changes: 2 additions & 3 deletions src/caffe/util/math_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,10 @@ void caffe_vRngBernoulli(const int n, Dtype* r, const double p) {
CHECK(r);
CHECK_GE(p, 0);
CHECK_LE(p, 1);
// FIXME check if parameters are handled in the same way ?
boost::bernoulli_distribution<Dtype> random_distribution(p);
boost::bernoulli_distribution<double> random_distribution(p);
Caffe::random_generator_t &generator = Caffe::vsl_stream();
boost::variate_generator<Caffe::random_generator_t,
boost::bernoulli_distribution<Dtype> > variate_generator(
boost::bernoulli_distribution<double> > variate_generator(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be Dtype and not double, no? Otherwise this looks good.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this was the point of the PR - the only Dtype Caffe actually instantiates for caffe_vRngBernoulli is int (as Bernoulli outputs 0/1), and when you use bernoulli_distribution it seems to typecast p to an int (setting the Bernoulli parameter to 0.0 for p in [0, 1)) and output all zeros (unless p==1.0).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, I forgot you told me that yesterday.

generator, random_distribution);

for (int i = 0; i < n; ++i) {
Expand Down