Skip to content

Commit

Permalink
Keras file format updates (#128)
Browse files Browse the repository at this point in the history
* update save, load syntax

* regenerate outdated notebooks

* generate new model files

* remove old keras files

* Test using IDAES/idaes-pse#1401

* Update version constraint for TensorFlow

* Address Python 3.8 failures due to Tensorflow 2.16.1 not being available

* Remove exclusion for Python 3.12 for Tensorflow

* Remove Python 3.8 support

* Restore installing idaes-pse from main branch

---------

Co-authored-by: Ludovico Bianchi <lbianchi@lbl.gov>
  • Loading branch information
bpaul4 and lbianchi-lbl authored Aug 16, 2024
1 parent 9d87c17 commit e0d3966
Show file tree
Hide file tree
Showing 41 changed files with 2,136 additions and 7,310 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ concurrency:

env:
# default Python version to use for checks that do not require multiple versions
DEFAULT_PYTHON_VERSION: '3.8'
DEFAULT_PYTHON_VERSION: '3.10'
IDAES_CONDA_ENV_NAME_DEV: idaes-examples-dev
PYTEST_ADDOPTS: "--color=yes"

Expand Down Expand Up @@ -62,9 +62,10 @@ jobs:
fail-fast: false
matrix:
python-version:
- '3.8'
- '3.9'
- '3.10'
- '3.11'
- '3.12'
os:
- linux
- win64
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
build:
os: ubuntu-20.04
tools:
python: "3.8"
python: "3.10"
jobs:
pre_build:
# Set conf vars and update the Sphinx configuration (conf.py)
Expand Down
3 changes: 0 additions & 3 deletions idaes_examples/browse.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
# stdlib
from importlib import resources

if not hasattr(resources, "files"):
# importlib.resources.files() added in Python 3.9
import importlib_resources as resources
import json
import logging
from logging.handlers import RotatingFileHandler
Expand Down
6 changes: 3 additions & 3 deletions idaes_examples/mod/surrogates/AR_training_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def train_load_surrogates(retrain=False) -> Set[SurrType]:

# Train surrogates using Keras

if os.path.exists('keras_surrogate/') and retrain is False:
if os.path.exists('keras_surrogate/keras_model.keras') and retrain is False:
# surrogates folder already exists, skip training
# we will load the object into the flowsheet later
pass
Expand Down Expand Up @@ -263,7 +263,7 @@ def train_load_surrogates(retrain=False) -> Set[SurrType]:
# Train surrogate (calls optimizer on neural network and solves
# for weights)
model.compile(loss=loss, optimizer=optimizer, metrics=metrics)
mcp_save = tf.keras.callbacks.ModelCheckpoint('.mdl_wts.hdf5',
mcp_save = tf.keras.callbacks.ModelCheckpoint('.mdl_wts.keras',
save_best_only=True,
monitor='val_loss',
mode='min')
Expand All @@ -281,7 +281,7 @@ def train_load_surrogates(retrain=False) -> Set[SurrType]:
input_bounds=input_bounds,
input_scaler=input_scaler,
output_scaler=output_scaler)
keras_surrogate.save_to_folder('keras_surrogate')
keras_surrogate.save_to_folder(keras_folder_name="keras_surrogate", keras_model_name="keras_model")

trained_surr.add(SurrType.KERAS)

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(surrogate, input_vars=inputs, output_vars=outputs)\n",
" elif surrogate_type == SurrType.KERAS:\n",
" keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
" keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down Expand Up @@ -531,7 +531,7 @@
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(surrogate, input_vars=inputs, output_vars=outputs)\n",
" elif surrogate_type == SurrType.KERAS:\n",
" keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
" keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down
4,033 changes: 587 additions & 3,446 deletions idaes_examples/notebooks/docs/surrogates/best_practices_optimization_doc.ipynb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(surrogate, input_vars=inputs, output_vars=outputs)\n",
" elif surrogate_type == SurrType.KERAS:\n",
" keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
" keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down Expand Up @@ -531,7 +531,7 @@
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(surrogate, input_vars=inputs, output_vars=outputs)\n",
" elif surrogate_type == SurrType.KERAS:\n",
" keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
" keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down Expand Up @@ -635,4 +635,4 @@
},
"nbformat": 4,
"nbformat_minor": 3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(surrogate, input_vars=inputs, output_vars=outputs)\n",
" elif surrogate_type == SurrType.KERAS:\n",
" keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
" keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down Expand Up @@ -531,7 +531,7 @@
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(surrogate, input_vars=inputs, output_vars=outputs)\n",
" elif surrogate_type == SurrType.KERAS:\n",
" keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
" keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
" m.fs.surrogate = SurrogateBlock()\n",
" m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down Expand Up @@ -635,4 +635,4 @@
},
"nbformat": 4,
"nbformat_minor": 3
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
"# Train surrogate (calls optimizer on neural network and solves for weights)\n",
"model.compile(loss=loss, optimizer=optimizer, metrics=metrics)\n",
"mcp_save = tf.keras.callbacks.ModelCheckpoint(\n",
" \".mdl_wts.hdf5\", save_best_only=True, monitor=\"val_loss\", mode=\"min\"\n",
" \".mdl_wts.keras\", save_best_only=True, monitor=\"val_loss\", mode=\"min\"\n",
")\n",
"history = model.fit(\n",
" x=x, y=y, validation_split=0.2, verbose=1, epochs=1000, callbacks=[mcp_save]\n",
Expand All @@ -268,7 +268,7 @@
" input_scaler=input_scaler,\n",
" output_scaler=output_scaler,\n",
")\n",
"keras_surrogate.save_to_folder(\"keras_surrogate\")\n",
"keras_surrogate.save_to_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
"\n",
"# revert back to normal output capture\n",
"sys.stdout = oldstdout\n",
Expand Down Expand Up @@ -411,7 +411,7 @@
"\n",
"# create the Pyomo/IDAES block that corresponds to the surrogate\n",
"# Keras\n",
"keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
"keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
"m.fs.surrogate = SurrogateBlock()\n",
"m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down Expand Up @@ -523,4 +523,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
"# Train surrogate (calls optimizer on neural network and solves for weights)\n",
"model.compile(loss=loss, optimizer=optimizer, metrics=metrics)\n",
"mcp_save = tf.keras.callbacks.ModelCheckpoint(\n",
" \".mdl_wts.hdf5\", save_best_only=True, monitor=\"val_loss\", mode=\"min\"\n",
" \".mdl_wts.keras\", save_best_only=True, monitor=\"val_loss\", mode=\"min\"\n",
")\n",
"history = model.fit(\n",
" x=x, y=y, validation_split=0.2, verbose=1, epochs=1000, callbacks=[mcp_save]\n",
Expand All @@ -268,7 +268,7 @@
" input_scaler=input_scaler,\n",
" output_scaler=output_scaler,\n",
")\n",
"keras_surrogate.save_to_folder(\"keras_surrogate\")\n",
"keras_surrogate.save_to_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
"\n",
"# revert back to normal output capture\n",
"sys.stdout = oldstdout\n",
Expand Down Expand Up @@ -411,7 +411,7 @@
"\n",
"# create the Pyomo/IDAES block that corresponds to the surrogate\n",
"# Keras\n",
"keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
"keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
"m.fs.surrogate = SurrogateBlock()\n",
"m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
"# Train surrogate (calls optimizer on neural network and solves for weights)\n",
"model.compile(loss=loss, optimizer=optimizer, metrics=metrics)\n",
"mcp_save = tf.keras.callbacks.ModelCheckpoint(\n",
" \".mdl_wts.hdf5\", save_best_only=True, monitor=\"val_loss\", mode=\"min\"\n",
" \".mdl_wts.keras\", save_best_only=True, monitor=\"val_loss\", mode=\"min\"\n",
")\n",
"history = model.fit(\n",
" x=x, y=y, validation_split=0.2, verbose=1, epochs=1000, callbacks=[mcp_save]\n",
Expand All @@ -268,7 +268,7 @@
" input_scaler=input_scaler,\n",
" output_scaler=output_scaler,\n",
")\n",
"keras_surrogate.save_to_folder(\"keras_surrogate\")\n",
"keras_surrogate.save_to_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
"\n",
"# revert back to normal output capture\n",
"sys.stdout = oldstdout\n",
Expand Down Expand Up @@ -411,7 +411,7 @@
"\n",
"# create the Pyomo/IDAES block that corresponds to the surrogate\n",
"# Keras\n",
"keras_surrogate = KerasSurrogate.load_from_folder(\"keras_surrogate\")\n",
"keras_surrogate = KerasSurrogate.load_from_folder(keras_folder_name=\"keras_surrogate\", keras_model_name=\"keras_model\")\n",
"m.fs.surrogate = SurrogateBlock()\n",
"m.fs.surrogate.build_model(\n",
" keras_surrogate,\n",
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -17,7 +17,7 @@
"# University, West Virginia University Research Corporation, et al.\n",
"# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md\n",
"# for full copyright and license information.\n",
"###############################################################################"
"###############################################################################\n"
]
},
{
Expand All @@ -37,7 +37,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [
{
Expand All @@ -47,7 +47,7 @@
"<IPython.core.display.Image object>"
]
},
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -75,9 +75,19 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING: DEPRECATED: pyomo.core.expr.current is deprecated. Please import\n",
"expression symbols from pyomo.core.expr (deprecated in 6.6.2) (called from\n",
"<frozen importlib._bootstrap>:241)\n"
]
}
],
"source": [
"from pyomo.environ import (ConcreteModel,\n",
" Block,\n",
Expand Down Expand Up @@ -117,33 +127,33 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2023-08-19 22:20:40 [INFO] idaes.init.fs.boiler.control_volume: Initialization Complete\n",
"2023-08-19 22:20:40 [INFO] idaes.init.fs.boiler: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:41 [INFO] idaes.init.fs.turbine: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:41 [INFO] idaes.init.fs.HTR_pseudo_shell.control_volume: Initialization Complete\n",
"2023-08-19 22:20:41 [INFO] idaes.init.fs.HTR_pseudo_shell: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:41 [INFO] idaes.init.fs.LTR_pseudo_shell.control_volume: Initialization Complete\n",
"2023-08-19 22:20:42 [INFO] idaes.init.fs.LTR_pseudo_shell: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:42 [INFO] idaes.init.fs.splitter_1: Initialization Step 2 Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:42 [INFO] idaes.init.fs.co2_cooler.control_volume: Initialization Complete\n",
"2023-08-19 22:20:42 [INFO] idaes.init.fs.co2_cooler: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:43 [INFO] idaes.init.fs.bypass_compressor: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:44 [INFO] idaes.init.fs.main_compressor: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:44 [INFO] idaes.init.fs.splitter_2: Initialization Step 2 Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:44 [INFO] idaes.init.fs.FG_cooler.control_volume: Initialization Complete\n",
"2023-08-19 22:20:44 [INFO] idaes.init.fs.FG_cooler: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:44 [INFO] idaes.init.fs.LTR_pseudo_tube.control_volume: Initialization Complete\n",
"2023-08-19 22:20:45 [INFO] idaes.init.fs.LTR_pseudo_tube: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:45 [INFO] idaes.init.fs.mixer: Initialization Complete: optimal - Optimal Solution Found\n",
"2023-08-19 22:20:45 [INFO] idaes.init.fs.HTR_pseudo_tube.control_volume: Initialization Complete\n",
"2023-08-19 22:20:45 [INFO] idaes.init.fs.HTR_pseudo_tube: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:41:57 [INFO] idaes.init.fs.boiler.control_volume: Initialization Complete\n",
"2024-01-24 21:42:01 [INFO] idaes.init.fs.boiler: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:02 [INFO] idaes.init.fs.turbine: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:03 [INFO] idaes.init.fs.HTR_pseudo_shell.control_volume: Initialization Complete\n",
"2024-01-24 21:42:03 [INFO] idaes.init.fs.HTR_pseudo_shell: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:03 [INFO] idaes.init.fs.LTR_pseudo_shell.control_volume: Initialization Complete\n",
"2024-01-24 21:42:03 [INFO] idaes.init.fs.LTR_pseudo_shell: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:04 [INFO] idaes.init.fs.splitter_1: Initialization Step 2 Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:04 [INFO] idaes.init.fs.co2_cooler.control_volume: Initialization Complete\n",
"2024-01-24 21:42:04 [INFO] idaes.init.fs.co2_cooler: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:05 [INFO] idaes.init.fs.bypass_compressor: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:07 [INFO] idaes.init.fs.main_compressor: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:07 [INFO] idaes.init.fs.splitter_2: Initialization Step 2 Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:07 [INFO] idaes.init.fs.FG_cooler.control_volume: Initialization Complete\n",
"2024-01-24 21:42:08 [INFO] idaes.init.fs.FG_cooler: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:08 [INFO] idaes.init.fs.LTR_pseudo_tube.control_volume: Initialization Complete\n",
"2024-01-24 21:42:08 [INFO] idaes.init.fs.LTR_pseudo_tube: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:09 [INFO] idaes.init.fs.mixer: Initialization Complete: optimal - Optimal Solution Found\n",
"2024-01-24 21:42:09 [INFO] idaes.init.fs.HTR_pseudo_tube.control_volume: Initialization Complete\n",
"2024-01-24 21:42:09 [INFO] idaes.init.fs.HTR_pseudo_tube: Initialization Complete: optimal - Optimal Solution Found\n",
"--------------------------------------------------------------------\n",
"The degrees of freedom for the flowsheet is 0\n",
"--------------------------------------------------------------------\n",
Expand Down Expand Up @@ -204,8 +214,8 @@
"Number of equality constraint Jacobian evaluations = 2\n",
"Number of inequality constraint Jacobian evaluations = 0\n",
"Number of Lagrangian Hessian evaluations = 1\n",
"Total CPU secs in IPOPT (w/o function evaluations) = 0.119\n",
"Total CPU secs in NLP function evaluations = 0.003\n",
"Total CPU secs in IPOPT (w/o function evaluations) = 0.362\n",
"Total CPU secs in NLP function evaluations = 0.008\n",
"\n",
"EXIT: Optimal Solution Found.\n",
"\n",
Expand Down Expand Up @@ -689,9 +699,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 3
}
}
Loading

0 comments on commit e0d3966

Please sign in to comment.