|
2579 | 2579 | "model.fit(X_train_scaled.astype(np.float32), y_train.astype(np.float32), epochs=2)"
|
2580 | 2580 | ]
|
2581 | 2581 | },
|
| 2582 | + { |
| 2583 | + "cell_type": "markdown", |
| 2584 | + "metadata": {}, |
| 2585 | + "source": [ |
| 2586 | + "**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`." |
| 2587 | + ] |
| 2588 | + }, |
2582 | 2589 | {
|
2583 | 2590 | "cell_type": "code",
|
2584 | 2591 | "execution_count": 124,
|
|
2596 | 2603 | }
|
2597 | 2604 | ],
|
2598 | 2605 | "source": [
|
2599 |
| - "model.metrics[0].threshold" |
| 2606 | + "model.metrics[-1].threshold" |
2600 | 2607 | ]
|
2601 | 2608 | },
|
2602 | 2609 | {
|
|
2764 | 2771 | "model.fit(X_train_scaled.astype(np.float32), y_train.astype(np.float32), epochs=2)"
|
2765 | 2772 | ]
|
2766 | 2773 | },
|
| 2774 | + { |
| 2775 | + "cell_type": "markdown", |
| 2776 | + "metadata": {}, |
| 2777 | + "source": [ |
| 2778 | + "**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`." |
| 2779 | + ] |
| 2780 | + }, |
2767 | 2781 | {
|
2768 | 2782 | "cell_type": "code",
|
2769 | 2783 | "execution_count": 134,
|
|
2783 | 2797 | }
|
2784 | 2798 | ],
|
2785 | 2799 | "source": [
|
2786 |
| - "model.metrics[0].threshold" |
| 2800 | + "model.metrics[-1].threshold" |
2787 | 2801 | ]
|
2788 | 2802 | },
|
2789 | 2803 | {
|
|
3124 | 3138 | "class ResidualBlock(keras.layers.Layer):\n",
|
3125 | 3139 | " def __init__(self, n_layers, n_neurons, **kwargs):\n",
|
3126 | 3140 | " super().__init__(**kwargs)\n",
|
3127 |
| - " self.n_layers = n_layers # not shown in the book\n", |
3128 |
| - " self.n_neurons = n_neurons # not shown\n", |
3129 | 3141 | " self.hidden = [keras.layers.Dense(n_neurons, activation=\"elu\",\n",
|
3130 | 3142 | " kernel_initializer=\"he_normal\")\n",
|
3131 | 3143 | " for _ in range(n_layers)]\n",
|
|
3134 | 3146 | " Z = inputs\n",
|
3135 | 3147 | " for layer in self.hidden:\n",
|
3136 | 3148 | " Z = layer(Z)\n",
|
3137 |
| - " return inputs + Z\n", |
3138 |
| - " \n", |
3139 |
| - " def get_config(self): # not shown\n", |
3140 |
| - " base_config = super().get_config() # not shown\n", |
3141 |
| - " return {**base_config, # not shown\n", |
3142 |
| - " \"n_layers\": self.n_layers, \"n_neurons\": self.n_neurons} # not shown" |
| 3149 | + " return inputs + Z" |
3143 | 3150 | ]
|
3144 | 3151 | },
|
3145 | 3152 | {
|
|
3151 | 3158 | "class ResidualRegressor(keras.models.Model):\n",
|
3152 | 3159 | " def __init__(self, output_dim, **kwargs):\n",
|
3153 | 3160 | " super().__init__(**kwargs)\n",
|
3154 |
| - " self.output_dim = output_dim # not shown in the book\n", |
3155 | 3161 | " self.hidden1 = keras.layers.Dense(30, activation=\"elu\",\n",
|
3156 | 3162 | " kernel_initializer=\"he_normal\")\n",
|
3157 | 3163 | " self.block1 = ResidualBlock(2, 30)\n",
|
|
3163 | 3169 | " for _ in range(1 + 3):\n",
|
3164 | 3170 | " Z = self.block1(Z)\n",
|
3165 | 3171 | " Z = self.block2(Z)\n",
|
3166 |
| - " return self.out(Z)\n", |
3167 |
| - "\n", |
3168 |
| - " def get_config(self): # not shown\n", |
3169 |
| - " base_config = super().get_config() # not shown\n", |
3170 |
| - " return {**base_config, # not shown\n", |
3171 |
| - " \"output_dim\": self.output_dim} # not shown" |
| 3172 | + " return self.out(Z)" |
3172 | 3173 | ]
|
3173 | 3174 | },
|
3174 | 3175 | {
|
|
0 commit comments