Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 : #ifdef MOOSE_LIBTORCH_ENABLED
10 :
11 : #include "ActiveLearningGaussianProcess.h"
12 :
13 : #include <petsctao.h>
14 : #include <petscdmda.h>
15 :
16 : #include "libmesh/petsc_vector.h"
17 : #include "libmesh/petsc_matrix.h"
18 :
19 : #include <math.h>
20 :
21 : registerMooseObject("StochasticToolsApp", ActiveLearningGaussianProcess);
22 :
23 : InputParameters
24 192 : ActiveLearningGaussianProcess::validParams()
25 : {
26 192 : InputParameters params = SurrogateTrainerBase::validParams();
27 192 : params.addClassDescription(
28 : "Permit re-training Gaussian Process surrogate model for active learning.");
29 384 : params.addRequiredParam<UserObjectName>("covariance_function", "Name of covariance function.");
30 384 : params.addParam<bool>(
31 384 : "standardize_params", true, "Standardize (center and scale) training parameters (x values)");
32 384 : params.addParam<bool>(
33 384 : "standardize_data", true, "Standardize (center and scale) training data (y values)");
34 384 : params.addParam<unsigned int>("num_iters", 1000, "Tolerance value for Adam optimization");
35 384 : params.addParam<unsigned int>("batch_size", 0, "The batch size for Adam optimization");
36 384 : params.addParam<Real>("learning_rate", 0.001, "The learning rate for Adam optimization");
37 384 : params.addParam<MooseEnum>(
38 : "optimizer",
39 576 : MooseEnum("adam=0 legacy_adam=1", "adam"),
40 : "The Adam optimizer semantics to use for Gaussian process hyperparameter tuning.");
41 384 : params.addParam<unsigned int>(
42 : "show_every_nth_iteration",
43 384 : 0,
44 : "Switch to show Adam optimization loss values at every nth step. If 0, nothing is showed.");
45 384 : params.addParam<std::vector<std::string>>(
46 : "tune_parameters", {}, "Select hyperparameters to be tuned");
47 384 : params.addParam<std::vector<Real>>("tuning_min", {}, "Minimum allowable tuning value");
48 384 : params.addParam<std::vector<Real>>("tuning_max", {}, "Maximum allowable tuning value");
49 192 : return params;
50 0 : }
51 :
52 96 : ActiveLearningGaussianProcess::ActiveLearningGaussianProcess(const InputParameters & parameters)
53 : : SurrogateTrainerBase(parameters),
54 : CovarianceInterface(parameters),
55 : SurrogateModelInterface(this),
56 192 : _gp(declareModelData<StochasticTools::GaussianProcess>("_gp")),
57 192 : _training_params(declareModelData<torch::Tensor>("_training_params")),
58 192 : _training_data(declareModelData<torch::Tensor>("_training_data")),
59 192 : _standardize_params(getParam<bool>("standardize_params")),
60 192 : _standardize_data(getParam<bool>("standardize_data")),
61 96 : _optimization_opts(StochasticTools::GaussianProcess::GPOptimizerOptions(
62 192 : getParam<unsigned int>("show_every_nth_iteration"),
63 192 : getParam<unsigned int>("num_iters"),
64 192 : getParam<unsigned int>("batch_size"),
65 192 : getParam<Real>("learning_rate"),
66 : 0.9,
67 : 0.999,
68 : 1e-7,
69 : 1e-4,
70 96 : getParam<MooseEnum>("optimizer")
71 96 : .getEnum<StochasticTools::GaussianProcess::OptimizerType>()))
72 : {
73 576 : _gp.initialize(getCovarianceFunctionByName(getParam<UserObjectName>("covariance_function")),
74 : getParam<std::vector<std::string>>("tune_parameters"),
75 : getParam<std::vector<Real>>("tuning_min"),
76 : getParam<std::vector<Real>>("tuning_max"));
77 96 : }
78 :
79 : void
80 227 : ActiveLearningGaussianProcess::reTrain(const std::vector<std::vector<Real>> & inputs,
81 : const std::vector<Real> & outputs) const
82 : {
83 : // Addtional error check for each re-train call of the GP surrogate
84 227 : if (inputs.size() != outputs.size())
85 0 : mooseError("Number of inputs (",
86 0 : inputs.size(),
87 : ") does not match number of outputs (",
88 0 : outputs.size(),
89 : ").");
90 227 : if (inputs.empty())
91 0 : mooseError("There is no data for retraining.");
92 :
93 : const auto input_size = inputs[0].size();
94 : std::vector<Real> flat_inputs;
95 227 : flat_inputs.reserve(outputs.size() * input_size);
96 :
97 2576 : for (const auto & input : inputs)
98 : {
99 2349 : if (input.size() != input_size)
100 0 : mooseError("All active learning retraining inputs must have the same dimension.");
101 2349 : flat_inputs.insert(flat_inputs.end(), input.begin(), input.end());
102 : }
103 :
104 454 : _training_params = LibtorchUtils::vectorToTensorCopy(
105 : flat_inputs, {cast_int<int64_t>(outputs.size()), cast_int<int64_t>(input_size)});
106 227 : _training_data =
107 227 : LibtorchUtils::vectorToTensorCopy(outputs, {cast_int<int64_t>(outputs.size()), 1});
108 :
109 227 : LibtorchUtils::moveToLibtorchDevice(_training_params, _app.getLibtorchDevice());
110 227 : LibtorchUtils::moveToLibtorchDevice(_training_data, _app.getLibtorchDevice());
111 :
112 : // Standardize (center and scale) training params
113 227 : if (_standardize_params)
114 227 : _gp.standardizeParameters(_training_params);
115 : // if not standardizing data set mean=0, std=1 for use in surrogate
116 : else
117 0 : _gp.paramStandardizer().set(0, 1, input_size);
118 :
119 : // Standardize (center and scale) training data
120 227 : if (_standardize_data)
121 227 : _gp.standardizeData(_training_data);
122 : // if not standardizing data set mean=0, std=1 for use in surrogate
123 : else
124 0 : _gp.dataStandardizer().set(0, 1);
125 :
126 : // Setup the covariance
127 227 : _gp.setupCovarianceMatrix(_training_params, _training_data, _optimization_opts);
128 227 : }
129 :
130 : const std::vector<Real> &
131 86 : ActiveLearningGaussianProcess::getLengthScales() const
132 : {
133 86 : return _gp.getLengthScales();
134 : }
135 :
136 : const StochasticTools::Standardizer &
137 0 : ActiveLearningGaussianProcess::getTrainingStandardizer() const
138 : {
139 0 : return _gp.getDataStandardizer();
140 : }
141 :
142 : void
143 0 : ActiveLearningGaussianProcess::getNormTrainingOuts(std::vector<Real> & norm_training_outs) const
144 : {
145 0 : norm_training_outs.resize(_training_data.size(0));
146 0 : const auto training_data = LibtorchUtils::toCPUContiguous(_training_data);
147 0 : const auto data_accessor = training_data.accessor<Real, 2>();
148 0 : for (unsigned int i = 0; i < norm_training_outs.size(); ++i)
149 0 : norm_training_outs[i] = data_accessor[i][0];
150 0 : }
151 :
152 : #endif
|