Repository: Gurobi/gurobi-machinelearning (language: python)

Issue:
Bump pandas from 2.2.1 to 2.2.2
Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.2.1 to 2.2.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/pandas-dev/pandas/releases">pandas's releases</a>.</em></p>
<blockquote>
<h2>Pandas 2.2.2</h2>
<p>We are pleased to announce the release of pandas 2.2.2.
This release includes some new features, bug fixes, and performance improvements. We recommend that all users upgrade to this version.</p>
<p>See the <a href="https://pandas.pydata.org/pandas-docs/version/2.2.2/whatsnew/v2.2.2.html">full whatsnew</a> for a list of all the changes.
Pandas 2.2.2 supports Python 3.9 and higher.</p>
<p>The release will be available on the defaults and conda-forge channels:</p>
<pre><code>conda install pandas
</code></pre>
<p>Or via PyPI:</p>
<pre><code>python3 -m pip install --upgrade pandas
</code></pre>
<p>Please report any issues with the release on the <a href="https://github.com/pandas-dev/pandas/issues">pandas issue tracker</a>.</p>
<p>Thanks to all the contributors who made this release possible.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/pandas-dev/pandas/commit/d9cdd2ee5a58015ef6f4d15c7226110c9aab8140"><code>d9cdd2e</code></a> RLS: 2.2.2</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/98aeac9b1b559178ef4f6a0a112a09b1741d11d1"><code>98aeac9</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58209">#58209</a>: CI: Pin blosc to fix pytables (<a href="https://redirect.github.com/pandas-dev/pandas/issues/58211">#58211</a>)</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/5466f15462784eaa26e7ac43fc382f3802ab3ed1"><code>5466f15</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58202">#58202</a>: DOC/TST: Document numpy 2.0 support and add tests… (<a href="https://redirect.github.com/pandas-dev/pandas/issues/58208">#58208</a>)</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/45b0b32af03e65f8d9547c127f8694fb7c3e994f"><code>45b0b32</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58203">#58203</a> on branch 2.2.x (DOC: Add release date/contributors for 2....</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/c7ec5663b3a5f041d7e8c93fa3d75a1314477e27"><code>c7ec566</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58087">#58087</a> on branch 2.2.x (BLD: Build wheels using numpy 2.0rc1) (<a href="https://redirect.github.com/pandas-dev/pandas/issues/5">#5</a>...</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/691fc88fbd7b570017bbc05fa77754b24c1fa997"><code>691fc88</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58181">#58181</a> on branch 2.2.x (CI: correct error msg in test_view_index)...</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/a947587c8ad419e9cf8f6cce1fd5ad80c32d759f"><code>a947587</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58138">#58138</a> on branch 2.2.x (BLD: Fix nightlies not building) (<a href="https://redirect.github.com/pandas-dev/pandas/issues/58140">#58140</a>)</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/b56842d93dc76dc2a83b7ab640af6a419697decb"><code>b56842d</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58100">#58100</a> on branch 2.2.x (MNT: fix compatibility with beautifulsoup...</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/0f83d50c477f8aafb61a3db1d310d0b5fd261adc"><code>0f83d50</code></a> Revert &quot;BLD: Pin numpy on 2.2.x&quot; (<a href="https://redirect.github.com/pandas-dev/pandas/issues/58093">#58093</a>)</li>
<li><a href="https://github.com/pandas-dev/pandas/commit/e9b81ee3ecca2720f59e21091528e1e1e7eafe9a"><code>e9b81ee</code></a> Backport PR <a href="https://redirect.github.com/pandas-dev/pandas/issues/58126">#58126</a>: BLD: Build wheels with numpy 2.0rc1 (<a href="https://redirect.github.com/pandas-dev/pandas/issues/58127">#58127</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/pandas-dev/pandas/compare/v2.2.1...v2.2.2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pandas&package-manager=pip&previous-version=2.2.1&new-version=2.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/PR_license.yml b/.github/workflows/PR_license.yml
index 73d7c352..1597d77d 100644
--- a/.github/workflows/PR_license.yml
+++ b/.github/workflows/PR_license.yml
@@ -21,7 +21,7 @@ jobs:
     if: contains(github.event.pull_request.labels.*.name, 'safe to test')
     strategy:
       matrix:
-        python-version: ["3.9", "3.10", "3.11"]
+        python-version: ["3.9", "3.10", "3.11", "3.12"]
     steps:
     - uses: actions/checkout@v4
       with:
diff --git a/.github/workflows/PR_nolicense.yml b/.github/workflows/PR_nolicense.yml
index f76cf68f..85ce80e2 100644
--- a/.github/workflows/PR_nolicense.yml
+++ b/.github/workflows/PR_nolicense.yml
@@ -18,7 +18,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ["3.9", "3.10", "3.11"]
+        python-version: ["3.9", "3.10", "3.11", "3.12"]
     steps:
     - uses: actions/checkout@v4
     - name: Set up Python ${{ matrix.python-version }}
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
index 04dff282..51c2478f 100644
--- a/.github/workflows/publish_pypi.yml
+++ b/.github/workflows/publish_pypi.yml
@@ -31,13 +31,13 @@ jobs:
           gurobi-machinelearning \
           https://pypi.anaconda.org/gurobi-machinelearning-wheels-staging/simple/gurobi-machinelearning/
     - name: Publish package to TestPyPI
-      uses: pypa/gh-action-pypi-publish@v1.8.11
+      uses: pypa/gh-action-pypi-publish@v1.8.14
       with:
         password: ${{ secrets.TEST_PYPI_TOKEN }}
         repository_url: https://test.pypi.org/legacy/
       if: ${{ github.event.inputs.pypi_repo == 'testpypi' }}
     - name: Publish package to PyPI
-      uses: pypa/gh-action-pypi-publish@v1.8.11
+      uses: pypa/gh-action-pypi-publish@v1.8.14
       with:
         password: ${{ secrets.PYPI_TOKEN }}
       if: ${{ github.event.inputs.pypi_repo == 'pypi' }}
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 20c1a7c4..4a517fbf 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -18,7 +18,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ["3.9", "3.10", "3.11"]
+        python-version: ["3.9", "3.10", "3.11", "3.12"]
     steps:
     - uses: actions/checkout@v4
     - name: Set up Python ${{ matrix.python-version }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 66db61ec..e2030306 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -46,3 +46,9 @@ repos:
           entry: python3 .github/hooks/license_embedded.py
           language: system
           files: (src/.*\.py|.*\.ipynb)
+
+    - repo: https://github.com/jorisroovers/gitlint
+      rev: v0.19.1 # Fill in a tag / sha here (e.g. v0.19.1)
+      hooks:
+      - id: gitlint
+        args: [--ignore=B6, --msg-filename]
diff --git a/README.md b/README.md
index 6635183a..25f55c04 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 [![build and test](https://github.com/Gurobi/gurobi-machinelearning/actions/workflows/push.yml/badge.svg?branch=main)](https://github.com/Gurobi/gurobi-machinelearning/actions/workflows/push.yml?query=branch%3Amain++)
 [![build wheel](https://github.com/Gurobi/gurobi-machinelearning/actions/workflows/build_wheel.yml/badge.svg?branch=main)](https://github.com/Gurobi/gurobi-machinelearning/actions/workflows/build_wheel.yml?query=branch%3Amain++)
-![Python versions](https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11-blue)
+![Python versions](https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11%203.12-blue)
 [![Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
 [![PyPI](https://img.shields.io/pypi/v/gurobi-machinelearning)](https://pypi.org/project/gurobi-machinelearning)
 [![ReadTheDocs](https://readthedocs.com/projects/gurobi-optimization-gurobi-machine-learning/badge/?version=stable)](https://gurobi-optimization-gurobi-machine-learning.readthedocs-hosted.com)
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 9f239031..e7ecb1b7 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,13 +1,13 @@
 gurobipy==11.0.1
 gurobipy-pandas==1.1.1
-ipykernel==6.29.3
+ipykernel==6.29.4
 jupytext==1.16.1
 matplotlib==3.6.0
-matplotlib-inline==0.1.6
+matplotlib-inline==0.1.7
 sphinxcontrib_bibtex==2.6.2
 numpy==1.26.4
-numpydoc==1.6.0
-pandas==2.2.1
+numpydoc==1.7.0
+pandas==2.2.2
 scikit-learn==1.4.1.post1
 seaborn==0.13.2
 Sphinx==7.2.6
diff --git a/notebooks/adversarial/adversarial_keras.ipynb b/notebooks/adversarial/adversarial_keras.ipynb
index 23ac01d0..9eeb629f 100644
--- a/notebooks/adversarial/adversarial_keras.ipynb
+++ b/notebooks/adversarial/adversarial_keras.ipynb
@@ -88,7 +88,7 @@
    "source": [
     "nn = tf.keras.models.Sequential(\n",
     "    [\n",
-    "        tf.keras.layers.InputLayer(28 * 28),\n",
+    "        tf.keras.layers.InputLayer((28 * 28,)),\n",
     "        tf.keras.layers.Dense(50, activation=\"relu\"),\n",
     "        tf.keras.layers.Dense(50, activation=\"relu\"),\n",
     "        tf.keras.layers.Dense(10),\n",
@@ -243,9 +243,9 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3.10",
+   "display_name": "Python 3 (ipykernel)",
    "language": "python",
-   "name": "python310"
+   "name": "python3"
   },
   "language_info": {
    "codemirror_mode": {
@@ -257,7 +257,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.11.8"
   },
   "license": {
    "full_text": "# Copyright © 2023 Gurobi Optimization, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# =============================================================================="
diff --git a/pyproject.toml b/pyproject.toml
index b0962636..9831662d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "gurobi-machinelearning"
-version = "1.5.0"
+version = "1.5.0post1"
 description = "package to insert ML models in Gurobi"
 readme = "README.md"
 requires-python = ">=3.9"
diff --git a/requirements.keras.txt b/requirements.keras.txt
index 475ea226..71e8ec31 100644
--- a/requirements.keras.txt
+++ b/requirements.keras.txt
@@ -1,1 +1,1 @@
-tensorflow==2.15.0.post1
+tensorflow==2.16.1
diff --git a/requirements.pandas.txt b/requirements.pandas.txt
index 4f2db945..9ecb783e 100644
--- a/requirements.pandas.txt
+++ b/requirements.pandas.txt
@@ -1,2 +1,2 @@
-pandas==2.2.1
+pandas==2.2.2
 gurobipy-pandas==1.1.1
diff --git a/requirements.pytorch.txt b/requirements.pytorch.txt
index dcf8d3e4..c5ddafe5 100644
--- a/requirements.pytorch.txt
+++ b/requirements.pytorch.txt
@@ -1,1 +1,1 @@
-torch==2.2.1
+torch==2.2.2
diff --git a/requirements.tox.txt b/requirements.tox.txt
index ec114b4f..2d3d4f2c 100644
--- a/requirements.tox.txt
+++ b/requirements.tox.txt
@@ -1,2 +1,2 @@
 numpy==1.26.4
-scipy==1.12.0
+scipy==1.13.0
diff --git a/requirements.txt b/requirements.txt
index 3400bf6b..2653a5b9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
 gurobipy==11.0.1
 numpy==1.26.4
-pandas==2.2.1
+pandas==2.2.2
 scikit-learn==1.4.1.post1
 seaborn==0.13.2
 .
diff --git a/tox.ini b/tox.ini
index 72c6f1f5..a69b7764 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,13 +4,14 @@
 # and then run "tox" from this directory.
 
 [tox]
-envlist = {py39,py310,py311}-{lightgbm,keras,pytorch,sklearn,xgboost,no_deps,all_deps}-{gurobi10,gurobi11},pre-commit,docs,examples-{gurobi10,gurobi11}
+envlist = {py39,py310,py311,py312}-{lightgbm,keras,pytorch,sklearn,xgboost,no_deps,all_deps}-{gurobi10,gurobi11},pre-commit,docs,examples-{gurobi10,gurobi11}
 isolated_build = True
 
 [gh-actions]
 python =
     3.9: py39-all_deps-gurobi11
     3.10: py310-all_deps-gurobi11
+    3.12: py312-all_deps-gurobi11
     3.11: pre-commit, docs,py311-{lightgbm,keras,pytorch,sklearn,xgboost,no_deps,all_deps}-{gurobi10,gurobi11}
 
 [testenv:docs]
@@ -34,7 +35,7 @@ deps =
     ipywidgets
     seaborn
     gurobi10: gurobipy==10.0.3
-    gurobi11: gurobipy==11.0.0
+    gurobi11: gurobipy==11.0.1
 
 changedir = {toxinidir}/notebooks
 allowlist_externals = /usr/bin/make
@@ -72,30 +73,30 @@ deps =
     pytest-cov
     joblib
     gurobi10: gurobipy==10.0.3
-    gurobi11: gurobipy==11.0.0
+    gurobi11: gurobipy==11.0.1
 
-[testenv:{py39,py310,py311}-keras-{gurobi10,gurobi11}]
+[testenv:{py39,py310,py311,py312}-keras-{gurobi10,gurobi11}]
 deps =
     {[base]deps}
     -r{toxinidir}/requirements.keras.txt
 commands =
     pytest tests/test_keras
 
-[testenv:{py39,py310,py311}-pytorch-{gurobi10,gurobi11}]
+[testenv:{py39,py310,py311,py312}-pytorch-{gurobi10,gurobi11}]
 deps =
     {[base]deps}
     -r{toxinidir}/requirements.pytorch.txt
 commands =
     pytest tests/test_pytorch
 
-[testenv:{py39,py310,py311}-sklearn-{gurobi10,gurobi11}]
+[testenv:{py39,py310,py311,py312}-sklearn-{gurobi10,gurobi11}]
 deps =
     {[base]deps}
     -r{toxinidir}/requirements.sklearn.txt
 commands =
     pytest tests/test_sklearn
 
-[testenv:{py39,py310,py311}-xgboost-{gurobi10,gurobi11}]
+[testenv:{py39,py310,py311,py312}-xgboost-{gurobi10,gurobi11}]
 deps =
     {[base]deps}
     -r{toxinidir}/requirements.sklearn.txt
@@ -103,7 +104,7 @@ deps =
 commands =
     pytest tests/test_xgboost
 
-[testenv:{py39,py310,py311}-lightgbm-{gurobi10,gurobi11}]
+[testenv:{py39,py310,py311,py312}-lightgbm-{gurobi10,gurobi11}]
 deps =
     {[base]deps}
     -r{toxinidir}/requirements.lightgbm.txt
@@ -111,13 +112,13 @@ deps =
 commands =
     pytest tests/test_lightgbm
 
-[testenv:{py39,py310,py311}-no_deps]
+[testenv:{py39,py310,py311,py312}-no_deps]
 deps =
     pytest
 commands =
     pytest tests/test_no_deps
 
-[testenv:{py39,py310,py311}-all_deps-{gurobi10,gurobi11}]
+[testenv:{py39,py310,py311,py312}-all_deps-{gurobi10,gurobi11}]
 deps =
     {[base]deps}
     -r{toxinidir}/requirements.keras.txt


Test patch:
diff --git a/tests/predictors/diabetes.keras b/tests/predictors/diabetes.keras
new file mode 100644
index 00000000..f298c5be
Binary files /dev/null and b/tests/predictors/diabetes.keras differ
diff --git a/tests/predictors/diabetes_keras/keras_metadata.pb b/tests/predictors/diabetes_keras/keras_metadata.pb
deleted file mode 100644
index 460cfb57..00000000
--- a/tests/predictors/diabetes_keras/keras_metadata.pb
+++ /dev/null
@@ -1,6 +0,0 @@
-
-�"root"_tf_keras_sequential*�"{"name": "sequential_9", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "class_name": "Sequential", "config": {"name": "sequential_9", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_21_input"}}, {"class_name": "Dense", "config": {"name": "dense_21", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_22", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_23", "trainable": true, "dtype": "float32", "units": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "shared_object_id": 10, "build_input_shape": {"class_name": "TensorShape", "items": [null, 10]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 10]}, "float32", "dense_21_input"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 10]}, "float32", "dense_21_input"]}, "keras_version": "2.9.0", "backend": "tensorflow", "model_config": {"class_name": "Sequential", "config": {"name": "sequential_9", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_21_input"}, "shared_object_id": 0}, {"class_name": "Dense", "config": {"name": "dense_21", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3}, {"class_name": "Dense", "config": {"name": "dense_22", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 4}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 5}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 6}, {"class_name": "Dense", "config": {"name": "dense_23", "trainable": true, "dtype": "float32", "units": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 7}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 8}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 9}]}}, "training_config": {"loss": "mean_absolute_error", "metrics": null, "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.10000000149011612, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2
-�root.layer_with_weights-0"_tf_keras_layer*�{"name": "dense_21", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_21", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 10}}, "shared_object_id": 11}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 10]}}2
-�root.layer_with_weights-1"_tf_keras_layer*�{"name": "dense_22", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_22", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 4}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 5}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 6, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 20}}, "shared_object_id": 12}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 20]}}2
-�root.layer_with_weights-2"_tf_keras_layer*�{"name": "dense_23", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_23", "trainable": true, "dtype": "float32", "units": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 7}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 8}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 9, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 20}}, "shared_object_id": 13}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 20]}}2
-�Mroot.keras_api.metrics.0"_tf_keras_metric*�{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 14}2
\ No newline at end of file
diff --git a/tests/predictors/diabetes_keras/saved_model.pb b/tests/predictors/diabetes_keras/saved_model.pb
deleted file mode 100644
index 0f47028e..00000000
Binary files a/tests/predictors/diabetes_keras/saved_model.pb and /dev/null differ
diff --git a/tests/predictors/diabetes_keras/variables/variables.data-00000-of-00001 b/tests/predictors/diabetes_keras/variables/variables.data-00000-of-00001
deleted file mode 100644
index fea8f9db..00000000
Binary files a/tests/predictors/diabetes_keras/variables/variables.data-00000-of-00001 and /dev/null differ
diff --git a/tests/predictors/diabetes_keras/variables/variables.index b/tests/predictors/diabetes_keras/variables/variables.index
deleted file mode 100644
index 02aee116..00000000
Binary files a/tests/predictors/diabetes_keras/variables/variables.index and /dev/null differ
diff --git a/tests/predictors/diabetes_keras_v2/keras_metadata.pb b/tests/predictors/diabetes_keras_v2/keras_metadata.pb
deleted file mode 100644
index 8a1c5b6d..00000000
--- a/tests/predictors/diabetes_keras_v2/keras_metadata.pb
+++ /dev/null
@@ -1,8 +0,0 @@
-
-�'root"_tf_keras_sequential*�'{"name": "sequential_10", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "class_name": "Sequential", "config": {"name": "sequential_10", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_26_input"}}, {"class_name": "Dense", "config": {"name": "dense_26", "trainable": true, "dtype": "float32", "units": 20, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "ReLU", "config": {"name": "re_lu", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}}, {"class_name": "Dense", "config": {"name": "dense_27", "trainable": true, "dtype": "float32", "units": 20, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "ReLU", "config": {"name": "re_lu_1", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}}, {"class_name": "Dense", "config": {"name": "dense_28", "trainable": true, "dtype": "float32", "units": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "shared_object_id": 12, "build_input_shape": {"class_name": "TensorShape", "items": [null, 10]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 10]}, "float32", "dense_26_input"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 10]}, "float32", "dense_26_input"]}, "keras_version": "2.9.0", "backend": "tensorflow", "model_config": {"class_name": "Sequential", "config": {"name": "sequential_10", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_26_input"}, "shared_object_id": 0}, {"class_name": "Dense", "config": {"name": "dense_26", "trainable": true, "dtype": "float32", "units": 20, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3}, {"class_name": "ReLU", "config": {"name": "re_lu", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 4}, {"class_name": "Dense", "config": {"name": "dense_27", "trainable": true, "dtype": "float32", "units": 20, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 5}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 6}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 7}, {"class_name": "ReLU", "config": {"name": "re_lu_1", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 8}, {"class_name": "Dense", "config": {"name": "dense_28", "trainable": true, "dtype": "float32", "units": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 9}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 10}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 11}]}}, "training_config": {"loss": "mean_absolute_error", "metrics": null, "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.10000000149011612, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2
-�root.layer_with_weights-0"_tf_keras_layer*�{"name": "dense_26", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_26", "trainable": true, "dtype": "float32", "units": 20, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 10}}, "shared_object_id": 13}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 10]}}2
-�root.layer-1"_tf_keras_layer*�{"name": "re_lu", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ReLU", "config": {"name": "re_lu", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 4}2
-�root.layer_with_weights-1"_tf_keras_layer*�{"name": "dense_27", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_27", "trainable": true, "dtype": "float32", "units": 20, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 5}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 6}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 7, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 20}}, "shared_object_id": 14}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 20]}}2
-�root.layer-3"_tf_keras_layer*�{"name": "re_lu_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ReLU", "config": {"name": "re_lu_1", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 8}2
-�root.layer_with_weights-2"_tf_keras_layer*�{"name": "dense_28", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_28", "trainable": true, "dtype": "float32", "units": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 9}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 10}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 11, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 20}}, "shared_object_id": 15}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 20]}}2
-�iroot.keras_api.metrics.0"_tf_keras_metric*�{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 16}2
\ No newline at end of file
diff --git a/tests/predictors/diabetes_keras_v2/saved_model.pb b/tests/predictors/diabetes_keras_v2/saved_model.pb
deleted file mode 100644
index 964ec6a3..00000000
Binary files a/tests/predictors/diabetes_keras_v2/saved_model.pb and /dev/null differ
diff --git a/tests/predictors/diabetes_keras_v2/variables/variables.data-00000-of-00001 b/tests/predictors/diabetes_keras_v2/variables/variables.data-00000-of-00001
deleted file mode 100644
index 4184766f..00000000
Binary files a/tests/predictors/diabetes_keras_v2/variables/variables.data-00000-of-00001 and /dev/null differ
diff --git a/tests/predictors/diabetes_keras_v2/variables/variables.index b/tests/predictors/diabetes_keras_v2/variables/variables.index
deleted file mode 100644
index beb7505d..00000000
Binary files a/tests/predictors/diabetes_keras_v2/variables/variables.index and /dev/null differ
diff --git a/tests/predictors/diabetes_v2.keras b/tests/predictors/diabetes_v2.keras
new file mode 100644
index 00000000..4f4c679c
Binary files /dev/null and b/tests/predictors/diabetes_v2.keras differ
diff --git a/tests/test_keras/test_keras_exceptions.py b/tests/test_keras/test_keras_exceptions.py
index 559244e8..2eace2c2 100644
--- a/tests/test_keras/test_keras_exceptions.py
+++ b/tests/test_keras/test_keras_exceptions.py
@@ -51,7 +51,7 @@ def test_keras_bad_activation(self):
 
         nn = tf.keras.models.Sequential(
             [
-                tf.keras.layers.InputLayer(28 * 28),
+                tf.keras.layers.InputLayer((28 * 28,)),
                 tf.keras.layers.Dense(50, activation="sigmoid"),
                 tf.keras.layers.Dense(50, activation="relu"),
                 tf.keras.layers.Dense(10),
@@ -89,7 +89,7 @@ def do_relu_tests(self, **kwargs):
 
         nn = tf.keras.models.Sequential(
             [
-                tf.keras.layers.InputLayer(28 * 28),
+                tf.keras.layers.InputLayer((28 * 28,)),
                 tf.keras.layers.Dense(50),
                 tf.keras.layers.ReLU(**kwargs),
                 tf.keras.layers.Dense(10),
diff --git a/tests/test_keras/test_keras_formulations.py b/tests/test_keras/test_keras_formulations.py
index 9e4a3d0d..0beeb30b 100644
--- a/tests/test_keras/test_keras_formulations.py
+++ b/tests/test_keras/test_keras_formulations.py
@@ -17,7 +17,7 @@ class TestKerasModel(FixedRegressionModel):
     def test_diabetes_keras(self):
         X = load(os.path.join(self.basedir, "examples_diabetes.joblib"))
 
-        filename = os.path.join(self.basedir, "diabetes_keras")
+        filename = os.path.join(self.basedir, "diabetes.keras")
         regressor = tf.keras.models.load_model(filename)
         onecase = {"predictor": regressor, "nonconvex": 0}
         self.do_one_case(onecase, X, 5, "all")
@@ -27,7 +27,7 @@ def test_diabetes_keras_alt(self):
         X = load(os.path.join(self.basedir, "examples_diabetes.joblib"))
 
         filename = os.path.join(
-            os.path.dirname(__file__), "..", "predictors", "diabetes_keras_v2"
+            os.path.dirname(__file__), "..", "predictors", "diabetes_v2.keras"
         )
         print(filename)
         regressor = tf.keras.models.load_model(filename)