Skip to content

Commit

Permalink
Merge pull request #123 from jezsadler/main
Browse files Browse the repository at this point in the history
Quickstart guide amendments
  • Loading branch information
rmisener authored Sep 25, 2023
2 parents 47f646b + c0d5739 commit c0f6c0b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 28 deletions.
10 changes: 5 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.. image:: https://readthedocs.org/projects/omlt/badge/?version=latest
:target: https://omlt.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status

.. image:: https://user-images.githubusercontent.com/31448377/202018691-dfacb0f8-620d-4d48-b918-2fa8b8da3d26.png
:target: https://www.coin-or.org/
:alt: COIN
Expand Down Expand Up @@ -103,10 +103,10 @@ Example
model.nn.build_formulation(formulation)
#query inputs and outputs, as well as scaled inputs and outputs
model.nn.inputs
model.nn.outputs
model.nn.scaled_inputs
model.nn.scaled_outputs
model.nn.inputs.display()
model.nn.outputs.display()
model.nn.scaled_inputs.display()
model.nn.scaled_outputs.display()
#connect pyomo model input and output to the neural network
@model.Constraint()
Expand Down
10 changes: 7 additions & 3 deletions docs/installation.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Installation
==============

OMLT requires Python >= 3.6. The most stable OMLT version can be installed using the PyPI package index. This will also install the required depencies. Simply run: ::
OMLT requires Python >= 3.6. The most stable OMLT version can be installed using the PyPI package index. This will also install the required depencies. Simply run: ::

pip install omlt

Expand All @@ -17,8 +17,12 @@ Optional Requirements

OMLT can import sequential Keras models which requires a working installation of tensorflow: ::

pip install tensorflow
pip install tensorflow

OMLT can also import neural network and gradient boosted tree models using ONNX. This requires installing the ONNX interface: ::

pip install onnx
pip install onnx

On Windows machines, the IPOPT solver executable is not installed with pyomo. See https://github.com/conda-forge/ipopt-feedstock/issues/55 for details. An older version of the solver can be installed with: ::

conda install -c conda-forge ipopt=3.11.1
42 changes: 22 additions & 20 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
Quick-Start
============

The quick-start uses the same model shown on the OMLT `README <https://github.com/cog-imperial/OMLT/blob/main/README.rst>`_, but it provides a little more detail. The example
imports a neural network trained in TensorFlow, formulates a Pyomo model, and seeks the neural network input that produces
the desired output.
The quick-start uses the same model shown on the OMLT `README <https://github.com/cog-imperial/OMLT/blob/main/README.rst>`_, but it provides a little more detail. The example
imports a neural network trained in TensorFlow, formulates a Pyomo model, and seeks the neural network input that produces
the desired output.

We begin by importing the necessary packages. These include `tensorflow` to import the neural network and `pyomo` to
build the optimization problem. We also import the necessary objects from `omlt` to formulate the neural network in Pyomo. ::
We begin by importing the necessary packages. These include `tensorflow` to import the neural network and `pyomo` to
build the optimization problem. We also import the necessary objects from `omlt` to formulate the neural network in Pyomo. ::

import tensorflow
import pyomo.environ as pyo
from omlt import OmltBlock, OffsetScaling
from omlt.neuralnet import FullSpaceNNFormulation, NetworkDefinition
from omlt.io import load_keras_sequential

We first load a simple neural network from the tests directory that contains 1 input, 1 output, and 3 hidden nodes
We first load a simple neural network from the tests directory that contains 1 input, 1 output, and 3 hidden nodes
with sigmoid activation functions. ::

#load a Keras model
nn = tensorflow.keras.models.load_model('tests/models/keras_linear_131_sigmoid', compile=False)

We next create a Pyomo model and attach an `OmltBlock` which will be used to formulate the neural network. An `OmltBlock` is a
custom Pyomo block that we use to build machine learning model formulations. We also create Pyomo model variables to represent the
We next create a Pyomo model and attach an `OmltBlock` which will be used to formulate the neural network. An `OmltBlock` is a
custom Pyomo block that we use to build machine learning model formulations. We also create Pyomo model variables to represent the
input and output of the neural network. ::

#create a Pyomo model with an OMLT block
Expand All @@ -32,8 +32,8 @@ input and output of the neural network. ::
model.input = pyo.Var()
model.output = pyo.Var()

OMLT supports the use of scaling and input bound information. This information informs how the Pyomo model
applies scaling and unscaling to the neural network inputs and outputs. It also informs variable bounds on the inputs. ::
OMLT supports the use of scaling and input bound information. This information informs how the Pyomo model
applies scaling and unscaling to the neural network inputs and outputs. It also informs variable bounds on the inputs. ::

#apply simple offset scaling for the input and output
scale_x = (1, 0.5) #(mean,stdev) of the input
Expand All @@ -46,9 +46,9 @@ applies scaling and unscaling to the neural network inputs and outputs. It also
#provide bounds on the input variable (e.g. from training)
scaled_input_bounds = {0:(0,5)}

We now create a `NetworkDefinition` using the `load\_keras\_sequential` function where we provide the
scaler object and input bounds. Once we have a `NetworkDefinition`, we can pass it to various formulation objects which
decide how to build the neural network within the `OmltBlock`. Here, we use the `FullSpaceNNFormulation`, but others are also possible
We now create a `NetworkDefinition` using the `load\_keras\_sequential` function where we provide the
scaler object and input bounds. Once we have a `NetworkDefinition`, we can pass it to various formulation objects which
decide how to build the neural network within the `OmltBlock`. Here, we use the `FullSpaceNNFormulation`, but others are also possible
(see :ref:`formulations <formulations>`). ::

#load the keras model into a network definition
Expand All @@ -61,15 +61,15 @@ decide how to build the neural network within the `OmltBlock`. Here, we use the
#build the formulation on the OMLT block
model.nn.build_formulation(formulation)

We can query the input and output pyomo variables that the `build_formulation` method produces (as well as scaled input and output varialbes).
We lastly create pyomo constraints that connect our input and output variables defined earlier to the neural network input and output variables on
We can query the input and output pyomo variables that the `build_formulation` method produces (as well as scaled input and output variables).
We lastly create pyomo constraints that connect our input and output variables defined earlier to the neural network input and output variables on
the `OmltBlock`.::

#query inputs and outputs, as well as scaled inputs and outputs
model.nn.inputs
model.nn.outputs
model.nn.scaled_inputs
model.nn.scaled_outputs
model.nn.inputs.display()
model.nn.outputs.display()
model.nn.scaled_inputs.display()
model.nn.scaled_outputs.display()

#connect pyomo model input and output to the neural network
@model.Constraint()
Expand All @@ -86,4 +86,6 @@ Lastly, we formulate an objective function and use Ipopt to solve the optimizati
model.obj = pyo.Objective(expr=(model.output - 0.5)**2)
status = pyo.SolverFactory('ipopt').solve(model, tee=False)
print(pyo.value(model.input))
print(pyo.value(model.output))
print(pyo.value(model.output))

In this example, the function is monotonically increasing and the output is always below the target of 0.5. The optimal solution is at x=3.5, y=-0.1079...

0 comments on commit c0f6c0b

Please sign in to comment.