Open meekus-fischer opened 1 year ago
As an update, adjusting the update_state call to the following is a workaround:
self.f1.update_state(tf.cast(targets,dtype=predictions.dtype) ,predictions)
However, there is additionally an issue when there is only a single output class as in a Binary Classification problem using Binary CrossEntropy:
ValueError: FBetaScore expects 2D inputs with shape (batch_size, output_dim). Received input shapes: y_pred.shape=(None, 1) and y_true.shape=(None,).
@meekus-fischer, I tried to execute the mentioned code, in the given code snippet you have defined the class and its methods but are not calling them anywhere. Could you please provide the complete code or the colab gist. Kindly find the gist of it here.
ValueError: FBetaScore expects 2D inputs with shape (batch_size, output_dim). Received input shapes: y_pred.shape=(None, 1) and y_true.shape=(None,).
And you are facing the above error, the input shapes which were provided are not compatible for the shape(batch_size, output_dim). Could you please try to provide correct shapes and try to execute. Thank you!
@meekus-fischer, I tried to execute the mentioned code, in the given code snippet you have defined the class and its methods but are not calling them anywhere. Could you please provide the complete code or the colab gist. Kindly find the gist of it here.
ValueError: FBetaScore expects 2D inputs with shape (batch_size, output_dim). Received input shapes: y_pred.shape=(None, 1) and y_true.shape=(None,).
And you are facing the above error, the input shapes which were provided are not compatible for the shape(batch_size, output_dim). Could you please try to provide correct shapes and try to execute. Thank you!
@tilakrayal I have edited the gist with a toy example as I am not able to share my entire project / data. The problem with the input shape compatibility arises during a typical binary classification case. The y_true tensor has shape (batch_size,) due to the fact that the tensor is just a tensor of 0s and 1s. The gist now encapsulates this issue. A workaround, for both issues described in my problem is contained in the gist and below:
#Workaround
self.f1.update_state(tf.expand_dims(tf.cast(targets,dtype=predictions.dtype),-1), predictions)
This type of workaround shouldn't be required for a binary classification problem. I should be able to use a model like this regardless of the type of classification problem. If I used this for a Multiclass or multlabel problem, it would now break without additional logic to not expand_dims in those cases.
As an update to the above. This solution does not allow TensorBoard to be utilized.
model.fit(train_ds, epochs=50, validation_data=val_ds, validation_freq=1, callbacks=tf.keras.callbacks.TensorBoard())
results in the following error
Epoch 1/50
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
[<ipython-input-16-039cc4c8c456>](https://3jm7pq18b6d-496ff2e9c6d22116-0-colab.googleusercontent.com/outputframe.html?vrz=colab-20230823-060135-RC00_559378898#) in <cell line: 1>()
----> 1 model.fit(train_ds, epochs=50, validation_data=val_ds, validation_freq=1, callbacks=tf.keras.callbacks.TensorBoard())
1 frames
[/usr/local/lib/python3.10/dist-packages/tensorboard/plugins/scalar/summary_v2.py](https://3jm7pq18b6d-496ff2e9c6d22116-0-colab.googleusercontent.com/outputframe.html?vrz=colab-20230823-060135-RC00_559378898#) in scalar(name, data, step, description)
86 )
87 with summary_scope(name, "scalar_summary", values=[data, step]) as (tag, _):
---> 88 tf.debugging.assert_scalar(data)
89 return tf.summary.write(
90 tag=tag,
ValueError: Expected scalar shape, saw shape: (1,).
I am dealing with the same problem with tf.keras.metrics.F1Score
for a binary classification problem.
@tilakrayal I reproduced a very similar error on TF 2.14.0 (see below). Please have a look at the full notebook gist.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-13-3be8d2fa8bed> in <cell line: 1>()
----> 1 result = classifier_model.evaluate(test_ds, return_dict=True)
/usr/local/lib/python3.10/dist-packages/keras/src/utils/traceback_utils.py in error_handler(*args, **kwargs)
68 # To get the full stack trace, call:
69 # `tf.debugging.disable_traceback_filtering()`
---> 70 raise e.with_traceback(filtered_tb) from None
71 finally:
72 del filtered_tb
/usr/local/lib/python3.10/dist-packages/keras/src/engine/training.py in tf__test_function(iterator)
13 try:
14 do_return = True
---> 15 retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
16 except:
17 do_return = False
ValueError: in user code:
File "/usr/local/lib/python3.10/dist-packages/keras/src/engine/training.py", line 2042, in test_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.10/dist-packages/keras/src/engine/training.py", line 2025, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.10/dist-packages/keras/src/engine/training.py", line 2013, in run_step **
outputs = model.test_step(data)
File "/usr/local/lib/python3.10/dist-packages/keras/src/engine/training.py", line 1896, in test_step
return self.compute_metrics(x, y, y_pred, sample_weight)
File "/usr/local/lib/python3.10/dist-packages/keras/src/engine/training.py", line 1225, in compute_metrics
self.compiled_metrics.update_state(y, y_pred, sample_weight)
File "/usr/local/lib/python3.10/dist-packages/keras/src/engine/compile_utils.py", line 620, in update_state
metric_obj.update_state(y_t, y_p, sample_weight=mask)
File "/usr/local/lib/python3.10/dist-packages/keras/src/utils/metrics_utils.py", line 77, in decorated
result = update_state_fn(*args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/keras/src/metrics/base_metric.py", line 140, in update_state_fn
return ag_update_state(*args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/keras/src/metrics/f_score_metrics.py", line 176, in update_state **
y_true = tf.convert_to_tensor(y_true, dtype=self.dtype)
ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int32: <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=int32>
I have the same problem with the training phase in the case of binary classification.
This is reproducible with a small change to the tutorial example at https://www.tensorflow.org/tutorials/keras/text_classification with TF 2.15.0
Simply adding an F1Score as a metric to compile
raises the ValueError:
model.compile(optimizer=optimizer,
loss=tf.losses.BinaryCrossentropy(from_logits=True),
metrics=[tf.metrics.BinaryAccuracy(threshold=0.0, name='accuracy'),
tf.keras.metrics.F1Score()
])
Crashes with ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int64
during fit()
. Re-compiling with it as a metric after fit
causes the same raise during evaluate()
.
A workaround to add F1Score to this particular tutorial is to change
train_data, test_data = tfds.load(name="imdb_reviews", split=["train", "test"],
batch_size=-1, as_supervised=True)
train_examples, train_labels = tfds.as_numpy(train_data)
test_examples, test_labels = tfds.as_numpy(test_data)
to
train_data, test_data = tfds.load(name="imdb_reviews", split=["train", "test"],
batch_size=-1, as_supervised=True)
train_examples, train_labels = tfds.as_numpy(train_data)
test_examples, test_labels = tfds.as_numpy(test_data)
train_labels = train_labels.astype(np.float64)
test_labels = test_labels.astype(np.float64)
System information.
Describe the problem.
During training, model is monitoring tf.keras.metrics.F1Score; however, when F1Score.update_state is called, a Value Error is thrown.
ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int32: <tf.Tensor 'cond/Identity_4:0' shape=(None,) dtype=int32>
which is the result of the following line of code in the FBetaScore Class:
Describe the current behavior.
F1Score metric unable to update_state. Error thrown. Unable to train model.
Describe the expected behavior.
I would expect F1Score to update_state based on a y_true tensor with an int32 datatype and a y_pred tensor of float32 datatype without throwing an error.
In the tfa.metrics.FBetaScore code, the corresponding line is:
Is it possible that the new tf.keras.metric code should be using a tf.cast(...) vice a tf.convert_to_tensor(...)?
Standalone code to reproduce the issue.
Cannot share full code. Can share custom model init / train_step which causes the error.
Source code / logs.