10#ifdef MOOSE_LIBTORCH_ENABLED
26 "Sets the value of multiple 'Real' input parameters and postprocessors based on a Deep "
27 "Reinforcement Learning (DRL) neural network trained using a PPO algorithm.");
31 params.
addParam<
unsigned int>(
"seed",
"Seed for the random number generator.");
34 "num_steps_in_period",
36 "1<=num_steps_in_period",
37 "Number of time steps between policy evaluations. The observation history advances once "
38 "per period, so the trainer's 'timestep_window' should match this value.");
40 "control_smoothing_factor",
42 "control_smoothing_factor>0 & control_smoothing_factor<=1",
43 "Exponential smoothing factor for the applied control signal: the fraction of the change "
44 "from the previously applied signal toward the new policy action that is applied at each "
45 "time step. A value of 1 applies the policy action directly.");
50 "Optional constant offsets added to each policy signal before setting the controlled "
51 "parameter. This can be used to train a policy on deviations from a nominal signal.");
56 "If true, sample from the policy distribution; otherwise use the deterministic action.");
59 "min_control_value", {},
"Optional lower bounds for each control signal.");
61 "max_control_value", {},
"Optional upper bounds for each control signal.");
63 "state_independent_std",
65 "If true, interpret the unbounded Gaussian actor as learning one log-std per action "
66 "dimension. If false, use a state-dependent std head.");
73 _current_control_signal_log_probabilities(declareRestartableData<
std::vector<Real>>(
74 "current_control_signal_log_probabilities",
std::vector<Real>(_control_names.size(), 0.0))),
75 _previous_control_signal(declareRestartableData<
std::vector<Real>>(
76 "previous_control_signal",
std::vector<Real>(_control_names.size(), 0.0))),
77 _current_smoothed_signal(declareRestartableData<
std::vector<Real>>(
78 "current_smoothed_signal",
std::vector<Real>(_control_names.size(), 0.0))),
79 _control_offsets(isParamSetByUser(
"control_offsets")
80 ? getParam<
std::vector<Real>>(
"control_offsets")
81 :
std::vector<Real>(_control_names.size(), 0.0)),
82 _has_control_offsets(isParamSetByUser(
"control_offsets")),
83 _policy_generator(
Moose::makeLibtorchCPUGenerator()),
84 _policy_generator_state(declareRestartableData<
std::vector<
std::uint8_t>>(
85 "policy_generator_state",
std::vector<
std::uint8_t>())),
86 _num_steps_in_period(getParam<unsigned
int>(
"num_steps_in_period")),
87 _control_smoothing_factor(getParam<Real>(
"control_smoothing_factor")),
88 _stochastic(getParam<bool>(
"stochastic"))
90 const auto & execute_on = getParam<ExecFlagEnum>(
"execute_on");
92 paramError(
"execute_on",
"LibtorchDRLControl only supports 'TIMESTEP_BEGIN' for 'execute_on'.");
99 "The number of control offsets must match the number of controlled parameters.");
115 const auto & filename = getParam<std::string>(
"filename");
118 std::vector<unsigned int> num_neurons_per_layer =
119 getParam<std::vector<unsigned int>>(
"num_neurons_per_layer");
120 std::vector<std::string> activation_functions =
122 ? getParam<std::vector<std::string>>(
"activation_function")
123 : std::vector<std::string>({
"relu"});
125 const std::vector<Real> & minimum_values = getParam<std::vector<Real>>(
"min_control_value");
126 const std::vector<Real> & maximum_values = getParam<std::vector<Real>>(
"max_control_value");
127 const auto input_shift_factors =
129 const auto input_scaling_factors =
133 std::make_shared<Moose::LibtorchActorNeuralNet>(filename,
136 num_neurons_per_layer,
137 activation_functions,
144 input_scaling_factors,
146 getParam<bool>(
"state_independent_std"));
157 mooseAssert(!
_nn,
"LibtorchDRLControl should not store a non-actor controller network.");
165 "LibtorchDRLControl should only execute on TIMESTEP_BEGIN or from a transfer "
166 "before the first time step.");
175 if (first_control_execution)
186 torch::Tensor log_probability =
_actor_nn->logProbability(action);
188 log_probability.data_ptr<Real>() +
189 log_probability.size(1)};
222 const Real applied_signal =
224 setControllableValueByName<Real>(
_control_names[control_i], applied_signal);
231 _actor_nn = std::make_shared<Moose::LibtorchActorNeuralNet>(input_nn);
240 mooseError(
"This needs to be a LibtorchActorNeuralNet!");
272 {static_cast<long>(_policy_generator_state.size())},
273 torch::TensorOptions().dtype(torch::kUInt8).device(torch::kCPU))
290 const auto * data = state_tensor.data_ptr<std::uint8_t>();
298 "The index of the requested control signal is not in the [0," +
registerMooseObject("StochasticToolsApp", LibtorchDRLControl)
const ExecFlagType EXEC_TIMESTEP_BEGIN
void ErrorVector unsigned int
A time-dependent, neural-network-based controller which is associated with a Proximal Policy Optimiza...
bool _has_control_offsets
Whether any offset data was provided by the user.
virtual void loadControlNeuralNetFromFile() override
Load the actor neural network from the configured checkpoint file.
LibtorchDRLControl(const InputParameters ¶meters)
Construct using input parameters.
std::vector< Real > _control_offsets
Constant offsets added to each control signal before it is applied.
at::Generator _policy_generator
Owned libtorch CPU generator used for policy sampling.
void restorePolicyGeneratorState()
Restore the owned libtorch generator state from restartable storage.
void savePolicyGeneratorState()
Mirror the owned libtorch generator state into restartable storage.
Real getSignalLogProbability(const unsigned int signal_index) const
Get the logarithmic probability of (signal_index)-th signal of the control neural net.
virtual void execute() override
Compute the actions and their corresponding logarithmic probabilities.
std::vector< Real > & _previous_control_signal
The smoothed control signal from the previous execution, saved for restart/recover.
std::vector< Real > & _current_control_signal_log_probabilities
The log probability of control signals from the last evaluation of the controller.
Real computeControlOffset(unsigned int control_i) const
Return the offset to add to a control signal at the current time.
static InputParameters validParams()
Return the input parameters supported by this control.
const bool _stochastic
Whether to sample actions stochastically instead of using the deterministic actor output.
const Real _control_smoothing_factor
Exponential smoothing factor in (0, 1] applied to the control signal at each time step.
void loadControlNeuralNet(const Moose::LibtorchActorNeuralNet &input_nn)
Copy an actor network into this DRL controller.
bool shouldEvaluatePolicy() const
Report whether the policy is evaluated at the current time step.
std::vector< Real > & _current_smoothed_signal
The current smoothed control signal applied to the controllable parameters.
const unsigned int _num_steps_in_period
Number of time steps between policy evaluations.
void setPolicySampleSeed(uint64_t seed)
Reset the owned policy-sampling generator to a known seed.
std::shared_ptr< Moose::LibtorchActorNeuralNet > _actor_nn
Actor network used when the controller operates as a stochastic policy.
std::vector< std::uint8_t > & _policy_generator_state
Restartable serialized state for the owned policy-sampling generator.
virtual void initialSetup() override
Restore any restartable controller state after base setup completes.
void applyControlSignals()
Apply the current smoothed control signals, including optional offsets.
const std::vector< Real > _action_scaling_factors
virtual void initialSetup() override
const unsigned int _input_timesteps
const std::vector< PostprocessorName > & _observation_names
const std::vector< Real > _observation_shift_factors
static InputParameters validParams()
const std::vector< Real > _observation_scaling_factors
std::vector< Real > _current_observation
std::vector< Real > & _current_control_signals
void updateCurrentObservation()
const std::vector< std::string > & _control_names
torch::Tensor prepareInputTensor()
std::shared_ptr< Moose::LibtorchNeuralNetBase > _nn
const LibtorchObservationHistoryHelper _observation_history
std::vector< std::vector< Real > > & _old_observations
void initializeHistory(const std::vector< Real > &observation, std::vector< std::vector< Real > > &old_observations) const
std::vector< Real > expandObservationFactors(const std::vector< Real > &observation_factors) const
void advanceHistory(const std::vector< Real > &observation, std::vector< std::vector< Real > > &old_observations) const
void paramError(const std::string ¶m, Args... args) const
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
Feed-forward actor network coupled to a Gaussian or Beta action distribution.
const ExecFlagType & _current_execute_flag
void loadLibtorchActorNeuralNetState(Moose::LibtorchActorNeuralNet &nn, const std::string &filename)
Load an actor checkpoint written as a native libtorch state archive.