https://mooseframework.inl.gov
GenericActiveLearner.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 #pragma once
12 
13 #include "GeneralReporter.h"
16 #include "GaussianProcess.h"
17 #include "SurrogateModel.h"
22 
23 // forward declarations
24 template <typename SamplerType>
26 
28 
33 template <typename SamplerType>
37 
38 {
39 public:
42  virtual void initialize() override {}
43  virtual void finalize() override {}
44  virtual void execute() override;
45 
46 protected:
52  virtual void setupGPData(const std::vector<Real> & data_out, const DenseMatrix<Real> & data_in);
53 
58  virtual void computeGPOutput(std::vector<Real> & eval_outputs);
59 
63  virtual Real computeConvergenceValue();
64 
68  virtual void evaluateGPTest();
69 
74  virtual void setupGeneric();
75 
81  virtual void includeAdditionalInputs();
82 
88  virtual void getAcquisition(std::vector<Real> & acq_new, std::vector<unsigned int> & indices);
89 
91  SamplerType & _al_sampler;
92 
94  unsigned int _n_dim;
95 
98 
100  const std::vector<std::vector<Real>> & _inputs_test;
101 
103  const std::vector<Real> & _output_value;
104 
106  std::vector<Real> & _output_comm;
107 
109  std::vector<unsigned int> & _sorted_indices;
110 
113 
116 
119 
121  std::vector<Real> & _acquisition_value;
122 
125 
127  std::vector<std::vector<Real>> _inputs_test_modified;
128 
130  std::vector<std::vector<Real>> & _inputs_required;
131 
133  const bool & _penalize_acquisition;
134 
137 
139  std::vector<std::vector<Real>> _gp_inputs;
140 
142  std::vector<Real> _gp_outputs;
143 
145  std::vector<Real> _gp_outputs_test;
146 
148  std::vector<Real> _gp_std_test;
149 
151  std::vector<Real> _length_scales;
152 
154  std::vector<Real> _generic;
155 
157  std::vector<Real> _eval_outputs_current;
158 };
159 
160 template <typename SamplerType>
163 {
166  params.addClassDescription("A generic reporter to support parallel active learning: re-trains GP "
167  "and picks the next best batch.");
168  params.addRequiredParam<ReporterName>("output_value",
169  "Value of the model output from the SubApp.");
170  params.addParam<ReporterValueName>(
171  "outputs_required",
172  "outputs_required",
173  "Modified value of the model output from this reporter class.");
174  params.addRequiredParam<SamplerName>("sampler", "The sampler object.");
175  params.addRequiredParam<UserObjectName>("al_gp", "Active learning GP trainer.");
176  params.addRequiredParam<UserObjectName>("gp_evaluator", "Evaluator for the trained GP.");
177  params.addParam<ReporterValueName>(
178  "sorted_indices",
179  "sorted_indices",
180  "The sorted sample indices in order of importance to evaluate the subApp.");
181  params.addParam<ReporterValueName>(
182  "acquisition_function",
183  "acquisition_function",
184  "The values of the acquistion function in the current iteration.");
185  params.addParam<ReporterValueName>(
186  "convergence_value", "convergence_value", "Value to measure convergence of active learning.");
187  params.addParam<ReporterValueName>(
188  "inputs", "inputs", "Modified value of the model inputs from this reporter class.");
189  params.addRequiredParam<UserObjectName>("acquisition", "Name of the acquisition function.");
190  params.addParam<bool>(
191  "penalize_acquisition",
192  true,
193  "Set true to prevent clustering of the best batch inputs when operating in parallel.");
194  return params;
195 }
196 
197 template <typename SamplerType>
199  const InputParameters & parameters)
200  : GeneralReporter(parameters),
201  ParallelAcquisitionInterface(parameters),
203  _al_sampler(getSampler<SamplerType>("sampler")),
204  _n_dim(_al_sampler.getNumberOfCols()),
205  _props(_al_sampler.getNumParallelProposals()),
206  _inputs_test(_al_sampler.getSampleTries()),
207  _output_value(getReporterValue<std::vector<Real>>("output_value", REPORTER_MODE_DISTRIBUTED)),
208  _output_comm(declareValue<std::vector<Real>>("outputs_required")),
209  _sorted_indices(declareValue<std::vector<unsigned int>>("sorted_indices")),
210  _al_gp(getUserObject<ActiveLearningGaussianProcess>("al_gp")),
211  _gp_eval(getSurrogateModel<GaussianProcessSurrogate>("gp_evaluator")),
212  _acquisition_obj(getParallelAcquisitionFunctionByName(getParam<UserObjectName>("acquisition"))),
213  _acquisition_value(declareValue<std::vector<Real>>("acquisition_function")),
214  _convergence_value(declareValue<Real>("convergence_value")),
215  _inputs_required(declareValue<std::vector<std::vector<Real>>>("inputs")),
216  _penalize_acquisition(getParam<bool>("penalize_acquisition")),
217  _check_step(std::numeric_limits<int>::max())
218 {
219  // Setting up the variable sizes to facilitate active learning.
220  _gp_outputs_test.resize(_inputs_test.size());
221  _gp_std_test.resize(_inputs_test.size());
222  _acquisition_value.resize(_props);
223  _length_scales.resize(_n_dim);
225  _generic.resize(1);
226  _inputs_required.resize(_props, std::vector<Real>(_n_dim, 0.0));
227  _sorted_indices.resize(_props, 1u);
228 }
229 
230 template <typename SamplerType>
231 void
232 GenericActiveLearnerTempl<SamplerType>::setupGPData(const std::vector<Real> & data_out,
233  const DenseMatrix<Real> & data_in)
234 {
235  for (unsigned int i = 0; i < data_out.size(); ++i)
236  {
237  for (unsigned int j = 0; j < _n_dim; ++j)
238  _inputs_required[i][j] = data_in(i, j);
239  _gp_inputs.push_back(_inputs_required[i]);
240  _gp_outputs.push_back(data_out[i]);
241  }
242 }
243 
244 template <typename SamplerType>
245 void
247 {
248  for (unsigned int i = 0; i < eval_outputs.size(); ++i)
249  eval_outputs[i] = _gp_eval.evaluate(_gp_inputs[i]);
250 }
251 
252 template <typename SamplerType>
253 void
255 {
256  _generic = _gp_outputs;
257 }
258 
259 template <typename SamplerType>
260 void
262 {
263  _inputs_test_modified = _inputs_test;
264 }
265 
266 template <typename SamplerType>
267 void
269  std::vector<unsigned int> & indices)
270 {
271  std::vector<Real> acq;
272  acq.resize(_inputs_test.size());
273  includeAdditionalInputs();
274  _acquisition_obj.computeAcquisition(
275  acq, _gp_outputs_test, _gp_std_test, _inputs_test_modified, _gp_inputs, _generic);
276  acq_new = acq;
277  if (_penalize_acquisition)
278  _acquisition_obj.penalizeAcquisition(
279  acq_new, indices, acq, _length_scales, _inputs_test_modified);
280 }
281 
282 template <typename SamplerType>
283 Real
285 {
286  Real convergence_value = 0.0;
287  for (unsigned int ii = 0; ii < _output_comm.size(); ++ii)
288  convergence_value += Utility::pow<2>(_output_comm[ii] - _eval_outputs_current[ii]);
289  convergence_value = std::sqrt(convergence_value) / _output_comm.size();
290  return convergence_value;
291 }
292 
293 template <typename SamplerType>
294 void
296 {
297  for (unsigned int i = 0; i < _gp_outputs_test.size(); ++i)
298  _gp_outputs_test[i] = _gp_eval.evaluate(_inputs_test[i], _gp_std_test[i]);
299 }
300 
301 template <typename SamplerType>
302 void
304 {
305  if (_al_sampler.getNumberOfLocalRows() == 0 || _check_step == _t_step)
306  {
307  _check_step = _t_step;
308  return;
309  }
310 
311  DenseMatrix<Real> data_in(_al_sampler.getNumberOfRows(), _al_sampler.getNumberOfCols());
312  for (dof_id_type ss = _al_sampler.getLocalRowBegin(); ss < _al_sampler.getLocalRowEnd(); ++ss)
313  {
314  const auto data = _al_sampler.getNextLocalRow();
315  for (unsigned int j = 0; j < _al_sampler.getNumberOfCols(); ++j)
316  data_in(ss, j) = data[j];
317  }
318  _communicator.sum(data_in.get_values());
319  _output_comm = _output_value;
320  _communicator.allgather(_output_comm);
321 
322  if (_t_step > 1)
323  {
324  // Setup the GP training data
325  setupGPData(_output_comm, data_in);
326 
327  // Compute the convergence value before re-training the GP
328  if (_t_step > 2)
329  {
330  computeGPOutput(_eval_outputs_current);
331  _convergence_value = computeConvergenceValue();
332  }
333 
334  // Retrain the GP and get the length scales
335  _al_gp.reTrain(_gp_inputs, _gp_outputs);
336  _length_scales = _al_gp.getLengthScales();
337 
338  // Evaluate the GP on all the test samples sent by the Sampler
339  evaluateGPTest();
340 
341  // Setup the generic variable for acquisition computation (depends on the objective:
342  // optimization, UQ, etc.)
343  setupGeneric();
344 
345  // Get the acquisition function values and ordering of indices as per the acquisition
346  std::vector<Real> acq_new;
347  std::vector<unsigned int> indices;
348  indices.resize(_inputs_test.size());
349  getAcquisition(acq_new, indices);
350 
351  // Output the acquisition function values and the best ordering of the indices
352  std::copy_n(indices.begin(), _props, _sorted_indices.begin());
353  std::copy_n(acq_new.begin(), _props, _acquisition_value.begin());
354  }
355  else
356  std::iota(_sorted_indices.begin(), _sorted_indices.end(), 0);
357 
358  // Track the current step
359  _check_step = _t_step;
360 }
361 
362 #endif
A generic reporter to support parallel active learning: re-trains GP and picks the next best batch...
std::vector< std::vector< Real > > _inputs_test_modified
Storage for all the modified proposed samples to test the GP model.
std::vector< std::vector< Real > > _gp_inputs
Storage for the GP re-training inputs.
const std::vector< Real > & _output_value
Model output value from SubApp.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
GenericActiveLearnerTempl< GenericActiveLearningSampler > GenericActiveLearner
virtual void computeGPOutput(std::vector< Real > &eval_outputs)
Computes the outputs of the trained GP model.
std::vector< Real > _eval_outputs_current
The GP outputs from the current iteration before re-training (to evaluate convergence) ...
const InputParameters & parameters() const
std::vector< Real > & _acquisition_value
The acquistion function values in the current iteration.
const SurrogateModel & _gp_eval
The GP evaluator object that permits re-evaluations.
virtual void initialize() override
std::vector< Real > _length_scales
Storage for the length scales after the GP training.
static InputParameters validParams()
dof_id_type _props
Storage for the number of parallel proposals.
All ParallelAcquisition functions should inherit from this class.
void addRequiredParam(const std::string &name, const std::string &doc_string)
unsigned int _n_dim
The input dimension for GP, equal to Sampler columns.
auto max(const L &left, const R &right)
std::vector< unsigned int > & _sorted_indices
The selected sample indices to evaluate the subApp.
virtual void execute() override
virtual void finalize() override
const std::vector< std::vector< Real > > & _inputs_test
Storage for all the proposed samples to test the GP model.
virtual void evaluateGPTest()
Evaluate the GP on all the test samples sent by the Sampler.
const bool & _penalize_acquisition
Penalize acquisition to prevent clustering when operating in parallel.
static InputParameters validParams()
Real & _convergence_value
For monitoring convergence of active learning.
std::vector< Real > & _output_comm
Modified value of model output by this reporter class.
virtual void includeAdditionalInputs()
Include additional inputs before evaluating the acquisition function.
const ReporterMode REPORTER_MODE_DISTRIBUTED
ParallelAcquisitionFunctionBase & _acquisition_obj
Storage for the parallel acquisition object to be utilized.
virtual void setupGeneric()
Setup the generic variable for acquisition computation (depends on the objective: optimization...
GenericActiveLearnerTempl(const InputParameters &parameters)
virtual Real computeConvergenceValue()
Computes the convergence value during active learning.
virtual void setupGPData(const std::vector< Real > &data_out, const DenseMatrix< Real > &data_in)
Sets up the training data for the GP model.
virtual void getAcquisition(std::vector< Real > &acq_new, std::vector< unsigned int > &indices)
Output the acquisition function values and ordering of the indices.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Interface for objects that need to use samplers.
const ActiveLearningGaussianProcess & _al_gp
The active learning GP trainer that permits re-training.
void addClassDescription(const std::string &doc_string)
std::vector< Real > _gp_outputs
Storage for the GP re-training outputs.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< Real > _gp_std_test
Outputs of GP model standard deviation for the test samples.
SamplerType & _al_sampler
The base sampler.
std::vector< std::vector< Real > > & _inputs_required
Transmit the required inputs to the json file.
std::vector< Real > _generic
A generic parameter to be passed to the acquisition function.
int _check_step
Ensure that the MCMC algorithm proceeds in a sequential fashion.
void ErrorVector unsigned int
std::vector< Real > _gp_outputs_test
Outputs of GP model for the test samples.
uint8_t dof_id_type