diff --git a/12_custom_models_and_training_with_tensorflow.ipynb b/12_custom_models_and_training_with_tensorflow.ipynb index f87cc36..879879d 100644 --- a/12_custom_models_and_training_with_tensorflow.ipynb +++ b/12_custom_models_and_training_with_tensorflow.ipynb @@ -1588,13 +1588,20 @@ "model.fit(X_train_scaled.astype(np.float32), y_train.astype(np.float32), epochs=2)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Warning**: In TF 2.2, tf.keras adds an extra first metric in `model.metrics` at position 0 (see [TF issue #38150](https://github.com/tensorflow/tensorflow/issues/38150)). This forces us to use `model.metrics[-1]` rather than `model.metrics[0]` to access the `HuberMetric`." + ] + }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [], "source": [ - "model.metrics[0].threshold" + "model.metrics[-1].threshold" ] }, { @@ -1713,6 +1720,13 @@ "model.fit(X_train_scaled.astype(np.float32), y_train.astype(np.float32), epochs=2)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Warning**: In TF 2.2, tf.keras adds an extra first metric in `model.metrics` at position 0 (see [TF issue #38150](https://github.com/tensorflow/tensorflow/issues/38150)). This forces us to use `model.metrics[-1]` rather than `model.metrics[0]` to access the `HuberMetric`." + ] + }, { "cell_type": "code", "execution_count": 134, @@ -1721,7 +1735,7 @@ }, "outputs": [], "source": [ - "model.metrics[0].threshold" + "model.metrics[-1].threshold" ] }, { @@ -1976,8 +1990,6 @@ "class ResidualBlock(keras.layers.Layer):\n", " def __init__(self, n_layers, n_neurons, **kwargs):\n", " super().__init__(**kwargs)\n", - " self.n_layers = n_layers # not shown in the book\n", - " self.n_neurons = n_neurons # not shown\n", " self.hidden = [keras.layers.Dense(n_neurons, activation=\"elu\",\n", " kernel_initializer=\"he_normal\")\n", " for _ in range(n_layers)]\n", @@ -1986,12 +1998,7 @@ " Z = inputs\n", " for layer in self.hidden:\n", " Z = layer(Z)\n", - " return inputs + Z\n", - " \n", - " def get_config(self): # not shown\n", - " base_config = super().get_config() # not shown\n", - " return {**base_config, # not shown\n", - " \"n_layers\": self.n_layers, \"n_neurons\": self.n_neurons} # not shown" + " return inputs + Z" ] }, { @@ -2003,7 +2010,6 @@ "class ResidualRegressor(keras.models.Model):\n", " def __init__(self, output_dim, **kwargs):\n", " super().__init__(**kwargs)\n", - " self.output_dim = output_dim # not shown in the book\n", " self.hidden1 = keras.layers.Dense(30, activation=\"elu\",\n", " kernel_initializer=\"he_normal\")\n", " self.block1 = ResidualBlock(2, 30)\n", @@ -2015,12 +2021,7 @@ " for _ in range(1 + 3):\n", " Z = self.block1(Z)\n", " Z = self.block2(Z)\n", - " return self.out(Z)\n", - "\n", - " def get_config(self): # not shown\n", - " base_config = super().get_config() # not shown\n", - " return {**base_config, # not shown\n", - " \"output_dim\": self.output_dim} # not shown" + " return self.out(Z)" ] }, {