From efe4a8c6165054d6f6999aa3d917cbb91523fdb8 Mon Sep 17 00:00:00 2001 From: Steven Berguin Date: Fri, 5 Dec 2025 08:51:44 -0500 Subject: [PATCH 1/3] #2: updated JENN 2.0 --- requirements.txt | 3 +- smt/surrogate_models/genn.py | 7 ++- smt/surrogate_models/tests/test_genn.py | 59 +++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 smt/surrogate_models/tests/test_genn.py diff --git a/requirements.txt b/requirements.txt index f749fb76a..32c4fe395 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,5 +10,6 @@ pytest # tests runner pytest-xdist # allows running parallel testing with pytest -n pytest-cov # allows to get coverage report ruff # format and lint code -jenn >= 1.0.2, <2.0 +# jenn >= 1.0.2, <2.0 +git+https://github.com/shb84/JENN.git egobox >= 0.25.0, <1.0 diff --git a/smt/surrogate_models/genn.py b/smt/surrogate_models/genn.py index 532c8b23f..e63c4589e 100644 --- a/smt/surrogate_models/genn.py +++ b/smt/surrogate_models/genn.py @@ -9,7 +9,7 @@ from typing import Dict, List, Tuple, Union import numpy as np -from jenn.model import NeuralNet +import jenn from smt.surrogate_models.surrogate_model import SurrogateModel from smt.utils import persistence @@ -70,7 +70,6 @@ class GENN(SurrogateModel): def load_data(self, xt, yt, dyt_dxt=None): """Load all training data into surrogate model in one step. - :param model: SurrogateModel object for which to load training data :param xt: smt data points at which response is evaluated :param yt: response at xt :param dyt_dxt: gradient at xt @@ -167,7 +166,7 @@ def _initialize(self): ) self.options.declare( "is_normalize", - default=False, + default=True, types=bool, desc="normalize training by mean and variance", ) @@ -183,7 +182,7 @@ def _final_initialize(self): output = [1] # will be overwritten during training (dummy value) hidden = self.options["hidden_layer_sizes"] layer_sizes = inputs + hidden + output - self.model = NeuralNet(layer_sizes) + self.model = jenn.NeuralNet(layer_sizes) def _train(self): X, Y, J = _smt_to_genn(self.training_points) diff --git a/smt/surrogate_models/tests/test_genn.py b/smt/surrogate_models/tests/test_genn.py new file mode 100644 index 000000000..7047e8f73 --- /dev/null +++ b/smt/surrogate_models/tests/test_genn.py @@ -0,0 +1,59 @@ +import numpy as np +import unittest +import jenn +import smt + +class TestGENN(unittest.TestCase): + + def test_rosenbrock(self): + """Check GENN predictions on Rosenbrock function.""" + + # Generate synthetic training data outside of SMT (using JENN) + x_train, y_train, dydx_train = jenn.utilities.sample( + f=jenn.synthetic_data.rosenbrock.compute, + f_prime=jenn.synthetic_data.rosenbrock.compute_partials, + m_random=0, + m_levels=3, + lb=[-np.pi, -np.pi], + ub=[np.pi, np.pi], + ) + + # Generate synthetic test data outside of SMT (using JENN) + x_test, y_test, dydx_test = jenn.utilities.sample( + f=jenn.synthetic_data.rosenbrock.compute, + f_prime=jenn.synthetic_data.rosenbrock.compute_partials, + m_random=0, + m_levels=100, + lb=[-np.pi, -np.pi], + ub=[np.pi, np.pi], + ) + + # SMT and JENN data structures are transposed from each other + x_train = x_train.T + y_train = y_train.T + dydx_train = dydx_train.squeeze().T + + x_test = x_test.T + y_test = y_test.T + dydx_test = dydx_test.squeeze().T + + # Training model using SMT API as usual + genn = smt.surrogate_models.GENN() + genn.options["hidden_layer_sizes"] = [12, 12] + genn.options["alpha"] = 0.01 + genn.options["lambd"] = 0.01 + genn.options["gamma"] = 1 + genn.options["num_iterations"] = 5000 + genn.options["is_backtracking"] = True + genn.options["is_normalize"] = True + genn.options["seed"] = 123 + genn.load_data(x_train, y_train, dydx_train) + genn.train() + + # Predict test data + y_pred = genn.predict_values(x_test) + + # Make sure the prediction is good + rsquare = jenn.metrics.rsquare(y_pred.ravel(), y_test.ravel()) + tol = 0.99 + self.assertGreater(rsquare, tol, msg=f"R^2 = {rsquare:.3f} is less than {tol}") \ No newline at end of file From d78ef7d260c34b1c8ad9169442ff1ad3a8f5e605 Mon Sep 17 00:00:00 2001 From: Steven Berguin Date: Sat, 6 Dec 2025 10:21:59 -0500 Subject: [PATCH 2/3] #2: updated requirements (jenn 2.0.0) --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 32c4fe395..7458067c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,5 @@ pytest # tests runner pytest-xdist # allows running parallel testing with pytest -n pytest-cov # allows to get coverage report ruff # format and lint code -# jenn >= 1.0.2, <2.0 -git+https://github.com/shb84/JENN.git +jenn >= 2.0.0, <3.0 egobox >= 0.25.0, <1.0 From 1c77c15417b930952411bee4f064f2946953a728 Mon Sep 17 00:00:00 2001 From: Steven Berguin Date: Sat, 6 Dec 2025 10:56:14 -0500 Subject: [PATCH 3/3] #2: linting --- smt/surrogate_models/genn.py | 2 +- smt/surrogate_models/tests/test_genn.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/smt/surrogate_models/genn.py b/smt/surrogate_models/genn.py index e63c4589e..896347272 100644 --- a/smt/surrogate_models/genn.py +++ b/smt/surrogate_models/genn.py @@ -9,7 +9,7 @@ from typing import Dict, List, Tuple, Union import numpy as np -import jenn +import jenn from smt.surrogate_models.surrogate_model import SurrogateModel from smt.utils import persistence diff --git a/smt/surrogate_models/tests/test_genn.py b/smt/surrogate_models/tests/test_genn.py index 7047e8f73..bc3f57d62 100644 --- a/smt/surrogate_models/tests/test_genn.py +++ b/smt/surrogate_models/tests/test_genn.py @@ -1,10 +1,10 @@ -import numpy as np +import numpy as np import unittest -import jenn +import jenn import smt + class TestGENN(unittest.TestCase): - def test_rosenbrock(self): """Check GENN predictions on Rosenbrock function.""" @@ -37,7 +37,7 @@ def test_rosenbrock(self): y_test = y_test.T dydx_test = dydx_test.squeeze().T - # Training model using SMT API as usual + # Training model using SMT API as usual genn = smt.surrogate_models.GENN() genn.options["hidden_layer_sizes"] = [12, 12] genn.options["alpha"] = 0.01 @@ -50,10 +50,10 @@ def test_rosenbrock(self): genn.load_data(x_train, y_train, dydx_train) genn.train() - # Predict test data + # Predict test data y_pred = genn.predict_values(x_test) - # Make sure the prediction is good + # Make sure the prediction is good rsquare = jenn.metrics.rsquare(y_pred.ravel(), y_test.ravel()) tol = 0.99 - self.assertGreater(rsquare, tol, msg=f"R^2 = {rsquare:.3f} is less than {tol}") \ No newline at end of file + self.assertGreater(rsquare, tol, msg=f"R^2 = {rsquare:.3f} is less than {tol}")