Commit 8e8e832a authored by Brice Videau's avatar Brice Videau
Browse files

Test numerical hypeparameter.

parent 27c6b45a
......@@ -24,15 +24,6 @@ enum ccs_scale_type_e {
typedef enum ccs_scale_type_e ccs_scale_type_t;
// Distribution
extern ccs_error_t
ccs_create_distribution(ccs_distribution_type_t distribution_type,
ccs_numeric_type_t data_type,
ccs_scale_type_t scale,
ccs_numeric_t quantization,
size_t num_parameters,
ccs_numeric_t *parameters,
ccs_distribution_t *distribution_ret);
extern ccs_error_t
ccs_create_normal_distribution(ccs_numeric_type_t data_type,
ccs_float_t mu,
......
......@@ -113,3 +113,13 @@ ccs_distribution_samples(ccs_distribution_t distribution,
_ccs_distribution_ops_t *ops = ccs_distribution_get_ops(distribution);
return ops->samples(distribution->data, rng, num_values, values);
}
extern ccs_error_t
ccs_create_normal_float_distribution(ccs_float_t mu,
ccs_float_t sigma,
ccs_scale_type_t scale,
ccs_float_t quantization,
ccs_distribution_t *distribution_ret) {
return ccs_create_normal_distribution(CCS_NUM_FLOAT, mu, sigma, scale,
CCSF(quantization), distribution_ret);
}
#include "cconfigspace_internal.h"
#include "hyperparameter_internal.h"
#include <string.h>
struct _ccs_hyperparameter_numerical_data_s {
_ccs_hyperparameter_common_data_t common_data;
......@@ -57,7 +58,9 @@ _ccs_hyperparameter_numerical_samples(_ccs_hyperparameter_data_t *data,
vs = NULL;
size_t coeff = 2;
while (found < num_values) {
size_t buff_sz = num_values - found;
fprintf(stderr, "Found %ld\n", found);
size_t buff_sz = (num_values - found)*coeff;
fprintf(stderr, "NewBuff %ld\n", buff_sz);
vs = (ccs_numeric_t *)malloc(sizeof(ccs_numeric_t)*buff_sz);
if (!vs)
return -CCS_ENOMEM;
......@@ -65,10 +68,12 @@ _ccs_hyperparameter_numerical_samples(_ccs_hyperparameter_data_t *data,
rng, buff_sz, vs);
if (d->interval.type == CCS_NUM_FLOAT) {
for(size_t i = 0; i < buff_sz && found < num_values; i++)
values[found++].value.f = vs[i].f;
if (_check_value(d, vs[i]))
values[found++].value.f = vs[i].f;
} else {
for(size_t i = 0; i < buff_sz && found < num_values; i++)
values[found++].value.i = vs[i].i;
if (_check_value(d, vs[i]))
values[found++].value.i = vs[i].i;
}
coeff <<= 1;
free(vs);
......@@ -96,7 +101,7 @@ ccs_create_numerical_hyperparameter(const char *name,
ccs_distribution_t distribution,
void *user_data,
ccs_hyperparameter_t *hyperparameter_ret) {
if (!hyperparameter_ret)
if (!hyperparameter_ret || !name)
return -CCS_INVALID_VALUE;
if (data_type != CCS_NUM_FLOAT && data_type != CCS_NUM_INTEGER)
return -CCS_INVALID_TYPE;
......@@ -114,7 +119,9 @@ ccs_create_numerical_hyperparameter(const char *name,
default_value.f < lower.f ||
default_value.f >= upper.f ) )
return -CCS_INVALID_VALUE;
uintptr_t mem = (uintptr_t)calloc(1, sizeof(struct _ccs_hyperparameter_s) + sizeof(_ccs_hyperparameter_numerical_data_t));
uintptr_t mem = (uintptr_t)calloc(1, sizeof(struct _ccs_hyperparameter_s) + sizeof(_ccs_hyperparameter_numerical_data_t)+strlen(name) + 1);
if (!mem)
return -CCS_ENOMEM;
ccs_interval_t interval;
interval.type = data_type;
......@@ -124,8 +131,6 @@ ccs_create_numerical_hyperparameter(const char *name,
interval.upper_included = CCS_FALSE;
ccs_error_t err;
if (!mem)
return -CCS_ENOMEM;
ccs_bool_t oversampling;
if (!distribution) {
err = ccs_create_uniform_distribution(data_type, lower, upper,
......@@ -140,17 +145,18 @@ ccs_create_numerical_hyperparameter(const char *name,
err = ccs_distribution_check_oversampling(distribution, &interval,
&oversampling);
if (err) {
ccs_release_object(distribution);
free((void *)mem);
return err;
}
ccs_retain_object(distribution);
}
ccs_hyperparameter_t hyperparam = (ccs_hyperparameter_t)mem;
_ccs_object_init(&(hyperparam->obj), CCS_HYPERPARAMETER, (_ccs_object_ops_t *)&_ccs_hyperparameter_numerical_ops);
_ccs_hyperparameter_numerical_data_t *hyperparam_data = (_ccs_hyperparameter_numerical_data_t *)(mem + sizeof(struct _ccs_hyperparameter_s));
hyperparam_data->common_data.type = CCS_NUMERICAL;
hyperparam_data->common_data.name = name;
hyperparam_data->common_data.name = (char *)(mem + sizeof(struct _ccs_hyperparameter_s) + sizeof(_ccs_hyperparameter_numerical_data_t));
strcpy((char *)hyperparam_data->common_data.name, name);
hyperparam_data->common_data.user_data = user_data;
hyperparam_data->common_data.distribution = distribution;
if (data_type == CCS_NUM_FLOAT) {
......
......@@ -7,7 +7,8 @@ RNG_TESTS = \
test_rng \
test_interval \
test_uniform_distribution \
test_normal_distribution
test_normal_distribution \
test_numerical_hyperparameter
# unit tests
UNIT_TESTS = \
......
......@@ -162,11 +162,9 @@ static void test_normal_distribution_int() {
to_float(samples, num_samples);
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mu: %lf \n", mean);
assert( mean < mu + 0.1 );
assert( mean > mu - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, mu);
//fprintf(stderr, "sig: %lf \n", sig);
assert( sig < sigma + 0.1 );
assert( sig > sigma - 0.1 );
......@@ -210,11 +208,9 @@ static void test_normal_distribution_float() {
assert( err == CCS_SUCCESS );
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mu: %lf \n", mean);
assert( mean < mu + 0.1 );
assert( mean > mu - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, mu);
//fprintf(stderr, "sig: %lf \n", sig);
assert( sig < sigma + 0.1 );
assert( sig > sigma - 0.1 );
......@@ -261,20 +257,16 @@ static void test_normal_distribution_int_log() {
to_float(samples, num_samples);
to_log(samples, num_samples);
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mean: %lf \n", mean);
// cutoff at 0.0 to have exp(v) >= 1
// see https://en.wikipedia.org/wiki/Truncated_normal_distribution
alpha = (log(0.5) - mu)/sigma;
zee = (1.0 - gsl_cdf_ugaussian_P(alpha));
pdfa = gsl_ran_ugaussian_pdf(alpha);
tmean = mu + pdfa * sigma / zee;
//fprintf(stderr, "tmean: %lf \n", tmean);
assert( mean < tmean + 0.1 );
assert( mean > tmean - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, tmean);
//fprintf(stderr, "sig: %lf \n", sig);
tsigma = sqrt( sigma * sigma * ( 1.0 + alpha * pdfa / zee - ( pdfa * pdfa )/( zee * zee ) ) );
//fprintf(stderr, "tsig: %lf \n", tsigma);
assert( sig < tsigma + 0.1 );
assert( sig > tsigma - 1.1 );
......@@ -319,11 +311,9 @@ static void test_normal_distribution_float_log() {
to_log(samples, num_samples);
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mu: %lf \n", mean);
assert( mean < mu + 0.1 );
assert( mean > mu - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, mu);
//fprintf(stderr, "sig: %lf \n", sig);
assert( sig < sigma + 0.1 );
assert( sig > sigma - 0.1 );
......@@ -369,11 +359,9 @@ static void test_normal_distribution_int_quantize() {
to_float(samples, num_samples);
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mu: %lf \n", mean);
assert( mean < mu + 0.1 );
assert( mean > mu - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, mu);
//fprintf(stderr, "sig: %lf \n", sig);
assert( sig < sigma + 0.1 );
assert( sig > sigma - 0.1 );
......@@ -417,11 +405,9 @@ static void test_normal_distribution_float_quantize() {
assert( err == CCS_SUCCESS );
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mu: %lf \n", mean);
assert( mean < mu + 0.1 );
assert( mean > mu - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, mu);
//fprintf(stderr, "sig: %lf \n", sig);
assert( sig < sigma + 0.1 );
assert( sig > sigma - 0.1 );
......@@ -469,20 +455,16 @@ static void test_normal_distribution_int_log_quantize() {
to_float(samples, num_samples);
to_log(samples, num_samples);
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mean: %lf \n", mean);
// cutoff at 0.0 to have exp(v) >= 1
// see https://en.wikipedia.org/wiki/Truncated_normal_distribution
alpha = (log(0.5*quantize) - mu)/sigma;
zee = (1.0 - gsl_cdf_ugaussian_P(alpha));
pdfa = gsl_ran_ugaussian_pdf(alpha);
tmean = mu + pdfa * sigma / zee;
//fprintf(stderr, "tmean: %lf \n", tmean);
assert( mean < tmean + 0.1 );
assert( mean > tmean - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, tmean);
//fprintf(stderr, "sig: %lf \n", sig);
tsigma = sqrt( sigma * sigma * ( 1.0 + alpha * pdfa / zee - ( pdfa * pdfa )/( zee * zee ) ) );
//fprintf(stderr, "tsig: %lf \n", tsigma);
assert( sig < tsigma + 0.1 );
assert( sig > tsigma - 1.1 );
......@@ -529,20 +511,16 @@ static void test_normal_distribution_float_log_quantize() {
to_log(samples, num_samples);
mean = gsl_stats_mean((double*)samples, 1, num_samples);
//fprintf(stderr, "mu: %lf \n", mean);
// cutoff at log(quantization/2.0) to have quantized(exp(v)) >= quantization
// see https://en.wikipedia.org/wiki/Truncated_normal_distribution
alpha = (log(quantization*0.5) - mu)/sigma;
zee = (1.0 - gsl_cdf_ugaussian_P(alpha));
pdfa = gsl_ran_ugaussian_pdf(alpha);
tmean = mu + pdfa * sigma / zee;
//fprintf(stderr, "tmean: %lf \n", tmean);
assert( mean < tmean + 0.1 );
assert( mean > tmean - 0.1 );
sig = gsl_stats_sd_m((double*)samples, 1, num_samples, tmean);
//fprintf(stderr, "sig: %lf \n", sig);
tsigma = sqrt( sigma * sigma * ( 1.0 + alpha * pdfa / zee - ( pdfa * pdfa )/( zee * zee ) ) );
//fprintf(stderr, "tsig: %lf \n", tsigma);
assert( sig < tsigma + 0.1 );
assert( sig > tsigma - 0.1 );
......
#include <stdlib.h>
#include <assert.h>
#include <cconfigspace.h>
#include <string.h>
void test_create() {
ccs_hyperparameter_t hyperparameter;
ccs_hyperparameter_type_t type;
ccs_datum_t default_value;
ccs_error_t err;
const char *name;
void * user_data;
ccs_distribution_t distribution;
ccs_distribution_type_t dist_type;
ccs_interval_t interval;
err = ccs_create_numerical_hyperparameter("my_param", CCS_NUM_FLOAT,
CCSF(-5.0), CCSF(5.0),
CCSF(0.0), CCSF(1.0),
NULL, NULL, &hyperparameter);
assert( err == CCS_SUCCESS );
err = ccs_hyperparameter_get_type(hyperparameter, &type);
assert( err == CCS_SUCCESS );
assert( type == CCS_NUMERICAL );
err = ccs_hyperparameter_get_default_value(hyperparameter, &default_value);
assert( err == CCS_SUCCESS );
assert( default_value.type == CCS_FLOAT );
assert( default_value.value.f == 1.0 );
err = ccs_hyperparameter_get_name(hyperparameter, &name);
assert( err == CCS_SUCCESS );
assert( strcmp(name, "my_param") == 0 );
err = ccs_hyperparameter_get_user_data(hyperparameter, &user_data);
assert( err == CCS_SUCCESS );
assert( user_data == NULL );
err = ccs_hyperparameter_get_distribution(hyperparameter, &distribution);
assert( err == CCS_SUCCESS );
assert( distribution );
err = ccs_distribution_get_type(distribution, &dist_type);
assert( err == CCS_SUCCESS );
assert( dist_type == CCS_UNIFORM );
err = ccs_distribution_get_bounds(distribution, &interval);
assert( err == CCS_SUCCESS );
assert( interval.type == CCS_NUM_FLOAT );
assert( interval.lower.f == -5.0 );
assert( interval.lower_included == CCS_TRUE );
assert( interval.upper.f == 5.0 );
assert( interval.upper_included == CCS_FALSE );
err = ccs_release_object(hyperparameter);
assert( err == CCS_SUCCESS );
}
void test_samples() {
ccs_rng_t rng;
ccs_hyperparameter_t hyperparameter;
const size_t num_samples = 10000;
ccs_datum_t samples[num_samples];
ccs_error_t err;
err = ccs_rng_create(&rng);
assert( err == CCS_SUCCESS );
err = ccs_create_numerical_hyperparameter("my_param", CCS_NUM_FLOAT,
CCSF(-5.0), CCSF(5.0),
CCSF(0.0), CCSF(1.0),
NULL, NULL, &hyperparameter);
assert( err == CCS_SUCCESS );
err = ccs_hyperparameter_samples(hyperparameter, rng, num_samples, samples);
assert( err == CCS_SUCCESS );
for( size_t i = 0; i < num_samples; i++) {
assert( samples[i].type == CCS_FLOAT );
assert( samples[i].value.f >= -5.0 && samples[i].value.f < 5.0 );
}
err = ccs_release_object(hyperparameter);
assert( err == CCS_SUCCESS );
err = ccs_release_object(rng);
assert( err == CCS_SUCCESS );
}
void test_oversampling() {
ccs_rng_t rng;
ccs_hyperparameter_t hyperparameter;
ccs_distribution_t distribution;
const size_t num_samples = 10000;
ccs_datum_t samples[num_samples];
ccs_error_t err;
err = ccs_rng_create(&rng);
assert( err == CCS_SUCCESS );
err = ccs_create_normal_float_distribution(0.0, 1.0, CCS_LINEAR, 0.0,
&distribution);
assert( err == CCS_SUCCESS );
err = ccs_create_numerical_hyperparameter("my_param", CCS_NUM_FLOAT,
CCSF(-1.0), CCSF(1.0),
CCSF(0.0), CCSF(0.0),
distribution, NULL, &hyperparameter);
assert( err == CCS_SUCCESS );
err = ccs_release_object(distribution);
assert( err == CCS_SUCCESS );
err = ccs_hyperparameter_samples(hyperparameter, rng, num_samples, samples);
assert( err == CCS_SUCCESS );
for( size_t i = 0; i < num_samples; i++) {
assert( samples[i].type == CCS_FLOAT );
assert( samples[i].value.f >= -1.0 && samples[i].value.f < 1.0 );
}
err = ccs_release_object(hyperparameter);
assert( err == CCS_SUCCESS );
err = ccs_release_object(rng);
assert( err == CCS_SUCCESS );
}
int main(int argc, char *argv[]) {
ccs_init();
test_create();
test_samples();
test_oversampling();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment