Repository: keras-team/keras

Issue:
Better error message for Unexpected result of `train_function` (Empty logs). Please use `Model.compile(..., run_eagerly=True)`, or `tf.config.run_functions_eagerly(True)` for more information of where went wrong, or file a issue/bug to `tf.keras`
Hi!

This error message pops up when empty arrays are passed to `Model.fit` or `Model.predict`. The solution suggested in the error message does not work and in some sense is not logical. Either the error message should be updated or the mentioned functions should have additional assertions to check for empty input arrays.


Discussion:
Could you please provide some simple reproducible code and the error message which you are getting currently in order to expedite the troubleshooting process. Thanks!
To be precise, this issue popped up in `tensorflow==2.7.0` and `keras==2.7.0` and their recent versions.

Currently, I have `python==3.8.6`, `tensorflow==2.8.0` and `keras==2.8.0`.

The minimal code to reproduce the issue:

```
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
import numpy as np

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
Y = np.array([0, 1, 1, 0])

model = Sequential()
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(optimizer='Adam', loss='binary_crossentropy', metrics=['acc'])

idx = []

model.fit(X[idx], Y[idx])
```
This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Thank you.

i have the same issue and i didnt know what is the solution 
Fix this error message to something more logical. Asap
Can you check also this case:
https://discuss.tensorflow.org/t/text-based-tensorflow-unexpected-result-of-train-function-empty-logs/11075
Hi all,

Is there any solution to this issue?

Thank you in advance.
> Hi all,
> 
> Is there any solution to this issue?
> 
> Thank you in advance.

Did you find a solution to this?
Any update on a different (more informative) error message?

I've been working with TF for a while now and just have to say that this generic error message requires a lot more time to debug code than it seems like it should. Having a more informative message would really help code development.
@pwernette , There is a PR created for this issue here https://github.com/keras-team/keras/pull/16216, but there is no update from the author.
I also came across this error, but when using a `tf.data.Dataset` with `step` calculations and large batch sizes on small datasets.  
I would also expect to get a better error message if I were to give `steps_per_epoch=0` to `fit`.

Example:
```py
import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
import numpy as np

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
Y = np.array([0, 1, 1, 0])

ds = tf.data.Dataset.from_tensor_slices((X, Y))
ds = ds.repeat()
steps = 0  # from calculations such as len//batchsize

model = Sequential()
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(optimizer='Adam', loss='binary_crossentropy', metrics=['acc'])

model.fit(ds, steps_per_epoch=steps)
```

also results in the error:

```
ValueError: Unexpected result of `train_function` (Empty logs). Ple
ase use `Model.compile(..., run_eagerly=True)`, or `tf.config.run_f
unctions_eagerly(True)` for more information of where went wrong, o
r file a issue/bug to `tf.keras`.
```

Also if compiling the model with `run_eagerly=True`, as the error message suggest, you get the same error.

Resolving patch:
diff --git a/keras/engine/data_adapter.py b/keras/engine/data_adapter.py
--- a/keras/engine/data_adapter.py
+++ b/keras/engine/data_adapter.py
@@ -1271,6 +1271,13 @@ def __init__(
         self._insufficient_data = False
         self._model = model
 
+        if steps_per_epoch == 0:
+            raise ValueError(
+                "Unexpected value for `steps_per_epoch`. Received value is 0. "
+                "Please check the docstring for `model.fit()` for supported "
+                "values."
+            )
+
         self._steps_per_epoch = steps_per_epoch
 
         # `steps_per_execution_value` is the cached initial value.
@@ -1308,6 +1315,9 @@ def __init__(
             strategy, x, steps_per_epoch, class_weight, distribute
         )
 
+        if self._inferred_steps == 0:
+            raise ValueError("Expected input data to be non-empty.")
+
     def _configure_dataset_and_inferred_steps(
         self, strategy, x, steps_per_epoch, class_weight, distribute
     ):


Test patch:
diff --git a/keras/engine/data_adapter_test.py b/keras/engine/data_adapter_test.py
--- a/keras/engine/data_adapter_test.py
+++ b/keras/engine/data_adapter_test.py
@@ -1442,6 +1442,37 @@ def test_single_x_input_no_tuple_wrapping(self, use_numpy):
                 # Check that single x input is not wrapped in a tuple.
                 self.assertIsInstance(next(iterator), tf.Tensor)
 
+    def test_error_if_zero_steps_per_epoch(self):
+        data = tf.data.Dataset.from_tensor_slices([0, 1, 2, 3]).batch(1)
+
+        with self.assertRaisesRegex(
+            ValueError,
+            "Unexpected value for `steps_per_epoch`. Received value is 0.",
+        ):
+            data_adapter.DataHandler(
+                data, initial_epoch=0, epochs=2, steps_per_epoch=0
+            )
+
+    def test_error_if_empty_array_input_data(self):
+        x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
+        y = np.array([0, 1, 1, 0])
+        idx = []
+
+        with self.assertRaisesWithLiteralMatch(
+            ValueError,
+            "Expected input data to be non-empty.",
+        ):
+            data_adapter.DataHandler(x[idx], y[idx])
+
+    def test_error_if_empty_dataset_input_data(self):
+        data = tf.data.Dataset.from_tensor_slices([]).batch(1)
+
+        with self.assertRaisesWithLiteralMatch(
+            ValueError,
+            "Expected input data to be non-empty.",
+        ):
+            data_adapter.DataHandler(data)
+
 
 class TestValidationSplit(test_combinations.TestCase):
     @parameterized.named_parameters(("numpy_arrays", True), ("tensors", False))
diff --git a/keras/engine/training_test.py b/keras/engine/training_test.py
--- a/keras/engine/training_test.py
+++ b/keras/engine/training_test.py
@@ -94,7 +94,7 @@ def test_fit_on_empty(self):
         model = sequential.Sequential([layers_module.Dense(1)])
         model.compile("sgd", "mse", run_eagerly=test_utils.should_run_eagerly())
         with self.assertRaisesRegex(
-            ValueError, "Unexpected result of `train_function`.*"
+            ValueError, "Expected input data to be non-empty."
         ):
             model.fit(x=np.array([]), y=np.array([]))
 
@@ -2448,7 +2448,7 @@ def test_predict_error_with_empty_x(self):
         model.compile(loss="mse")
 
         with self.assertRaisesRegex(
-            ValueError, "Unexpected result of `predict_function`.*"
+            ValueError, "Expected input data to be non-empty."
         ):
             model.predict(np.array([]))