Repository: tensorflow/addons

Issue:
TQDMProgressBar not working in TF-2.2.0rc1
**System information**
- OS Platform and Distribution: Linux Ubuntu 18.04
- TensorFlow version and how it was installed (source or binary): TF-2.2.0rc1 (wheel compiled from source)
- TensorFlow-Addons version and how it was installed (source or binary): 0.8.3 installed via pip
- Python version: 3.7.6
- Is GPU used? (yes/no): Yes

**Describe the bug**

Executing `model.fit()` with the `TQDMProgressBar()` callback results in `KeyError: 'metrics'` because of a change in TF-2.2 that moves initialization of `model.metrics` (and `model.metrics_names`) from compile stage to train stage.

**Code to reproduce the issue**

```python
import numpy as np
import tensorflow as tf
import tensorflow_addons as tfa

x = np.random.random((5,1,5))
y = np.random.random((5,1,5))

inputs = tf.keras.layers.Input(shape=(3,))
outputs = tf.keras.layers.Dense(2, name="out_1")(inputs)
model = tf.keras.models.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer="Adam", loss="mse", metrics=["acc"])

pg = tfa.callbacks.TQDMProgressBar()
model_callbacks = [pg, ]
VERBOSE=0
history = model.fit(
    x,
    y,
    epochs=100,
    verbose=VERBOSE,
    callbacks=model_callbacks
)
````

**Other info / logs**

```python
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-23-fdbb03f574a1> in <module>
     48 #   class_weight=class_weights,
     49     verbose=VERBOSE,
---> 50     callbacks=model_callbacks,
     51 )

~/.pyenv/versions/3.7.6/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py in _method_wrapper(self, *args, **kwargs)
     63   def _method_wrapper(self, *args, **kwargs):
     64     if not self._in_multi_worker_mode():  # pylint: disable=protected-access
---> 65       return method(self, *args, **kwargs)
     66 
     67     # Running inside `run_distribute_coordinator` already.

~/.pyenv/versions/3.7.6/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
    763       self.stop_training = False
    764       train_function = self.make_train_function()
--> 765       callbacks.on_train_begin()
    766       # Handle fault-tolerance for multi-worker.
    767       # TODO(omalleyt): Fix the ordering issues that mean this has to

~/.pyenv/versions/3.7.6/lib/python3.7/site-packages/tensorflow/python/keras/callbacks.py in on_train_begin(self, logs)
    445     logs = self._process_logs(logs)
    446     for callback in self.callbacks:
--> 447       callback.on_train_begin(logs)
    448 
    449   def on_train_end(self, logs=None):

~/.pyenv/versions/3.7.6/lib/python3.7/site-packages/tensorflow_addons/callbacks/tqdm_progress_bar.py in on_train_begin(self, logs)
    100     def on_train_begin(self, logs=None):
    101         self.num_epochs = self.params["epochs"]
--> 102         self.metrics = self.params["metrics"]
    103 
    104         if self.show_overall_progress:

KeyError: 'metrics'
```



Discussion:
I believe that it's going to be fixed with #1365 . We lack tests for those, which explains why they break unexpectedly.
@gabrieldemarmiesse I can confirm that the patch you mentioned fixed my issue 👍 It does introduce a new issue, however. Validation metrics are not printed at the end of an epoch anymore.
Yeah we definitly lack some proper testing for the callbacks in Addons.

Resolving patch:
diff --git a/tensorflow_addons/callbacks/tqdm_progress_bar.py b/tensorflow_addons/callbacks/tqdm_progress_bar.py
--- a/tensorflow_addons/callbacks/tqdm_progress_bar.py
+++ b/tensorflow_addons/callbacks/tqdm_progress_bar.py
@@ -95,11 +95,10 @@ def __init__(
         self.epoch_progress_tqdm = None
         self.num_epochs = None
         self.logs = None
-        self.metrics = None
+        super().__init__()
 
     def on_train_begin(self, logs=None):
         self.num_epochs = self.params["epochs"]
-        self.metrics = self.params["metrics"]
 
         if self.show_overall_progress:
             self.overall_progress_tqdm = self.tqdm(
@@ -112,12 +111,8 @@ def on_train_begin(self, logs=None):
             )
 
         # set counting mode
-        if "samples" in self.params:
-            self.mode = "samples"
-            self.total_steps = self.params["samples"]
-        else:
-            self.mode = "steps"
-            self.total_steps = self.params["steps"]
+        self.mode = "steps"
+        self.total_steps = self.params["steps"]
 
     def on_train_end(self, logs={}):
         if self.show_overall_progress:
@@ -208,11 +203,11 @@ def format_metrics(self, logs={}, factor=1):
         """
 
         metric_value_pairs = []
-        for metric in self.metrics:
-            if metric in logs:
-                value = logs[metric] / factor
-                pair = self.metrics_format.format(name=metric, value=value)
-                metric_value_pairs.append(pair)
+        for key, value in logs.items():
+            if key in ["batch", "size"]:
+                continue
+            pair = self.metrics_format.format(name=key, value=value / factor)
+            metric_value_pairs.append(pair)
         metrics_string = self.metrics_separator.join(metric_value_pairs)
         return metrics_string
 


Test patch:
diff --git a/tensorflow_addons/callbacks/tests/tqdm_progress_bar_test.py b/tensorflow_addons/callbacks/tests/tqdm_progress_bar_test.py
--- a/tensorflow_addons/callbacks/tests/tqdm_progress_bar_test.py
+++ b/tensorflow_addons/callbacks/tests/tqdm_progress_bar_test.py
@@ -1,4 +1,3 @@
-from distutils.version import LooseVersion
 import re
 
 import numpy as np
@@ -8,15 +7,9 @@
 import tensorflow_addons as tfa
 
 
-pytestmark = pytest.mark.xfail(
-    LooseVersion(tf.__version__) >= LooseVersion("2.2.0"),
-    reason="TODO: Fixeme See #1495",
-)
-
-
 def get_data_and_model():
-    x = np.random.random((5, 1))
-    y = np.random.randint(0, 2, (5, 1), dtype=np.int)
+    x = np.random.random((12, 1))
+    y = np.random.randint(0, 2, (12, 1), dtype=np.int)
 
     inputs = tf.keras.layers.Input(shape=(1,))
     outputs = tf.keras.layers.Dense(1)(inputs)
@@ -74,9 +67,9 @@ def test_tqdm_progress_bar_epoch_bar_format_missing_parameter(capsys):
         epoch_bar_format=epoch_bar_format, show_overall_progress=False
     )
     capsys.readouterr()  # flush the buffer
-    model.fit(x, y, epochs=1, verbose=0, callbacks=[pb])
+    model.fit(x, y, batch_size=4, epochs=2, verbose=0, callbacks=[pb])
     fit_stderr = capsys.readouterr().err
-    assert "/5" not in fit_stderr
+    assert "/3" not in fit_stderr
 
 
 def test_tqdm_progress_bar_metrics_format(capsys):
@@ -104,12 +97,19 @@ def test_tqdm_progress_bar_show(capsys, show_epoch_progress, show_overall_progre
         show_overall_progress=show_overall_progress,
     )
     capsys.readouterr()  # flush the buffer
-    model.fit(x, y, epochs=1, verbose=0, callbacks=[pb])
+    model.fit(x, y, batch_size=4, epochs=2, verbose=0, callbacks=[pb])
     fit_stderr = capsys.readouterr().err
 
-    assert ("/5" in fit_stderr) is show_epoch_progress
+    assert ("/3" in fit_stderr) is show_epoch_progress
     assert ("epochs/s" in fit_stderr) is show_overall_progress
 
+    if show_epoch_progress and not show_overall_progress:
+        # in 2.1.0, they are present in the logs
+        # in 2.2.0+, they're not
+        # in any case, they shouldn't appear.
+        assert "size" not in fit_stderr
+        assert "batch" not in fit_stderr
+
 
 def test_tqdm_progress_bar_validation(capsys):
     x, y, model = get_data_and_model()