diff --git a/examples/keras_recipes/ipynb/tensorflow_numpy_models.ipynb b/examples/keras_recipes/ipynb/tensorflow_numpy_models.ipynb index e555038d89..aa1cb0c5c1 100644 --- a/examples/keras_recipes/ipynb/tensorflow_numpy_models.ipynb +++ b/examples/keras_recipes/ipynb/tensorflow_numpy_models.ipynb @@ -41,8 +41,7 @@ "colab_type": "text" }, "source": [ - "## Setup\n", - "TensorFlow NumPy requires TensorFlow 2.5 or later." + "## Setup" ] }, { @@ -53,32 +52,14 @@ }, "outputs": [], "source": [ + "import os\n", + "\n", + "os.environ[\"KERAS_BACKEND\"] = \"tensorflow\"\n", + "\n", "import tensorflow as tf\n", "import tensorflow.experimental.numpy as tnp\n", "import keras\n", - "import keras.layers as layers\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text" - }, - "source": [ - "Optionally, you can call `tnp.experimental_enable_numpy_behavior()` to enable type promotion in TensorFlow.\n", - "This allows TNP to more closely follow the NumPy standard." - ] - }, - { - "cell_type": "code", - "execution_count": 0, - "metadata": { - "colab_type": "code" - }, - "outputs": [], - "source": [ - "tnp.experimental_enable_numpy_behavior()" + "from keras import layers" ] }, { @@ -98,16 +79,17 @@ }, "outputs": [], "source": [ - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.boston_housing.load_data(\n", + "(x_train, y_train), (x_test, y_test) = keras.datasets.boston_housing.load_data(\n", " path=\"boston_housing.npz\", test_split=0.2, seed=113\n", ")\n", + "input_dim = x_train.shape[1]\n", "\n", "\n", "def evaluate_model(model: keras.Model):\n", - " [loss, percent_error] = model.evaluate(x_test, y_test, verbose=0)\n", + " loss, percent_error = model.evaluate(x_test, y_test, verbose=0)\n", " print(\"Mean absolute percent error before training: \", percent_error)\n", " model.fit(x_train, y_train, epochs=200, verbose=0)\n", - " [loss, percent_error] = model.evaluate(x_test, y_test, verbose=0)\n", + " loss, percent_error = model.evaluate(x_test, y_test, verbose=0)\n", " print(\"Mean absolute percent error after training:\", percent_error)\n", "" ] @@ -157,16 +139,27 @@ " for i, block in enumerate(self.blocks):\n", " self.block_weights.append(\n", " self.add_weight(\n", - " shape=(current_shape, block), trainable=True, name=f\"block-{i}\"\n", + " shape=(current_shape, block),\n", + " trainable=True,\n", + " name=f\"block-{i}\",\n", + " initializer=\"glorot_normal\",\n", " )\n", " )\n", " self.biases.append(\n", - " self.add_weight(shape=(block,), trainable=True, name=f\"bias-{i}\")\n", + " self.add_weight(\n", + " shape=(block,),\n", + " trainable=True,\n", + " name=f\"bias-{i}\",\n", + " initializer=\"zeros\",\n", + " )\n", " )\n", " current_shape = block\n", "\n", " self.linear_layer = self.add_weight(\n", - " shape=(current_shape, 1), name=\"linear_projector\", trainable=True\n", + " shape=(current_shape, 1),\n", + " name=\"linear_projector\",\n", + " trainable=True,\n", + " initializer=\"glorot_normal\",\n", " )\n", "\n", " def call(self, inputs):\n", @@ -215,7 +208,7 @@ "colab_type": "text" }, "source": [ - "Great! Our model seems to be effectively learning to solve the problem at hand.\n", + "Great! Our model seems to be effectively learning to solve the problem at hand.\n", "\n", "We can also write our own custom loss function using TNP." ] @@ -284,7 +277,7 @@ " self.bias = self.add_weight(\n", " name=\"bias\",\n", " shape=(self.units,),\n", - " initializer=\"random_normal\",\n", + " initializer=\"zeros\",\n", " trainable=True,\n", " )\n", "\n", @@ -311,7 +304,7 @@ " loss=\"mean_squared_error\",\n", " metrics=[keras.metrics.MeanAbsolutePercentageError()],\n", ")\n", - "model.build((None, 13,))\n", + "model.build((None, input_dim))\n", "model.summary()\n", "\n", "evaluate_model(model)" @@ -353,7 +346,7 @@ " loss=\"mean_squared_error\",\n", " metrics=[keras.metrics.MeanAbsolutePercentageError()],\n", ")\n", - "model.build((None, 13,))\n", + "model.build((None, input_dim))\n", "model.summary()\n", "\n", "evaluate_model(model)" @@ -406,7 +399,7 @@ " loss=\"mean_squared_error\",\n", " metrics=[keras.metrics.MeanAbsolutePercentageError()],\n", " )\n", - " model.build((None, 13,))\n", + " model.build((None, input_dim))\n", " model.summary()\n", " evaluate_model(model)" ] @@ -456,7 +449,10 @@ "outputs": [], "source": [ "models = [\n", - " (TNPForwardFeedRegressionNetwork(blocks=[3, 3]), \"TNPForwardFeedRegressionNetwork\"),\n", + " (\n", + " TNPForwardFeedRegressionNetwork(blocks=[3, 3]),\n", + " \"TNPForwardFeedRegressionNetwork\",\n", + " ),\n", " (create_layered_tnp_model(), \"layered_tnp_model\"),\n", " (create_mixed_model(), \"mixed_model\"),\n", "]\n", @@ -546,4 +542,4 @@ }, "nbformat": 4, "nbformat_minor": 0 -} +} \ No newline at end of file diff --git a/examples/keras_recipes/md/tensorflow_numpy_models.md b/examples/keras_recipes/md/tensorflow_numpy_models.md index 324792852a..124d7c7b08 100644 --- a/examples/keras_recipes/md/tensorflow_numpy_models.md +++ b/examples/keras_recipes/md/tensorflow_numpy_models.md @@ -27,43 +27,45 @@ Let's run through a few examples. --- ## Setup -TensorFlow NumPy requires TensorFlow 2.5 or later. ```python +import os + +os.environ["KERAS_BACKEND"] = "tensorflow" + import tensorflow as tf import tensorflow.experimental.numpy as tnp import keras -import keras.layers as layers -import numpy as np -``` - -Optionally, you can call `tnp.experimental_enable_numpy_behavior()` to enable type promotion in TensorFlow. -This allows TNP to more closely follow the NumPy standard. - - -```python -tnp.experimental_enable_numpy_behavior() +from keras import layers ``` To test our models we will use the Boston housing prices regression dataset. ```python -(x_train, y_train), (x_test, y_test) = tf.keras.datasets.boston_housing.load_data( +(x_train, y_train), (x_test, y_test) = keras.datasets.boston_housing.load_data( path="boston_housing.npz", test_split=0.2, seed=113 ) +input_dim = x_train.shape[1] def evaluate_model(model: keras.Model): - [loss, percent_error] = model.evaluate(x_test, y_test, verbose=0) + loss, percent_error = model.evaluate(x_test, y_test, verbose=0) print("Mean absolute percent error before training: ", percent_error) model.fit(x_train, y_train, epochs=200, verbose=0) - [loss, percent_error] = model.evaluate(x_test, y_test, verbose=0) + loss, percent_error = model.evaluate(x_test, y_test, verbose=0) print("Mean absolute percent error after training:", percent_error) ``` +
+``` +Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/california_housing.npz + 743530/743530 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step + +``` +
--- ## Subclassing keras.Model with TNP @@ -97,16 +99,27 @@ class TNPForwardFeedRegressionNetwork(keras.Model): for i, block in enumerate(self.blocks): self.block_weights.append( self.add_weight( - shape=(current_shape, block), trainable=True, name=f"block-{i}" + shape=(current_shape, block), + trainable=True, + name=f"block-{i}", + initializer="glorot_normal", ) ) self.biases.append( - self.add_weight(shape=(block,), trainable=True, name=f"bias-{i}") + self.add_weight( + shape=(block,), + trainable=True, + name=f"bias-{i}", + initializer="zeros", + ) ) current_shape = block self.linear_layer = self.add_weight( - shape=(current_shape, 1), name="linear_projector", trainable=True + shape=(current_shape, 1), + name="linear_projector", + trainable=True, + initializer="glorot_normal", ) def call(self, inputs): @@ -138,12 +151,15 @@ evaluate_model(model)
``` -Mean absolute percent error before training: 422.45343017578125 -Mean absolute percent error after training: 97.24715423583984 +WARNING: All log messages before absl::InitializeLog() is called are written to STDERR +I0000 00:00:1699476780.568655 331531 device_compiler.h:186] Compiled cluster using XLA! This line is logged at most once for the lifetime of the process. + +Mean absolute percent error before training: 100.00450134277344 +Mean absolute percent error after training: 100.0 ```
-Great! Our model seems to be effectively learning to solve the problem at hand. +Great! Our model seems to be effectively learning to solve the problem at hand. We can also write our own custom loss function using TNP. @@ -166,8 +182,8 @@ evaluate_model(model)
``` -Mean absolute percent error before training: 79.84039306640625 -Mean absolute percent error after training: 28.658035278320312 +Mean absolute percent error before training: 99.8993911743164 +Mean absolute percent error after training: 42.862823486328125 ```
@@ -200,7 +216,7 @@ class TNPDense(keras.layers.Layer): self.bias = self.add_weight( name="bias", shape=(self.units,), - initializer="random_normal", + initializer="zeros", trainable=True, ) @@ -227,30 +243,54 @@ model.compile( loss="mean_squared_error", metrics=[keras.metrics.MeanAbsolutePercentageError()], ) -model.build((None, 13,)) +model.build((None, input_dim)) model.summary() evaluate_model(model) ``` + +
Model: "sequential"
+
+ + + + +
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
+┃ Layer (type)                     Output Shape                  Param # ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
+│ tnp_dense (TNPDense)            │ (None, 3)                 │         27 │
+├─────────────────────────────────┼───────────────────────────┼────────────┤
+│ tnp_dense_1 (TNPDense)          │ (None, 3)                 │         12 │
+├─────────────────────────────────┼───────────────────────────┼────────────┤
+│ tnp_dense_2 (TNPDense)          │ (None, 1)                 │          4 │
+└─────────────────────────────────┴───────────────────────────┴────────────┘
+
+ + + + +
 Total params: 43 (172.00 B)
+
+ + + + +
 Trainable params: 43 (172.00 B)
+
+ + + + +
 Non-trainable params: 0 (0.00 B)
+
+ + +
``` -Model: "sequential" -_________________________________________________________________ -Layer (type) Output Shape Param # -================================================================= -tnp_dense (TNPDense) (None, 3) 42 -_________________________________________________________________ -tnp_dense_1 (TNPDense) (None, 3) 12 -_________________________________________________________________ -tnp_dense_2 (TNPDense) (None, 1) 4 -================================================================= -Total params: 58 -Trainable params: 58 -Non-trainable params: 0 -_________________________________________________________________ -Mean absolute percent error before training: 101.17143249511719 -Mean absolute percent error after training: 23.479856491088867 +Mean absolute percent error before training: 99.99999237060547 +Mean absolute percent error after training: 42.25301742553711 ```
@@ -277,30 +317,54 @@ model.compile( loss="mean_squared_error", metrics=[keras.metrics.MeanAbsolutePercentageError()], ) -model.build((None, 13,)) +model.build((None, input_dim)) model.summary() evaluate_model(model) ``` + +
Model: "sequential_1"
+
+ + + + +
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
+┃ Layer (type)                     Output Shape                  Param # ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
+│ tnp_dense_3 (TNPDense)          │ (None, 3)                 │         27 │
+├─────────────────────────────────┼───────────────────────────┼────────────┤
+│ dense (Dense)                   │ (None, 3)                 │         12 │
+├─────────────────────────────────┼───────────────────────────┼────────────┤
+│ tnp_dense_4 (TNPDense)          │ (None, 1)                 │          4 │
+└─────────────────────────────────┴───────────────────────────┴────────────┘
+
+ + + + +
 Total params: 43 (172.00 B)
+
+ + + + +
 Trainable params: 43 (172.00 B)
+
+ + + + +
 Non-trainable params: 0 (0.00 B)
+
+ + +
``` -Model: "sequential_1" -_________________________________________________________________ -Layer (type) Output Shape Param # -================================================================= -tnp_dense_3 (TNPDense) (None, 3) 42 -_________________________________________________________________ -dense (Dense) (None, 3) 12 -_________________________________________________________________ -tnp_dense_4 (TNPDense) (None, 1) 4 -================================================================= -Total params: 58 -Trainable params: 58 -Non-trainable params: 0 -_________________________________________________________________ -Mean absolute percent error before training: 104.59967041015625 -Mean absolute percent error after training: 27.712949752807617 +Mean absolute percent error before training: 100.0 +Mean absolute percent error after training: 44.0278205871582 ```
@@ -332,30 +396,59 @@ with strategy.scope(): loss="mean_squared_error", metrics=[keras.metrics.MeanAbsolutePercentageError()], ) - model.build((None, 13,)) + model.build((None, input_dim)) model.summary() evaluate_model(model) ```
``` -Running with strategy: _DefaultDistributionStrategy -Model: "sequential_2" -_________________________________________________________________ -Layer (type) Output Shape Param # -================================================================= -tnp_dense_5 (TNPDense) (None, 3) 42 -_________________________________________________________________ -tnp_dense_6 (TNPDense) (None, 3) 12 -_________________________________________________________________ -tnp_dense_7 (TNPDense) (None, 1) 4 -================================================================= -Total params: 58 -Trainable params: 58 -Non-trainable params: 0 -_________________________________________________________________ -Mean absolute percent error before training: 100.5331039428711 -Mean absolute percent error after training: 20.71842384338379 +INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',) +Running with strategy: MirroredStrategy + +``` +
+
Model: "sequential_2"
+
+ + + + +
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
+┃ Layer (type)                     Output Shape                  Param # ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
+│ tnp_dense_5 (TNPDense)          │ (None, 3)                 │         27 │
+├─────────────────────────────────┼───────────────────────────┼────────────┤
+│ tnp_dense_6 (TNPDense)          │ (None, 3)                 │         12 │
+├─────────────────────────────────┼───────────────────────────┼────────────┤
+│ tnp_dense_7 (TNPDense)          │ (None, 1)                 │          4 │
+└─────────────────────────────────┴───────────────────────────┴────────────┘
+
+ + + + +
 Total params: 43 (172.00 B)
+
+ + + + +
 Trainable params: 43 (172.00 B)
+
+ + + + +
 Non-trainable params: 0 (0.00 B)
+
+ + + +
+``` +Mean absolute percent error before training: 99.99930572509766 +Mean absolute percent error after training: 49.11731719970703 ```
@@ -379,7 +472,10 @@ To load the TensorBoard from a Jupyter notebook, you can run the following magic ```python models = [ - (TNPForwardFeedRegressionNetwork(blocks=[3, 3]), "TNPForwardFeedRegressionNetwork"), + ( + TNPForwardFeedRegressionNetwork(blocks=[3, 3]), + "TNPForwardFeedRegressionNetwork", + ), (create_layered_tnp_model(), "layered_tnp_model"), (create_mixed_model(), "mixed_model"), ] @@ -396,9 +492,15 @@ for model, model_name in models: verbose=0, callbacks=[keras.callbacks.TensorBoard(log_dir=f"logs/{model_name}")], ) -``` +``` +
+``` +/opt/conda/envs/keras-tensorflow/lib/python3.10/site-packages/keras/src/callbacks/tensorboard.py:676: UserWarning: Model failed to serialize as JSON. Ignoring... Invalid format specifier + warnings.warn(f"Model failed to serialize as JSON. Ignoring... {exc}") +``` +
To load the TensorBoard from a Jupyter notebook you can use the `%tensorboard` magic: ``` diff --git a/examples/keras_recipes/tensorflow_numpy_models.py b/examples/keras_recipes/tensorflow_numpy_models.py index 5790eda1e1..568945022a 100644 --- a/examples/keras_recipes/tensorflow_numpy_models.py +++ b/examples/keras_recipes/tensorflow_numpy_models.py @@ -24,36 +24,32 @@ """ ## Setup -TensorFlow NumPy requires TensorFlow 2.5 or later. """ +import os + +os.environ["KERAS_BACKEND"] = "tensorflow" + import tensorflow as tf import tensorflow.experimental.numpy as tnp import keras -import keras.layers as layers -import numpy as np - -""" -Optionally, you can call `tnp.experimental_enable_numpy_behavior()` to enable type promotion in TensorFlow. -This allows TNP to more closely follow the NumPy standard. -""" - -tnp.experimental_enable_numpy_behavior() +from keras import layers """ To test our models we will use the Boston housing prices regression dataset. """ -(x_train, y_train), (x_test, y_test) = tf.keras.datasets.boston_housing.load_data( +(x_train, y_train), (x_test, y_test) = keras.datasets.boston_housing.load_data( path="boston_housing.npz", test_split=0.2, seed=113 ) +input_dim = x_train.shape[1] def evaluate_model(model: keras.Model): - [loss, percent_error] = model.evaluate(x_test, y_test, verbose=0) + loss, percent_error = model.evaluate(x_test, y_test, verbose=0) print("Mean absolute percent error before training: ", percent_error) model.fit(x_train, y_train, epochs=200, verbose=0) - [loss, percent_error] = model.evaluate(x_test, y_test, verbose=0) + loss, percent_error = model.evaluate(x_test, y_test, verbose=0) print("Mean absolute percent error after training:", percent_error) @@ -89,16 +85,27 @@ def build(self, input_shape): for i, block in enumerate(self.blocks): self.block_weights.append( self.add_weight( - shape=(current_shape, block), trainable=True, name=f"block-{i}" + shape=(current_shape, block), + trainable=True, + name=f"block-{i}", + initializer="glorot_normal", ) ) self.biases.append( - self.add_weight(shape=(block,), trainable=True, name=f"bias-{i}") + self.add_weight( + shape=(block,), + trainable=True, + name=f"bias-{i}", + initializer="zeros", + ) ) current_shape = block self.linear_layer = self.add_weight( - shape=(current_shape, 1), name="linear_projector", trainable=True + shape=(current_shape, 1), + name="linear_projector", + trainable=True, + initializer="glorot_normal", ) def call(self, inputs): @@ -127,7 +134,7 @@ def call(self, inputs): evaluate_model(model) """ -Great! Our model seems to be effectively learning to solve the problem at hand. +Great! Our model seems to be effectively learning to solve the problem at hand. We can also write our own custom loss function using TNP. """ @@ -174,7 +181,7 @@ def build(self, input_shape): self.bias = self.add_weight( name="bias", shape=(self.units,), - initializer="random_normal", + initializer="zeros", trainable=True, ) @@ -201,12 +208,7 @@ def create_layered_tnp_model(): loss="mean_squared_error", metrics=[keras.metrics.MeanAbsolutePercentageError()], ) -model.build( - ( - None, - 13, - ) -) +model.build((None, input_dim)) model.summary() evaluate_model(model) @@ -234,12 +236,7 @@ def create_mixed_model(): loss="mean_squared_error", metrics=[keras.metrics.MeanAbsolutePercentageError()], ) -model.build( - ( - None, - 13, - ) -) +model.build((None, input_dim)) model.summary() evaluate_model(model) @@ -273,12 +270,7 @@ def create_mixed_model(): loss="mean_squared_error", metrics=[keras.metrics.MeanAbsolutePercentageError()], ) - model.build( - ( - None, - 13, - ) - ) + model.build((None, input_dim)) model.summary() evaluate_model(model) @@ -301,7 +293,10 @@ def create_mixed_model(): """ models = [ - (TNPForwardFeedRegressionNetwork(blocks=[3, 3]), "TNPForwardFeedRegressionNetwork"), + ( + TNPForwardFeedRegressionNetwork(blocks=[3, 3]), + "TNPForwardFeedRegressionNetwork", + ), (create_layered_tnp_model(), "layered_tnp_model"), (create_mixed_model(), "mixed_model"), ]