Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
GradientDescentInstantiationSearcher.h
Go to the documentation of this file.
1#pragma once
2
3#include <boost/variant.hpp>
4#include <map>
5#include <memory>
6
15#include "storm/logic/Formula.h"
20
21namespace storm {
22namespace derivative {
23template<typename FunctionType, typename ConstantType>
25 public:
27
49 ConstantType learningRate = 0.1, ConstantType averageDecay = 0.9, ConstantType squaredAverageDecay = 0.999, uint_fast64_t miniBatchSize = 32,
50 ConstantType terminationEpsilon = 1e-6,
51 std::optional<
53 startPoint = std::nullopt,
55 std::optional<storage::ParameterRegion<FunctionType>> region = std::nullopt, bool recordRun = false)
56 : env(env),
57 model(model),
58 derivativeEvaluationHelper(std::make_unique<SparseDerivativeInstantiationModelChecker<FunctionType, ConstantType>>(model)),
59 instantiationModelChecker(
60 std::make_unique<modelchecker::SparseDtmcInstantiationModelChecker<models::sparse::Dtmc<FunctionType>, ConstantType>>(env, model)),
61 startPoint(startPoint),
62 miniBatchSize(miniBatchSize),
63 terminationEpsilon(terminationEpsilon),
64 constraintMethod(constraintMethod),
65 region(region),
66 recordRun(recordRun) {
67 STORM_LOG_ERROR_COND(region == std::nullopt || (constraintMethod == GradientDescentConstraintMethod::PROJECT ||
69 "Specifying a region is only supported if you are constraining by projection.");
70 // TODO should we put this in subclasses?
71 switch (method) {
73 Adam adam;
74 adam.learningRate = learningRate;
75 adam.averageDecay = averageDecay;
76 adam.averageDecay = averageDecay;
77 adam.squaredAverageDecay = squaredAverageDecay;
78 gradientDescentType = adam;
79 break;
80 }
82 RAdam radam;
83 radam.learningRate = learningRate;
84 radam.averageDecay = averageDecay;
85 radam.squaredAverageDecay = squaredAverageDecay;
86 gradientDescentType = radam;
87 break;
88 }
90 RmsProp rmsProp;
91 rmsProp.learningRate = learningRate;
92 rmsProp.averageDecay = averageDecay;
93 gradientDescentType = rmsProp;
94 break;
95 }
98 Plain plain;
99 plain.learningRate = learningRate;
100 gradientDescentType = plain;
101 if (method == GradientDescentMethod::PLAIN_SIGN) {
102 useSignsOnly = true;
103 } else {
104 useSignsOnly = false;
105 }
106 break;
107 }
110 Momentum momentum;
111 momentum.learningRate = learningRate;
112 // TODO Document this
113 momentum.momentumTerm = averageDecay;
114 gradientDescentType = momentum;
116 useSignsOnly = true;
117 } else {
118 useSignsOnly = false;
119 }
120 break;
121 }
124 Nesterov nesterov;
125 nesterov.learningRate = learningRate;
126 // TODO Document this
127 nesterov.momentumTerm = averageDecay;
128 gradientDescentType = nesterov;
130 useSignsOnly = true;
131 } else {
132 useSignsOnly = false;
133 }
134 break;
135 }
136 }
137 }
138
147 void setup(Environment const& env, std::shared_ptr<storm::pars::FeasibilitySynthesisTask const> const& task) {
148 this->env = env;
149 this->parameters = storm::models::sparse::getProbabilityParameters(model);
150 this->synthesisTask = task;
151 STORM_LOG_ASSERT(task->getFormula().isProbabilityOperatorFormula() || task->getFormula().isRewardOperatorFormula(),
152 "Formula must be either a reward or a probability operator formula.");
153
154 std::shared_ptr<storm::logic::Formula> formulaWithoutBounds = task->getFormula().clone();
155 formulaWithoutBounds->asOperatorFormula().removeBound();
156 this->currentFormulaNoBound = formulaWithoutBounds->asSharedPointer();
157
158 if (task->getFormula().isRewardOperatorFormula()) {
159 auto rewardParameters = storm::models::sparse::getRewardParameters(model);
160 this->parameters.insert(rewardParameters.begin(), rewardParameters.end());
161 }
162
163 this->currentCheckTaskNoBound = std::make_unique<storm::modelchecker::CheckTask<storm::logic::Formula, FunctionType>>(*currentFormulaNoBound);
164 this->currentCheckTaskNoBoundConstantType =
165 std::make_unique<storm::modelchecker::CheckTask<storm::logic::Formula, ConstantType>>(*currentFormulaNoBound);
166
167 instantiationModelChecker->specifyFormula(*this->currentCheckTaskNoBound);
168 derivativeEvaluationHelper->specifyFormula(env, *this->currentCheckTaskNoBound);
169 }
170
174 std::pair<std::map<typename utility::parametric::VariableType<FunctionType>::type, typename utility::parametric::CoefficientType<FunctionType>::type>,
177
181 void printRunAsJson();
182
187 std::map<typename utility::parametric::VariableType<FunctionType>::type, typename utility::parametric::CoefficientType<FunctionType>::type> position;
189 };
190
193 std::vector<VisualizationPoint> getVisualizationWalk();
194
195 private:
196 void resetDynamicValues();
197
198 Environment env;
199 std::shared_ptr<storm::pars::FeasibilitySynthesisTask const> synthesisTask;
200 std::unique_ptr<modelchecker::CheckTask<storm::logic::Formula, FunctionType>> currentCheckTaskNoBound;
201 std::unique_ptr<modelchecker::CheckTask<storm::logic::Formula, ConstantType>> currentCheckTaskNoBoundConstantType;
202 std::shared_ptr<storm::logic::Formula const> currentFormulaNoBound;
203
205 std::set<typename utility::parametric::VariableType<FunctionType>::type> parameters;
206 const std::unique_ptr<storm::derivative::SparseDerivativeInstantiationModelChecker<FunctionType, ConstantType>> derivativeEvaluationHelper;
207 std::unique_ptr<storm::analysis::MonotonicityHelper<FunctionType, ConstantType>> monotonicityHelper;
208 const std::unique_ptr<modelchecker::SparseDtmcInstantiationModelChecker<models::sparse::Dtmc<FunctionType>, ConstantType>> instantiationModelChecker;
209 std::optional<std::map<typename utility::parametric::VariableType<FunctionType>::type, typename utility::parametric::CoefficientType<FunctionType>::type>>
210 startPoint;
211 const uint_fast64_t miniBatchSize;
212 const ConstantType terminationEpsilon;
213 const GradientDescentConstraintMethod constraintMethod;
214 const std::optional<storage::ParameterRegion<FunctionType>> region;
215
216 // This is for visualizing data
217 const bool recordRun;
218 std::vector<VisualizationPoint> walk;
219
220 // Gradient Descent types and data that belongs to them, with hyperparameters and running data.
221 struct Adam {
222 ConstantType averageDecay;
223 ConstantType squaredAverageDecay;
224 ConstantType learningRate;
225 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> decayingStepAverageSquared;
226 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> decayingStepAverage;
227 };
228 struct RAdam {
229 ConstantType averageDecay;
230 ConstantType squaredAverageDecay;
231 ConstantType learningRate;
232 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> decayingStepAverageSquared;
233 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> decayingStepAverage;
234 };
235 struct RmsProp {
236 ConstantType averageDecay;
237 ConstantType learningRate;
238 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> rootMeanSquare;
239 };
240 struct Plain {
241 ConstantType learningRate;
242 };
243 struct Momentum {
244 ConstantType learningRate;
245 ConstantType momentumTerm;
246 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> pastStep;
247 };
248 struct Nesterov {
249 ConstantType learningRate;
250 ConstantType momentumTerm;
251 std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType> pastStep;
252 };
253 typedef boost::variant<Adam, RAdam, RmsProp, Plain, Momentum, Nesterov> GradientDescentType;
254 GradientDescentType gradientDescentType;
255 // Only respected by some Gradient Descent methods, the ones that have a "sign" version in the GradientDescentMethod enum
256 bool useSignsOnly;
257
258 ConstantType logarithmicBarrierTerm;
259
260 ExtendedConstantType stochasticGradientDescent(
262 ConstantType doStep(
265 const std::map<typename utility::parametric::VariableType<FunctionType>::type, ConstantType>& gradient, uint_fast64_t stepNum);
266 ConstantType constantTypeSqrt(ConstantType input) {
267 return storm::utility::sqrt(input);
268 }
269
270 utility::Stopwatch stochasticWatch;
271 utility::Stopwatch batchWatch;
272 utility::Stopwatch startingPointCalculationWatch;
273};
274} // namespace derivative
275} // namespace storm
storm::models::sparse::Dtmc< double > Dtmc
storm::utility::ExtendedValueType< ConstantType > ExtendedConstantType
std::pair< std::map< typename utility::parametric::VariableType< FunctionType >::type, typename utility::parametric::CoefficientType< FunctionType >::type >, ExtendedConstantType > gradientDescent()
Perform Gradient Descent.
void setup(Environment const &env, std::shared_ptr< storm::pars::FeasibilitySynthesisTask const > const &task)
This will setup the matrices used for computing the derivatives by constructing the SparseDerivativeI...
std::vector< VisualizationPoint > getVisualizationWalk()
Get the visualization walk that is recorded if recordRun is set to true in the constructor (false by ...
GradientDescentInstantiationSearcher(Environment const &env, storm::models::sparse::Dtmc< FunctionType > const &model, GradientDescentMethod method=GradientDescentMethod::ADAM, ConstantType learningRate=0.1, ConstantType averageDecay=0.9, ConstantType squaredAverageDecay=0.999, uint_fast64_t miniBatchSize=32, ConstantType terminationEpsilon=1e-6, std::optional< std::map< typename utility::parametric::VariableType< FunctionType >::type, typename utility::parametric::CoefficientType< FunctionType >::type > > startPoint=std::nullopt, GradientDescentConstraintMethod constraintMethod=GradientDescentConstraintMethod::PROJECT_WITH_GRADIENT, std::optional< storage::ParameterRegion< FunctionType > > region=std::nullopt, bool recordRun=false)
The GradientDescentInstantiationSearcher can find extrema and feasible instantiations in pMCs,...
This class represents a discrete-time Markov chain.
Definition Dtmc.h:16
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_ERROR_COND(cond, message)
Definition macros.h:68
GradientDescentMethod
GradientDescentMethod is the method of Gradient Descent the GradientDescentInstantiationSearcher shal...
GradientDescentConstraintMethod
GradientDescentConstraintMethod is the method for mitigating constraints that the GradientDescentInst...
std::set< storm::RationalFunctionVariable > getRewardParameters(Model< storm::RationalFunction > const &model)
Get all parameters occurring in rewards.
Definition Model.cpp:736
std::set< storm::RationalFunctionVariable > getProbabilityParameters(Model< storm::RationalFunction > const &model)
Get all probability parameters occurring on transitions.
Definition Model.cpp:732
std::conditional_t< storm::NumberTraits< ValueType >::HasInfinity, ValueType, ExtendedNumber< ValueType > > ExtendedValueType
The type to use for values that may be infinite.
ValueType sqrt(ValueType const &number)
A point in the Gradient Descent walk, recorded if recordRun is set to true in the constructor (false ...
std::map< typename utility::parametric::VariableType< FunctionType >::type, typename utility::parametric::CoefficientType< FunctionType >::type > position