14 #include <petscdmda.h> 16 #include "libmesh/petsc_vector.h" 17 #include "libmesh/petsc_matrix.h" 28 const unsigned int num_iter,
29 const unsigned int batch_size,
30 const Real learning_rate,
35 : show_every_nth_iteration(show_every_nth_iteration),
37 batch_size(batch_size),
38 learning_rate(learning_rate),
50 const std::vector<std::string> & params_to_tune,
51 const std::vector<Real> & min,
52 const std::vector<Real> & max)
81 _K.resize(training_params.rows() * training_data.cols(),
82 training_params.rows() * training_data.cols());
86 training_data.reshaped(training_params.rows() * training_data.cols(), 1);
103 const std::vector<Real> & min_vector,
104 const std::vector<Real> & max_vector)
108 const bool upper_bounds_specified = min_vector.size();
109 const bool lower_bounds_specified = max_vector.size();
111 for (
const auto param_i :
index_range(params_to_tune))
113 const auto & hp = params_to_tune[param_i];
123 ::mooseError(
"The covariance parameter ", hp,
" could not be found!");
126 min = lower_bounds_specified ? min_vector[param_i] :
min;
127 max = upper_bounds_specified ? max_vector[param_i] :
max;
165 static constexpr
Real lambda = 1e-4;
173 Real store_loss = 0.0;
174 std::vector<Real> grad1;
177 std::vector<unsigned int> v_sequence(training_params.rows());
178 std::iota(std::begin(v_sequence), std::end(v_sequence), 0);
182 Moose::out <<
"OPTIMIZING GP HYPER-PARAMETERS USING Adam" << std::endl;
183 for (
unsigned int ss = 0; ss < opts.
num_iter; ++ss)
187 generator.
seed(0, 1980);
189 MooseUtils::shuffle<unsigned int>(v_sequence, generator, 0);
192 for (
unsigned int jj = 0; jj < training_params.cols(); ++jj)
193 inputs(ii, jj) = training_params(v_sequence[ii], jj);
195 for (
unsigned int jj = 0; jj < training_data.cols(); ++jj)
196 outputs(ii, jj) = training_data(v_sequence[ii], jj);
199 store_loss =
getLoss(inputs, outputs);
201 Moose::out <<
"Iteration: " << ss + 1 <<
" LOSS: " << store_loss << std::endl;
205 const auto first_index = std::get<0>(iter->second);
206 const auto num_entries = std::get<1>(iter->second);
207 for (
unsigned int ii = 0; ii < num_entries; ++ii)
209 const auto global_index = first_index + ii;
210 m0[global_index] = b1 * m0[global_index] + (1 - b1) * grad1[global_index];
212 b2 * v0[global_index] + (1 - b2) * grad1[global_index] * grad1[global_index];
213 m_hat = m0[global_index] / (1 -
std::pow(b1, (ss + 1)));
214 v_hat = v0[global_index] / (1 -
std::pow(b2, (ss + 1)));
216 theta[global_index] - 1.0 * (opts.
learning_rate * m_hat / (std::sqrt(v_hat) +
eps) +
217 lambda * theta[global_index]);
219 const auto min_value = std::get<2>(iter->second);
220 const auto max_value = std::get<3>(iter->second);
222 theta[global_index] = std::min(std::max(new_val, min_value), max_value);
230 Moose::out <<
"OPTIMIZED GP HYPER-PARAMETERS:" << std::endl;
232 Moose::out <<
"FINAL LOSS: " << store_loss << std::endl;
235 if (theta.size() > 0)
237 unsigned int count = 1;
249 RealEigenMatrix flattened_data = outputs.reshaped(outputs.rows() * outputs.cols(), 1);
253 Real log_likelihood = 0;
255 log_likelihood += -std::log(
_K.determinant());
256 log_likelihood -=
_batch_size * std::log(2 * M_PI);
257 log_likelihood = -log_likelihood / 2;
258 return log_likelihood;
266 std::vector<Real> grad_vec;
270 std::string hyper_param_name = iter->first;
271 const auto first_index = std::get<0>(iter->second);
272 const auto num_entries = std::get<1>(iter->second);
273 for (
unsigned int ii = 0; ii < num_entries; ++ii)
275 const auto global_index = first_index + ii;
278 grad_vec[global_index] = -tmp.trace() / 2.0;
286 const std::unordered_map<std::string, std::tuple<unsigned int, unsigned int, Real, Real>> &
288 const std::unordered_map<std::string, Real> & scalar_map,
289 const std::unordered_map<std::string, std::vector<Real>> & vector_map,
290 std::vector<Real> & vec)
const 292 for (
auto iter : tuning_data)
294 const std::string & param_name = iter.first;
295 const auto scalar_it = scalar_map.find(param_name);
296 if (scalar_it != scalar_map.end())
297 vec[std::get<0>(iter.second)] = scalar_it->second;
300 const auto vector_it = vector_map.find(param_name);
301 if (vector_it != vector_map.end())
302 for (
unsigned int ii = 0; ii < std::get<1>(iter.second); ++ii)
303 vec[std::get<0>(iter.second) + ii] = (vector_it->second)[ii];
310 const std::unordered_map<std::string, std::tuple<unsigned int, unsigned int, Real, Real>> &
312 std::unordered_map<std::string, Real> & scalar_map,
313 std::unordered_map<std::string, std::vector<Real>> & vector_map,
314 const std::vector<Real> & vec)
const 316 for (
auto iter : tuning_data)
318 const std::string & param_name = iter.first;
319 if (scalar_map.find(param_name) != scalar_map.end())
320 scalar_map[param_name] = vec[std::get<0>(iter.second)];
321 else if (vector_map.find(param_name) != vector_map.end())
322 for (
unsigned int ii = 0; ii < std::get<1>(iter.second); ++ii)
323 vector_map[param_name][ii] = vec[std::get<0>(iter.second) + ii];
331 dataStore(std::ostream & stream, Eigen::LLT<RealEigenMatrix> & decomp,
void * context)
341 dataLoad(std::istream & stream, Eigen::LLT<RealEigenMatrix> & decomp,
void * context)
345 decomp.compute(L * L.transpose());
void loadHyperParamMap(const std::unordered_map< std::string, Real > &map, const std::unordered_map< std::string, std::vector< Real >> &vec_map)
Load some hyperparameters into the local maps contained in this object.
void seed(std::size_t i, unsigned int seed)
Base class for covariance functions that are used in Gaussian Processes.
auto max(const L &left, const R &right)
void dataLoad(std::istream &stream, Eigen::LLT< RealEigenMatrix > &decomp, void *context)
const std::string & name() const
void dataStore(std::ostream &stream, Eigen::LLT< RealEigenMatrix > &decomp, void *context)
const std::string & type() const
const std::vector< UserObjectName > & dependentCovarianceNames() const
Get the names of the dependent covariances.
void buildHyperParamMap(std::unordered_map< std::string, Real > &map, std::unordered_map< std::string, std::vector< Real >> &vec_map) const
Populates the input maps with the owned hyperparameters.
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealEigenMatrix
std::string stringify(const T &t)
void dependentCovarianceTypes(std::map< UserObjectName, std::string > &name_type_map) const
Populate a map with the names and types of the dependent covariance functions.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void computeCovarianceMatrix(RealEigenMatrix &K, const RealEigenMatrix &x, const RealEigenMatrix &xp, const bool is_self_covariance) const =0
Generates the Covariance Matrix given two sets of points in the parameter space.
static const std::string alpha
unsigned int numOutputs() const
Return the number of outputs assumed for this covariance function.
auto min(const L &left, const R &right)
virtual bool computedKdhyper(RealEigenMatrix &dKdhp, const RealEigenMatrix &x, const std::string &hyper_param_name, unsigned int ind) const
Redirect dK/dhp for hyperparameter "hp".
MooseUnits pow(const MooseUnits &, int)
virtual bool getTuningData(const std::string &name, unsigned int &size, Real &min, Real &max) const
Get the default minimum and maximum and size of a hyperparameter.
auto index_range(const T &sizable)
virtual bool isTunable(const std::string &name) const
Check if a given parameter is tunable.