https://mooseframework.inl.gov
Loading...
Searching...
No Matches
GaussianProcess.C
Go to the documentation of this file.
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 "GaussianProcess.h"
12#include "FEProblemBase.h"
13
14#include <petsctao.h>
15#include <petscdmda.h>
16
17#include "libmesh/petsc_vector.h"
18#include "libmesh/petsc_matrix.h"
19
20#include <cmath>
21
22#include "MooseRandom.h"
23#include "Shuffle.h"
24
25#include <torch/optim/adam.h>
26
27namespace StochasticTools
28{
29
30namespace
31{
32
33using HyperParameterMap = GaussianProcess::HyperParameterMap;
34
35torch::Tensor
36flattenOutputData(const torch::Tensor & output_data)
37{
38 mooseAssert(output_data.dim() == 2, "GaussianProcess output data must be rank-2.");
39 return torch::reshape(torch::transpose(output_data, 0, 1),
40 {output_data.size(0) * output_data.size(1), 1});
41}
42
43torch::TensorOptions
44doubleOptionsLike(const torch::Tensor & tensor)
45{
46 return tensor.options().dtype(at::kDouble);
47}
48
49torch::Tensor
50toOptions(const torch::Tensor & tensor, const torch::TensorOptions & options)
51{
52 auto result = tensor.to(options.device());
53 if (result.scalar_type() != at::kDouble)
54 result = result.to(at::kDouble);
55 return result;
56}
57
58std::vector<Real>
59exportHyperParameter(const torch::Tensor & tensor)
60{
63 mooseError("Unsupported hyperparameter rank ", tensor.dim(), ".");
64 auto cpu_tensor = LibtorchUtils::toCPUContiguous(tensor);
65 if (cpu_tensor.scalar_type() != at::kDouble)
66 cpu_tensor = cpu_tensor.to(at::kDouble).contiguous();
67 const auto flattened = cpu_tensor.reshape({-1});
68 return {flattened.data_ptr<Real>(), flattened.data_ptr<Real>() + flattened.numel()};
69}
70
71torch::Tensor
72buildVectorHyperParameter(const std::vector<Real> & values, const torch::TensorOptions & options)
73{
74 auto tensor = torch::empty({long(values.size())}, torch::TensorOptions().dtype(at::kDouble));
75 auto tensor_accessor = tensor.accessor<Real, 1>();
76 for (const auto index : index_range(values))
77 tensor_accessor[index] = values[index];
78 return toOptions(tensor, options);
79}
80
81void
82moveHyperParameters(HyperParameterMap & hyperparameters, const torch::TensorOptions & options)
83{
84 for (auto & iter : hyperparameters)
85 iter.second = toOptions(iter.second, options);
86}
87
88void
89updateHyperParameter(torch::Tensor & tensor,
90 const std::vector<Real> & values,
91 const std::string & name)
92{
93 const auto options = doubleOptionsLike(tensor);
95 {
96 mooseAssert(values.size() == 1, "Scalar hyperparameter update requires a single value.");
97 tensor =
98 toOptions(torch::tensor(values[0], torch::TensorOptions().dtype(at::kDouble)), options);
99 }
101 tensor = buildVectorHyperParameter(values, options);
102 else
103 mooseError("Unsupported hyperparameter rank ", tensor.dim(), " for ", name, ".");
104}
105
106} // namespace
107
108GaussianProcess::GPOptimizerOptions::GPOptimizerOptions(const unsigned int show_every_nth_iteration,
109 const unsigned int num_iter,
110 const unsigned int batch_size,
111 const Real learning_rate,
112 const Real b1,
113 const Real b2,
114 const Real eps,
115 const Real lambda,
116 const OptimizerType optimizer_type)
117 : show_every_nth_iteration(show_every_nth_iteration),
118 num_iter(num_iter),
119 batch_size(batch_size),
120 learning_rate(learning_rate),
121 b1(b1),
122 b2(b2),
123 eps(eps),
124 lambda(lambda),
125 optimizer_type(optimizer_type)
126{
127}
128
130
131void
133 const std::vector<std::string> & params_to_tune,
134 const std::vector<Real> & min,
135 const std::vector<Real> & max)
136{
137 linkCovarianceFunction(covariance_function);
138 generateTuningMap(params_to_tune, min, max);
139}
140
141void
151
152void
153GaussianProcess::setupCovarianceMatrix(const torch::Tensor & training_params,
154 const torch::Tensor & training_data,
155 const GPOptimizerOptions & opts)
156{
157 const auto options = doubleOptionsLike(training_params);
158 const auto params = toOptions(training_params, options);
159 const auto data = toOptions(training_data, options);
160
161 mooseAssert(params.dim() == 2, "GaussianProcess training parameters must be rank-2.");
162 mooseAssert(data.dim() == 2, "GaussianProcess training responses must be rank-2.");
163
164 const auto num_samples = params.size(0);
165 mooseAssert(data.size(0) == num_samples,
166 "Training parameter and response sample counts must match.");
167 mooseAssert(data.size(1) == _num_outputs,
168 "Training response dimension does not match the covariance output dimension.");
169
170 const bool batch_decision = opts.batch_size > 0 && (opts.batch_size <= num_samples);
171 _batch_size = batch_decision ? opts.batch_size : num_samples;
172
173 _hyperparam_map.clear();
175 moveHyperParameters(_hyperparam_map, options);
177
178 if (_tuning_data.size())
179 tuneHyperParamsAdam(params, data, opts);
180
181 _covariance_function->computeCovarianceMatrix(_K, params, params, true);
182 const auto flattened_tensor = flattenOutputData(data);
183
184 // Compute the Cholesky decomposition and inverse action of the covariance matrix.
185 setupStoredMatrices(flattened_tensor);
186}
187
188void
189GaussianProcess::setupStoredMatrices(const torch::Tensor & input)
190{
191 _K_cho_decomp = torch::linalg_cholesky(_K);
192 _K_results_solve = torch::cholesky_solve(input, _K_cho_decomp);
193}
194
195void
196GaussianProcess::generateTuningMap(const std::vector<std::string> & params_to_tune,
197 const std::vector<Real> & min_vector,
198 const std::vector<Real> & max_vector)
199{
200 _num_tunable = 0;
201
202 const bool upper_bounds_specified = min_vector.size();
203 const bool lower_bounds_specified = max_vector.size();
204
205 for (const auto param_i : index_range(params_to_tune))
206 {
207 const auto & hp = params_to_tune[param_i];
209 {
210 unsigned int size;
211 Real min;
212 Real max;
213 // Get size and default min/max
214 const bool found = _covariance_function->getTuningData(hp, size, min, max);
215
216 if (!found)
217 ::mooseError("The covariance parameter ", hp, " could not be found!");
218
219 // Check for overridden min/max
220 min = lower_bounds_specified ? min_vector[param_i] : min;
221 max = upper_bounds_specified ? max_vector[param_i] : max;
222 // Save data in tuple
223 _tuning_data[hp] = std::make_tuple(_num_tunable, size, min, max);
224 _num_tunable += size;
225 }
226 }
227}
228
229void
230GaussianProcess::standardizeParameters(torch::Tensor & data, bool keep_moments)
231{
232 if (!keep_moments)
235}
236
237void
238GaussianProcess::standardizeData(torch::Tensor & data, bool keep_moments)
239{
240 if (!keep_moments)
243}
244
245void
246GaussianProcess::tuneHyperParamsAdam(const torch::Tensor & training_params,
247 const torch::Tensor & training_data,
248 const GPOptimizerOptions & opts)
249{
250 const auto options = doubleOptionsLike(training_params);
251 std::vector<Real> theta_values(_num_tunable, 0.0);
252
253 mapToVec(_tuning_data, _hyperparam_map, theta_values);
254
255 auto theta = torch::from_blob(theta_values.data(),
256 {static_cast<long>(_num_tunable)},
257 torch::TensorOptions().dtype(at::kDouble))
258 .clone()
259 .to(options.device());
260
261 auto adam_options = torch::optim::AdamOptions(opts.learning_rate);
262 adam_options.betas(std::make_tuple(opts.b1, opts.b2));
263 adam_options.eps(opts.eps);
264 // The legacy MOOSE shrink term is decoupled and not learning-rate-scaled, so it cannot be
265 // represented by Adam's coupled weight_decay option.
266 adam_options.weight_decay(0.0);
267 torch::optim::Adam optimizer({theta}, adam_options);
268
269 Real store_loss = 0.0;
270 std::vector<Real> grad_values;
271 const bool use_legacy_update = opts.optimizer_type == OptimizerType::LegacyAdam;
272
273 const bool use_full_batch = _batch_size == static_cast<unsigned int>(training_params.size(0));
274 // Preserve the existing deterministic shuffle sequence for mini-batches, but avoid rebuilding
275 // shuffled full-batch tensors when the batch already contains every training sample.
276 std::vector<unsigned int> v_sequence;
277 if (!use_full_batch)
278 {
279 v_sequence.resize(training_params.size(0));
280 std::iota(std::begin(v_sequence), std::end(v_sequence), 0);
281 }
283 Moose::out << "OPTIMIZING GP HYPER-PARAMETERS USING "
284 << (use_legacy_update ? "legacy-compatible Adam" : "Adam") << std::endl;
285 for (unsigned int ss = 0; ss < opts.num_iter; ++ss)
286 {
287 torch::Tensor inputs;
288 torch::Tensor outputs;
289 if (use_full_batch)
290 {
291 inputs = training_params;
292 outputs = training_data;
293 }
294 else
295 {
296 MooseRandom generator;
297 generator.seed(0, 1980);
298 generator.saveState();
299 MooseUtils::shuffle<unsigned int>(v_sequence, generator, 0);
300
301 std::vector<int64_t> batch_indices_vec(v_sequence.begin(), v_sequence.begin() + _batch_size);
302 auto batch_indices = torch::tensor(
303 batch_indices_vec, torch::TensorOptions().dtype(torch::kLong).device(options.device()));
304 inputs = torch::index_select(training_params, 0, batch_indices);
305 outputs = torch::index_select(training_data, 0, batch_indices);
306 }
307
308 store_loss = getLoss(inputs, outputs);
309 if (opts.show_every_nth_iteration && ((ss + 1) % opts.show_every_nth_iteration == 0))
310 Moose::out << "Iteration: " << ss + 1 << " LOSS: " << store_loss << std::endl;
311
312 grad_values = getGradient(inputs);
313 auto grad = torch::from_blob(grad_values.data(),
314 {static_cast<long>(_num_tunable)},
315 torch::TensorOptions().dtype(at::kDouble))
316 .clone()
317 .to(options.device());
318 optimizer.zero_grad();
319 theta.mutable_grad() = grad;
320 torch::Tensor theta_before_step;
321 if (use_legacy_update)
322 theta_before_step = theta.detach().clone();
323 optimizer.step();
324
325 {
326 torch::NoGradGuard no_grad;
327 if (use_legacy_update)
328 theta -= opts.lambda * theta_before_step;
329 for (auto iter = _tuning_data.begin(); iter != _tuning_data.end(); ++iter)
330 {
331 const auto first_index = std::get<0>(iter->second);
332 const auto num_entries = std::get<1>(iter->second);
333 const auto min_value = std::get<2>(iter->second);
334 const auto max_value = std::get<3>(iter->second);
335 theta.slice(0, first_index, first_index + num_entries).clamp_(min_value, max_value);
336 }
337 }
338
339 const auto theta_export = LibtorchUtils::toCPUContiguous(theta);
340 const auto * theta_data = theta_export.data_ptr<Real>();
341 theta_values.assign(theta_data, theta_data + theta_export.numel());
342 vecToMap(_tuning_data, _hyperparam_map, theta_values);
344 }
346 {
347 Moose::out << "OPTIMIZED GP HYPER-PARAMETERS:" << std::endl;
348 Moose::out << Moose::stringify(theta_values) << std::endl;
349 Moose::out << "FINAL LOSS: " << store_loss << std::endl;
350 }
351
352 if (theta_values.size() > 0)
353 {
354 unsigned int count = 1;
356 for (unsigned int i = 0; i < _num_tunable - count; ++i)
357 _length_scales[i] = theta_values[i + 1];
358 }
359}
360
361Real
362GaussianProcess::getLoss(torch::Tensor & inputs, torch::Tensor & outputs)
363{
364 _covariance_function->computeCovarianceMatrix(_K, inputs, inputs, true);
365 const auto flattened_data = flattenOutputData(outputs);
366
367 setupStoredMatrices(flattened_data);
368
369 Real log_likelihood = 0;
370 log_likelihood +=
371 -1 * torch::mm(torch::transpose(flattened_data, 0, 1), _K_results_solve).item<Real>();
372 log_likelihood += -2.0 * torch::sum(torch::log(torch::diagonal(_K_cho_decomp))).item<Real>();
373 log_likelihood -= flattened_data.size(0) * std::log(2 * M_PI);
374 log_likelihood = -log_likelihood / 2;
375 return log_likelihood;
376}
377
378std::vector<Real>
379GaussianProcess::getGradient(torch::Tensor & inputs) const
380{
381 torch::Tensor dKdhp = torch::empty({_num_outputs * _batch_size, _num_outputs * _batch_size},
382 doubleOptionsLike(inputs));
383 std::vector<Real> grad_vec;
384 grad_vec.resize(_num_tunable);
385 for (auto iter = _tuning_data.begin(); iter != _tuning_data.end(); ++iter)
386 {
387 std::string hyper_param_name = iter->first;
388 const auto first_index = std::get<0>(iter->second);
389 const auto num_entries = std::get<1>(iter->second);
390 for (unsigned int ii = 0; ii < num_entries; ++ii)
391 {
392 const auto global_index = first_index + ii;
393 _covariance_function->computedKdhyper(dKdhp, inputs, hyper_param_name, ii);
394 const auto quadratic_form =
395 torch::mm(torch::transpose(_K_results_solve, 0, 1), torch::mm(dKdhp, _K_results_solve))
396 .item<Real>();
397 const auto inverse_trace =
398 torch::trace(torch::cholesky_solve(dKdhp, _K_cho_decomp)).item<Real>();
399 grad_vec[global_index] = (inverse_trace - quadratic_form) / 2.0;
400 }
401 }
402 return grad_vec;
403}
404
405void
407 const std::unordered_map<std::string, std::tuple<unsigned int, unsigned int, Real, Real>> &
408 tuning_data,
409 const HyperParameterMap & hyperparam_map,
410 std::vector<Real> & vec) const
411{
412 for (auto iter : tuning_data)
413 {
414 const std::string & param_name = iter.first;
415 const auto tensor_it = hyperparam_map.find(param_name);
416 if (tensor_it == hyperparam_map.end())
417 mooseError("The covariance parameter ", param_name, " could not be found!");
418
419 const auto values = exportHyperParameter(tensor_it->second);
420 const auto num_entries = std::get<1>(iter.second);
421 mooseAssert(values.size() == num_entries,
422 "Hyperparameter size does not match tuning metadata.");
423 for (unsigned int ii = 0; ii < num_entries; ++ii)
424 vec[std::get<0>(iter.second) + ii] = values[ii];
425 }
426}
427
428void
430 const std::unordered_map<std::string, std::tuple<unsigned int, unsigned int, Real, Real>> &
431 tuning_data,
432 HyperParameterMap & hyperparam_map,
433 const std::vector<Real> & vec) const
434{
435 for (auto iter : tuning_data)
436 {
437 const std::string & param_name = iter.first;
438 const auto tensor_it = hyperparam_map.find(param_name);
439 if (tensor_it == hyperparam_map.end())
440 mooseError("The covariance parameter ", param_name, " could not be found!");
441
442 const auto first_index = std::get<0>(iter.second);
443 const auto num_entries = std::get<1>(iter.second);
444 std::vector<Real> values(num_entries);
445 for (unsigned int ii = 0; ii < num_entries; ++ii)
446 values[ii] = vec[first_index + ii];
447
448 updateHyperParameter(tensor_it->second, values, param_name);
449 }
450}
451
452} // StochasticTools namespace
453
454template <>
455void
456dataStore(std::ostream & stream, StochasticTools::GaussianProcess & gp_utils, void * context)
457{
458 dataStore(stream, gp_utils.hyperparamMap(), context);
459 dataStore(stream, gp_utils.covarType(), context);
460 dataStore(stream, gp_utils.covarName(), context);
461 dataStore(stream, gp_utils.covarNumOutputs(), context);
462 dataStore(stream, gp_utils.dependentCovarNames(), context);
463 dataStore(stream, gp_utils.dependentCovarTypes(), context);
464 dataStore(stream, gp_utils.K(), context);
465 dataStore(stream, gp_utils.KResultsSolve(), context);
466 dataStore(stream, gp_utils.KCholeskyDecomp(), context);
467 dataStore(stream, gp_utils.paramStandardizer(), context);
468 dataStore(stream, gp_utils.dataStandardizer(), context);
469}
470
471template <>
472void
473dataLoad(std::istream & stream, StochasticTools::GaussianProcess & gp_utils, void * context)
474{
475 dataLoad(stream, gp_utils.hyperparamMap(), context);
476 dataLoad(stream, gp_utils.covarType(), context);
477 dataLoad(stream, gp_utils.covarName(), context);
478 dataLoad(stream, gp_utils.covarNumOutputs(), context);
479 dataLoad(stream, gp_utils.dependentCovarNames(), context);
480 dataLoad(stream, gp_utils.dependentCovarTypes(), context);
481 dataLoad(stream, gp_utils.K(), context);
482 dataLoad(stream, gp_utils.KResultsSolve(), context);
483 dataLoad(stream, gp_utils.KCholeskyDecomp(), context);
484 dataLoad(stream, gp_utils.paramStandardizer(), context);
485 dataLoad(stream, gp_utils.dataStandardizer(), context);
486}
487
488#endif
void dataLoad(std::istream &stream, LineSegment &l, void *context)
void dataStore(std::ostream &stream, LineSegment &l, void *context)
void mooseError(Args &&... args)
unsigned int count
std::array< Real, 2 > values
const std::string name
Definition Setup.h:21
Base class for covariance functions that are used in Gaussian Processes.
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.
virtual void computeCovarianceMatrix(torch::Tensor &K, const torch::Tensor &x, const torch::Tensor &xp, const bool is_self_covariance) const =0
Generates the Covariance Matrix given two sets of points in the parameter space.
void buildHyperParamMap(HyperParameterMap &map) const
Populates the input maps with the owned hyperparameters.
void dependentCovarianceTypes(std::map< UserObjectName, std::string > &name_type_map) const
Populate a map with the names and types of the dependent covariance functions.
void loadHyperParamMap(const HyperParameterMap &map)
Load some hyperparameters into the local map contained in this object.
static bool isVectorHyperParameter(const torch::Tensor &tensor)
Return true if a hyperparameter tensor stores a vector of values.
virtual bool isTunable(const std::string &name) const
Check if a given parameter is tunable.
unsigned int numOutputs() const
Return the number of outputs assumed for this covariance function.
virtual bool computedKdhyper(torch::Tensor &dKdhp, const torch::Tensor &x, const std::string &hyper_param_name, unsigned int ind) const
Redirect dK/dhp for hyperparameter "hp".
static bool isScalarHyperParameter(const torch::Tensor &tensor)
Return true if a hyperparameter tensor stores one scalar value.
const std::vector< UserObjectName > & dependentCovarianceNames() const
Get the names of the dependent covariances.
const std::string & type() const
const std::string & name() const
void saveState()
void seed(std::size_t i, unsigned int seed)
Utility class dedicated to hold structures and functions commont to Gaussian Processes.
void standardizeParameters(torch::Tensor &parameters, bool keep_moments=false)
Standardizes the vector of input parameters (x values).
void initialize(CovarianceFunctionBase *covariance_function, const std::vector< std::string > &params_to_tune, const std::vector< Real > &min=std::vector< Real >(), const std::vector< Real > &max=std::vector< Real >())
Initializes the most important structures in the Gaussian Process: the covariance function and a tuni...
CovarianceFunctionBase::HyperParameterMap HyperParameterMap
unsigned int _num_tunable
Number of tunable hyperparameters.
unsigned int _batch_size
The batch size for Adam optimization.
Real getLoss(torch::Tensor &inputs, torch::Tensor &outputs)
unsigned int _num_outputs
The number of outputs of the GP.
std::vector< Real > _length_scales
To return the GP length scales for active learning.
HyperParameterMap _hyperparam_map
Hyperparameters. Stored as tensors for use in surrogate reload/reporting.
std::vector< UserObjectName > & dependentCovarNames()
void linkCovarianceFunction(CovarianceFunctionBase *covariance_function)
Finds and links the covariance function to this object.
std::string _covar_type
Type of covariance function used for this GP.
std::string _covar_name
The name of the covariance function used in this GP.
void setupStoredMatrices(const torch::Tensor &input)
Sets up the Cholesky decomposition and inverse action of the covariance matrix.
std::map< UserObjectName, std::string > & dependentCovarTypes()
CovarianceFunctionBase * _covariance_function
Covariance function object.
void tuneHyperParamsAdam(const torch::Tensor &training_params, const torch::Tensor &training_data, const GPOptimizerOptions &opts)
StochasticTools::Standardizer & paramStandardizer()
Get non-constant reference to the contained structures (if they need to be modified from the utside)
StochasticTools::Standardizer & dataStandardizer()
void standardizeData(torch::Tensor &data, bool keep_moments=false)
Standardizes the vector of responses (y values).
std::unordered_map< std::string, std::tuple< unsigned int, unsigned int, Real, Real > > _tuning_data
Contains tuning inforation. Index of hyperparam, size, and min/max bounds.
void mapToVec(const std::unordered_map< std::string, std::tuple< unsigned int, unsigned int, Real, Real > > &tuning_data, const HyperParameterMap &hyperparam_map, std::vector< Real > &vec) const
Function used to convert the hyperparameter map in this object to a flat vector.
void setupCovarianceMatrix(const torch::Tensor &training_params, const torch::Tensor &training_data, const GPOptimizerOptions &opts)
Sets up the covariance matrix given data and optimization options.
torch::Tensor _K_results_solve
A solve of Ax=b via Cholesky.
HyperParameterMap & hyperparamMap()
StochasticTools::Standardizer _param_standardizer
Standardizer for use with params (x)
std::vector< Real > getGradient(torch::Tensor &inputs) const
torch::Tensor _K
An _n_sample by _n_sample covariance matrix constructed from the selected kernel function.
void vecToMap(const std::unordered_map< std::string, std::tuple< unsigned int, unsigned int, Real, Real > > &tuning_data, HyperParameterMap &hyperparam_map, const std::vector< Real > &vec) const
Function used to convert the vector back to the hyperparameter map.
void generateTuningMap(const std::vector< std::string > &params_to_tune, const std::vector< Real > &min=std::vector< Real >(), const std::vector< Real > &max=std::vector< Real >())
Sets up the tuning map which is used if the user requires parameter tuning.
std::map< UserObjectName, std::string > _dependent_covar_types
The types of the covariance functions the used covariance function depends on.
torch::Tensor _K_cho_decomp
Cholesky decomposition libtorch tensor object.
std::vector< UserObjectName > _dependent_covar_names
The names of the covariance functions the used covariance function depends on.
StochasticTools::Standardizer _data_standardizer
Standardizer for use with data (y)
void getStandardized(torch::Tensor &input) const
Returns the standardized (centered and scaled) of the provided input.
void computeSet(const torch::Tensor &input)
Methods for computing and setting mean and standard deviation.
torch::Tensor toCPUContiguous(const torch::Tensor &tensor)
std::string stringify(const T &t)
Enum for batch type in stochastic tools MultiApp.
auto index_range(const T &sizable)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Structure containing the optimization options for hyperparameter-tuning.
const Real b1
Tuning parameter from the paper.
const unsigned int num_iter
The number of iterations for Adam optimizer.
const Real eps
Tuning parameter from the paper.
const Real b2
Tuning parameter from the paper.
GPOptimizerOptions(const unsigned int show_every_nth_iteration=0, const unsigned int num_iter=1000, const unsigned int batch_size=0, const Real learning_rate=1e-3, const Real b1=0.9, const Real b2=0.999, const Real eps=1e-7, const Real lambda=1e-4, const OptimizerType optimizer_type=OptimizerType::Adam)
Construct a new GPOptimizerOptions object using input parameters that will control the optimization.
const OptimizerType optimizer_type
Adam optimizer mode to use.
const Real learning_rate
The learning rate for Adam optimizer.
const unsigned int batch_size
The batch size for Adam optimizer.
const Real lambda
Legacy MOOSE shrink parameter.
const unsigned int show_every_nth_iteration
Switch to enable verbose output for parameter tuning at every n-th iteration.