https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
24template <typename SamplerType>
26
28
33template <typename SamplerType>
37
38{
39public:
42 virtual void initialize() override {}
43 virtual void finalize() override {}
44 virtual void execute() override;
45
46protected:
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
64
68 virtual void evaluateGPTest();
69
74 virtual void setupGeneric();
75
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
97 dof_id_type _props;
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
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
160template <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
197template <typename SamplerType>
199 const InputParameters & parameters)
200 : GeneralReporter(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());
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
230template <typename SamplerType>
231void
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
244template <typename SamplerType>
245void
247{
248 for (unsigned int i = 0; i < eval_outputs.size(); ++i)
249 eval_outputs[i] = _gp_eval.evaluate(_gp_inputs[i]);
250}
251
252template <typename SamplerType>
253void
255{
256 _generic = _gp_outputs;
257}
258
259template <typename SamplerType>
260void
262{
263 _inputs_test_modified = _inputs_test;
264}
265
266template <typename SamplerType>
267void
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
282template <typename SamplerType>
283Real
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
293template <typename SamplerType>
294void
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
301template <typename SamplerType>
302void
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
GenericActiveLearnerTempl< GenericActiveLearningSampler > GenericActiveLearner
const ReporterMode REPORTER_MODE_DISTRIBUTED
void ErrorVector unsigned int
static InputParameters validParams()
A generic reporter to support parallel active learning: re-trains GP and picks the next best batch.
std::vector< Real > _eval_outputs_current
The GP outputs from the current iteration before re-training (to evaluate convergence)
static InputParameters validParams()
Real & _convergence_value
For monitoring convergence of active learning.
GenericActiveLearnerTempl(const InputParameters &parameters)
virtual void getAcquisition(std::vector< Real > &acq_new, std::vector< unsigned int > &indices)
Output the acquisition function values and ordering of the indices.
virtual void initialize() override
std::vector< std::vector< Real > > _gp_inputs
Storage for the GP re-training inputs.
const bool & _penalize_acquisition
Penalize acquisition to prevent clustering when operating in parallel.
std::vector< std::vector< Real > > & _inputs_required
Transmit the required inputs to the json file.
const SurrogateModel & _gp_eval
The GP evaluator object that permits re-evaluations.
unsigned int _n_dim
The input dimension for GP, equal to Sampler columns.
std::vector< Real > _gp_outputs
Storage for the GP re-training outputs.
const ActiveLearningGaussianProcess & _al_gp
The active learning GP trainer that permits re-training.
virtual void computeGPOutput(std::vector< Real > &eval_outputs)
Computes the outputs of the trained GP model.
std::vector< unsigned int > & _sorted_indices
The selected sample indices to evaluate the subApp.
std::vector< Real > _length_scales
Storage for the length scales after the GP training.
virtual void setupGPData(const std::vector< Real > &data_out, const DenseMatrix< Real > &data_in)
Sets up the training data for the GP model.
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.
virtual void execute() override
std::vector< std::vector< Real > > _inputs_test_modified
Storage for all the modified proposed samples to test the GP model.
virtual void setupGeneric()
Setup the generic variable for acquisition computation (depends on the objective: optimization,...
SamplerType & _al_sampler
The base sampler.
dof_id_type _props
Storage for the number of parallel proposals.
std::vector< Real > _gp_std_test
Outputs of GP model standard deviation for the test samples.
virtual void includeAdditionalInputs()
Include additional inputs before evaluating the acquisition function.
ParallelAcquisitionFunctionBase & _acquisition_obj
Storage for the parallel acquisition object to be utilized.
std::vector< Real > & _acquisition_value
The acquistion function values in the current iteration.
std::vector< Real > _gp_outputs_test
Outputs of GP model for the test samples.
std::vector< Real > & _output_comm
Modified value of model output by this reporter class.
virtual Real computeConvergenceValue()
Computes the convergence value during active learning.
const std::vector< Real > & _output_value
Model output value from SubApp.
std::vector< Real > _generic
A generic parameter to be passed to the acquisition function.
virtual void finalize() override
int _check_step
Ensure that the MCMC algorithm proceeds in a sequential fashion.
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const InputParameters & parameters() const
All ParallelAcquisition functions should inherit from this class.
Interface for objects that need to use samplers.