-
Notifications
You must be signed in to change notification settings - Fork 12
Optimization
GUNNS includes code to help you automatically optimize, or tune, your models. This code resides in the gunns/core/optimization/ folder. An optimization scheme is selected from the set of schemes we have implemented. So far we have implemented two schemes, described below, but we may implement more in the future. The optimization uses Trick Monte Carlo to run your model in batch runs, allowing the optimization scheme to improve the model tuning towards achieving a desired set of model outputs.
- General model optimization, not GUNNS-specific
- Serial or parallel processing (parallel only partially implemented as of now)
- Static or dynamic input driver and output target data
- Monte carlo manager can be adapted to non-Trick environments
- Modular, plug-and-play optimizers
- Optional constraints between input variables
- Adjustable verbosity level for more or less verbose output to the console (for debugging)
These are the optimizers that we have implemented so far. We may implement more in the future.
- Particle Swarm Optimization - good for all-around, multi-variate optimization.
- Gradient Descent Optimization - good for single variable optimization to the local minimum.
These instructions are for the Trick environment.
- Add the optimization capability to your sim:
- Add a GunnsOptimMonteCarlo object to the sim. See gunns/sims/SIM_mc/S_define for an example.
- Add a scheduled job running before the set of models to be optimized, calling the GunnsOptimMonteCarlo object's updateSlaveInputs() function. This should be in the same thread and called with the same scheduled job rate as the optimized models.
- Add a similar scheduled job running after the models, calling the updateSlaveOutputs() function.
- Build the Trick sim.
- Prepare your model inputs:
- Model inputs can either static, or dynamic (varying over time).
- For static inputs, simply configure them as initial conditions like you normally would, by input file or default data, etc.
- For dynamic inputs, create a data file in your sim folder called input_driver_data.csv that describes their trajectories over time:
- See gunns/sims/SIM_mc/input_driver_data.csv for an example.
- The data should be comma-delimited.
- The first column should be the time tag. The GUNNS optimization doesn't actually use this column or sync the inputs to the given time - rather the inputs are read from the file sequentially starting at the beginning of each run. However, the GUNNS optimization expects this column to be in the file.
- The subsequent columns should have the data for the input driver variables.
- You can create this file by taking an ascii-formatted Trick data log, and deleting the columns you don't need.
- Prepare your target model outputs:
- This is the desired output of the model that you are trying to optimize the model to create, from the given inputs.
- These can either be static values, or dynamic (varying over time).
- For static outputs, these target values will be given in the input file when we define the Trick monte carlo variables (below).
- For dynamic outputs, create a data file in your sim folder called output_target_data.csv that describes their trajectories over time:
- See gunns/sims/SIM_mc/output_target_data.csv for an example.
- This has the same format as output_target_data.csv, described above. Each row in this output file lists the desired values that the model should produce from the corresponding row in the input driver data.
- Configure the optimizer in the input file:
- See gunns/sims/SIM_mc/input.py for an example.
- Define the set of variables to be optimized. Trick calls these the 'monte carlo variables'. In our example we call this list input_vars. It is a list of tuples, one tuple describing each variable. The tuple has these members:
- Variable name, a string. This is the actual Trick variable name as it would appear on Trick View, etc.
- Trick units, e.g. 1, m2, ft/s, etc.
- Min range. This is the minimum range of the state space for this variable - the lowest value that the optimizer can consider.
- Max range. This is the maximum range of the state space for this variable - the highest value that the optimizer can consider. This must be greater than the min range.
- Optional constraint object, described below. If no constraints are desired, then use a value of 0 here.
- Defined the set of output variables. In our example we call this list 'output_vars'. It is a list of tuples, one tuple describing each variable. Any number of output variables can be used (1 or more), and this doesn't have to match the number of input variables or input driver variables. The tuple has these members:
- Variable name, a string. Same as the input variables above.
- Static target value. These are the target model output values for the static output case, described above. You must include a value here, even if you are using dynamic output values defined by the output_target_data.csv file.
- Cost weight. This controls how much weight is given to this model output in the cost function. A zero causes this output to be ignored. Higher values weight this output more importantly than others.
- Decide which optimizer to use, and call the GunnsOptimMonteCarlo object's addOptimizer() function with the type of optimizer to use. The available types are defined in _gunns/core/optimization/GunnsOptimFactory.hh, the OptimizerType enumeration in the GunnsOptimFactory class.
- Create a configuration data object for the chosen optimizer type and load its configuration values.
- Give this configuration data to the optimizer by calling the GunnsOptimMonteCarlo object's setConfigData function.
- Add the slave input variables and run ID term - we recommend just copying this section from our input.py example.
- Add the input driver data and output target data to the optimizer.
- Enable monte carlo in Trick.
- Tell Trick monte carlo how many individual runs there will be, which is read from the optimizer's getNumRuns() function.
- Enable parallel processing, if desired.
- Tell Trick the simulation stop time of each run.
- Run the sim with your input file.
Depending on the type of optimizer you choose, it will output its results to various files to the sim folder.
We have a simulation that demonstrates optimization in gunns/sims/SIM_mc. It uses a simple fluid network defined in gunns/sims/SIM_mc/model/GunnsMcModelFluid.xml. Before building the sim, you will need to use the gunns/draw/netexport.py script to export the GunnsMcModelFluid drawing to source code. Then build the sim with trick-CP as usual.
- The example PSO, in serial operation, is run by starting the sim with RUN_mc/input.py. Follow the link to PSO above for more detail.
- The example PSO, with parallel processing, is run by starting the pso.py Python 3 file.
- The example GDO, in serial operation, is run by starting the sim with RUN_mc/input_grad.py. Follow the link to GDO above for more detail. We don't have an example with parallel processing for this.
Most optimizer schemes, including the optimizers we've implemented, require runs in batches, with an optimization step in between each batch. For example, each particle in the PSO needs to run once, and once all particles have run, the optimizer does its thing and propagates the swarm to its next state. Then the next optimization epoch starts, and particles are run again, and so on. However Trick, in its current implementation, doesn't allow this. Rather, Trick runs all of the total set of monte carlo runs as fast as it can, allowing no control of batches. Although Trick does allow an optimizer to run between each Slave run, it doesn't throttle the start of the next batch after a certain run of the optimizer.
Because of the this Trick limitation, we can't fully implement parallel processing. We've attempted to implement parallel processing on our own for PSO, with the pso.py script, but its results aren't fully verified, and we don't recommend using it yet.
Trick has an upgrade in work to allow control of batch runs. When this is delivered, we'll modify our optimization code and examples to use it. However as of writing, we don't know Trick will implement this upgrade.