Commit 13fddac7 authored by Konstantinos Chatzilygeroudis's avatar Konstantinos Chatzilygeroudis
Browse files

Changes in mean and kernel for saving

parent b57f7046
......@@ -57,7 +57,7 @@ namespace limbo {
BO_PARAM(double, noise, 0.01);
BO_PARAM(bool, optimize_noise, false);
};
}
} // namespace defaults
namespace kernel {
/**
......@@ -128,8 +128,20 @@ namespace limbo {
protected:
double _noise;
double _noise_p;
virtual size_t params_size() const
{
return 0;
}
virtual Eigen::VectorXd params() const
{
return Eigen::VectorXd();
}
virtual void set_params(const Eigen::VectorXd&) {}
};
}
}
} // namespace kernel
} // namespace limbo
#endif
......@@ -49,6 +49,7 @@
///@defgroup mean
///@defgroup mean_defaults
#include <limbo/mean/mean.hpp>
#include <limbo/mean/constant.hpp>
#include <limbo/mean/data.hpp>
#include <limbo/mean/function_ard.hpp>
......
......@@ -46,9 +46,7 @@
#ifndef LIMBO_MEAN_CONSTANT_HPP
#define LIMBO_MEAN_CONSTANT_HPP
#include <Eigen/Core>
#include <limbo/tools/macros.hpp>
#include <limbo/mean/mean.hpp>
namespace limbo {
namespace defaults {
......@@ -56,7 +54,8 @@ namespace limbo {
///@ingroup mean_defaults
BO_PARAM(double, constant, 1);
};
}
} // namespace defaults
namespace mean {
/** @ingroup mean
A constant mean (the traditionnal choice for Bayesian optimization)
......@@ -65,7 +64,7 @@ namespace limbo {
- ``double constant`` (the value of the constant)
*/
template <typename Params>
struct Constant {
struct Constant : public BaseMean<Params> {
Constant(size_t dim_out = 1) : _dim_out(dim_out) {}
template <typename GP>
......@@ -77,7 +76,7 @@ namespace limbo {
protected:
size_t _dim_out;
};
}
}
} // namespace mean
} // namespace limbo
#endif
......@@ -46,14 +46,14 @@
#ifndef LIMBO_MEAN_DATA_HPP
#define LIMBO_MEAN_DATA_HPP
#include <Eigen/Core>
#include <limbo/mean/mean.hpp>
namespace limbo {
namespace mean {
///@ingroup mean
///Use the mean of the observation as a constant mean
template <typename Params>
struct Data {
struct Data : public BaseMean<Params> {
Data(size_t dim_out = 1) {}
template <typename GP>
......@@ -62,7 +62,7 @@ namespace limbo {
return gp.mean_observation().array();
}
};
}
}
} // namespace mean
} // namespace limbo
#endif
......@@ -46,7 +46,7 @@
#ifndef LIMBO_MEAN_FUNCTION_ARD_HPP
#define LIMBO_MEAN_FUNCTION_ARD_HPP
#include <Eigen/Core>
#include <limbo/mean/mean.hpp>
namespace limbo {
namespace mean {
......@@ -55,7 +55,7 @@ namespace limbo {
///
/// @see limbo::model::gp::KernelMeanLFOpt, limbo::model::gp::MeanLFOpt
template <typename Params, typename MeanFunction>
struct FunctionARD {
struct FunctionARD : public BaseMean<Params> {
FunctionARD(size_t dim_out = 1)
: _mean_function(dim_out), _tr(dim_out, dim_out + 1)
{
......@@ -67,7 +67,7 @@ namespace limbo {
size_t h_params_size() const { return _tr.rows() * _tr.cols(); }
const Eigen::VectorXd& h_params() const { return _h_params; }
Eigen::VectorXd h_params() const { return _h_params; }
void set_h_params(const Eigen::VectorXd& p)
{
......
//| Copyright Inria May 2015
//| This project has received funding from the European Research Council (ERC) under
//| the European Union's Horizon 2020 research and innovation programme (grant
//| agreement No 637972) - see http://www.resibots.eu
//|
//| Contributor(s):
//| - Jean-Baptiste Mouret (jean-baptiste.mouret@inria.fr)
//| - Antoine Cully (antoinecully@gmail.com)
//| - Kontantinos Chatzilygeroudis (konstantinos.chatzilygeroudis@inria.fr)
//| - Federico Allocati (fede.allocati@gmail.com)
//| - Vaios Papaspyros (b.papaspyros@gmail.com)
//| - Roberto Rama (bertoski@gmail.com)
//|
//| This software is a computer library whose purpose is to optimize continuous,
//| black-box functions. It mainly implements Gaussian processes and Bayesian
//| optimization.
//| Main repository: http://github.com/resibots/limbo
//| Documentation: http://www.resibots.eu/limbo
//|
//| This software is governed by the CeCILL-C license under French law and
//| abiding by the rules of distribution of free software. You can use,
//| modify and/ or redistribute the software under the terms of the CeCILL-C
//| license as circulated by CEA, CNRS and INRIA at the following URL
//| "http://www.cecill.info".
//|
//| As a counterpart to the access to the source code and rights to copy,
//| modify and redistribute granted by the license, users are provided only
//| with a limited warranty and the software's author, the holder of the
//| economic rights, and the successive licensors have only limited
//| liability.
//|
//| In this respect, the user's attention is drawn to the risks associated
//| with loading, using, modifying and/or developing or reproducing the
//| software by the user in light of its specific status of free software,
//| that may mean that it is complicated to manipulate, and that also
//| therefore means that it is reserved for developers and experienced
//| professionals having in-depth computer knowledge. Users are therefore
//| encouraged to load and test the software's suitability as regards their
//| requirements in conditions enabling the security of their systems and/or
//| data to be ensured and, more generally, to use and operate it in the
//| same conditions as regards security.
//|
//| The fact that you are presently reading this means that you have had
//| knowledge of the CeCILL-C license and that you accept its terms.
//|
#ifndef LIMBO_MEAN_MEAN_HPP
#define LIMBO_MEAN_MEAN_HPP
#include <Eigen/Core>
#include <limbo/tools/macros.hpp>
namespace limbo {
namespace mean {
/** @ingroup mean
\rst
Base struct for mean definition.
\endrst
*/
template <typename Params>
struct BaseMean {
BaseMean(size_t dim_out = 1) : _dim_out(dim_out) {}
template <typename GP>
Eigen::VectorXd operator()(const Eigen::VectorXd& v, const GP&) const
{
std::cerr << "'BaseMean' should never be called!" << std::endl;
assert(false);
return Eigen::VectorXd();
}
virtual size_t h_params_size() const { return 0; }
virtual Eigen::VectorXd h_params() const { return Eigen::VectorXd(); }
virtual void set_h_params(const Eigen::VectorXd& p) {}
protected:
size_t _dim_out;
};
} // namespace mean
} // namespace limbo
#endif
......@@ -46,14 +46,14 @@
#ifndef LIMBO_MEAN_NULL_FUNCTION_HPP
#define LIMBO_MEAN_NULL_FUNCTION_HPP
#include <Eigen/Core>
#include <limbo/mean/mean.hpp>
namespace limbo {
namespace mean {
/// @ingroup mean
/// Constant with m=0
template <typename Params>
struct NullFunction {
struct NullFunction : public BaseMean<Params> {
NullFunction(size_t dim_out = 1) : _dim_out(dim_out) {}
template <typename GP>
......
......@@ -418,9 +418,10 @@ namespace limbo {
bool inv_kernel_computed() { return _inv_kernel_updated; }
/// TODO
/// save the parameters and the data for the GP to the archive (text or binary)
template <typename A>
void save(const std::string& directory){
void save(const std::string& directory)
{
A archive(directory);
save(archive);
}
......@@ -429,28 +430,30 @@ namespace limbo {
template <typename A>
void save(A& archive)
{
archive.save(_kernel_function.h_params(), "kernel_params");
// should we save parameters of the mean function as well?
// archive.save(_mean_function.h_params(), "mean_params");
if (_kernel_function.h_params_size() > 0) {
archive.save(_kernel_function.h_params(), "kernel_params");
}
if (_mean_function.h_params_size() > 0) {
archive.save(_mean_function.h_params(), "mean_params");
}
archive.save(_samples, "samples");
archive.save(_observations, "observations");
archive.save(_matrixL, "matrixL");
archive.save(_alpha, "alpha");
}
/// TODO
template<typename A>
void load(const std::string& directory){
A archive(directory);
/// load the parameters and the data for the GP from the archive (text or binary)
template <typename A>
void load(const std::string& directory, bool recompute = true)
{
A archive(directory, recompute);
load(archive);
}
/// load the parameters and the data for the GP from the archive (text or binary)
template <typename A>
void load(A& archive)
void load(A& archive, bool recompute = true)
{
Eigen::VectorXd h_params;
archive.load(h_params, "kernel_params");
// should we save parameters of the mean function as well?
_samples.clear();
archive.load(_samples, "samples");
......@@ -459,15 +462,31 @@ namespace limbo {
_dim_in = _samples[0].size();
_kernel_function = KernelFunction(_dim_in);
assert(h_params.size() == _kernel_function.h_params().size());
_kernel_function.set_h_params(h_params);
if (_kernel_function.h_params_size() > 0) {
Eigen::VectorXd h_params;
archive.load(h_params, "kernel_params");
assert(h_params.size() == (int)_kernel_function.h_params_size());
_kernel_function.set_h_params(h_params);
}
_dim_out = _observations.cols();
_mean_function = MeanFunction(_dim_out);
if (_mean_function.h_params_size() > 0) {
Eigen::VectorXd h_params;
archive.load(h_params, "mean_params");
assert(h_params.size() == (int)_mean_function.h_params_size());
_mean_function.set_h_params(h_params);
}
_mean_observation = _observations.colwise().mean();
recompute(true, true);
if (recompute)
this->recompute(true, true);
else {
archive.load(_matrixL, "matrixL");
archive.load(_alpha, "alpha");
}
}
protected:
......
......@@ -51,7 +51,10 @@
#include <boost/test/unit_test.hpp>
#include <limbo/mean/constant.hpp>
#include <limbo/mean/function_ard.hpp>
#include <limbo/model/gp.hpp>
#include <limbo/model/gp/mean_lf_opt.hpp>
#include <limbo/serialize/binary_archive.hpp>
#include <limbo/serialize/text_archive.hpp>
......@@ -68,9 +71,19 @@ struct Params {
};
struct opt_parallelrepeater : public limbo::defaults::opt_parallelrepeater {
};
struct kernel_maternfivehalves {
BO_PARAM(double, sigma_sq, 1);
BO_PARAM(double, l, 1);
};
struct mean_constant {
BO_PARAM(double, constant, 1);
};
};
BOOST_AUTO_TEST_CASE(test_text_archive)
template <typename GP, typename Archive>
void test_gp(const std::string& name, bool optimize_hp = true)
{
using namespace limbo;
......@@ -85,17 +98,18 @@ BOOST_AUTO_TEST_CASE(test_text_archive)
observations.push_back(tools::make_vector(std::cos(s(0) * s(1) * s(2))));
}
// 3-D inputs, 1-D outputs
model::GPOpt<Params> gp(3, 1);
GP gp(3, 1);
gp.compute(samples, observations);
gp.optimize_hyperparams();
if (optimize_hp)
gp.optimize_hyperparams();
// attempt to save
serialize::TextArchive a1("/tmp/test_model_text");
Archive a1(name);
gp.save(a1);
// attempt to load
model::GPOpt<Params> gp2(3, 1);
serialize::TextArchive a2("/tmp/test_model_text");
GP gp2(3, 1);
Archive a2(name);
gp2.load(a2);
BOOST_CHECK_EQUAL(gp.nb_samples(), gp2.nb_samples());
......@@ -109,45 +123,38 @@ BOOST_AUTO_TEST_CASE(test_text_archive)
BOOST_CHECK_SMALL(std::abs(std::get<0>(v1)[0] - std::get<0>(v2)[0]), 1e-10);
BOOST_CHECK_SMALL(std::abs(std::get<1>(v1) - std::get<1>(v2)), 1e-10);
}
}
BOOST_AUTO_TEST_CASE(test_bin_archive)
{
using namespace limbo;
// attempt to load without recomputing
GP gp3(3, 1);
Archive a3(name);
gp3.load(a3, false);
// our data (3-D inputs, 1-D outputs)
std::vector<Eigen::VectorXd> samples;
std::vector<Eigen::VectorXd> observations;
size_t n = 8;
for (size_t i = 0; i < n; i++) {
Eigen::VectorXd s = tools::random_vector(3).array() * 4.0 - 2.0;
samples.push_back(s);
observations.push_back(tools::make_vector(std::cos(s(0) * s(1) * s(2))));
}
// 3-D inputs, 1-D outputs
model::GPOpt<Params> gp(3, 1);
gp.compute(samples, observations);
gp.optimize_hyperparams();
// attempt to save
serialize::BinaryArchive a1("/tmp/test_model_bin");
gp.save(a1);
// attempt to load
model::GPOpt<Params> gp2(3, 1);
serialize::BinaryArchive a2("/tmp/test_model_bin");
gp2.load(a2);
BOOST_CHECK_EQUAL(gp.nb_samples(), gp2.nb_samples());
BOOST_CHECK_EQUAL(gp.nb_samples(), gp3.nb_samples());
// check that the two GPs make the same predictions
size_t k = 1000;
for (size_t i = 0; i < k; i++) {
Eigen::VectorXd s = tools::random_vector(3).array() * 4.0 - 2.0;
auto v1 = gp.query(s);
auto v2 = gp2.query(s);
auto v2 = gp3.query(s);
BOOST_CHECK_SMALL(std::abs(std::get<0>(v1)[0] - std::get<0>(v2)[0]), 1e-10);
BOOST_CHECK_SMALL(std::abs(std::get<1>(v1) - std::get<1>(v2)), 1e-10);
}
}
BOOST_AUTO_TEST_CASE(test_text_archive)
{
test_gp<limbo::model::GPOpt<Params>, limbo::serialize::TextArchive>("/tmp/gp_opt_text");
test_gp<limbo::model::GPBasic<Params>, limbo::serialize::TextArchive>("/tmp/gp_basic_text", false);
using GPMean = limbo::model::GP<Params, limbo::kernel::MaternFiveHalves<Params>, limbo::mean::FunctionARD<Params, limbo::mean::Constant<Params>>, limbo::model::gp::MeanLFOpt<Params>>;
test_gp<GPMean, limbo::serialize::TextArchive>("/tmp/gp_mean_text");
}
BOOST_AUTO_TEST_CASE(test_bin_archive)
{
test_gp<limbo::model::GPOpt<Params>, limbo::serialize::BinaryArchive>("/tmp/gp_opt_bin");
test_gp<limbo::model::GPBasic<Params>, limbo::serialize::BinaryArchive>("/tmp/gp_basic_bin", false);
using GPMean = limbo::model::GP<Params, limbo::kernel::MaternFiveHalves<Params>, limbo::mean::FunctionARD<Params, limbo::mean::Constant<Params>>, limbo::model::gp::MeanLFOpt<Params>>;
test_gp<GPMean, limbo::serialize::BinaryArchive>("/tmp/gp_mean_bin");
}
Supports Markdown
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