Skip to content

tf.keras.metrics.F1Score produces ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int32 #33

Open
@meekus-fischer

Description

@meekus-fischer

System information.

  • Have I written custom code (as opposed to using a stock example script provided in Keras): Yes
  • OS Platform and Distribution (e.g., Linux Ubuntu 16.04): RHELS 7.9
  • TensorFlow installed from (source or binary): Pip, binary
  • TensorFlow version (use command below): 2.13.0
  • Python version: 3.9
  • GPU model and memory: NVIDIA A100-SXM4-40GB
  • Exact command to reproduce:

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:

 y_true = tf.convert_to_tensor(y_true, dtype=self.dtype)

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:

y_true = tf.cast(y_true, self.dtype)

Is it possible that the new tf.keras.metric code should be using a tf.cast(...) vice a tf.convert_to_tensor(...)?

  • Do you want to contribute a PR? (yes/no): no

Standalone code to reproduce the issue.

Cannot share full code. Can share custom model init / train_step which causes the error.

class CustomModel(keras.Model):
    def __init__(self, model_type, val_samples, threshold, *args, **kwargs):
      super(CustomModel, self).__init__(*args,**kwargs)
      self.loss_tracker = tf.keras.metrics.Mean(name='Loss')
      self.val_samples = val_samples
      self.precision = tf.keras.metrics.Precision(name='Precision')
      self.recall = tf.keras.metrics.Recall(name='Recall')
      self.f1 = tf.keras.metrics.F1Score(name="F1", threshold=threshold)
      if model_type == 'binary':
          self.accuracy = tf.keras.metrics.BinaryAccuracy(name='accuracy', threshold=threshold)
      else:
          self.accuracy = tf.keras.metrics.CategoricalAccuracy(name='accuracy')
      

    def train_step(self, data):
        inputs, targets = data
        
        with tf.GradientTape() as tape:
            predictions = self(inputs, training=True)
            loss = self.compiled_loss(targets, predictions, regularization_losses=self.losses)

        gradients = tape.gradient(loss, self.trainable_variables)
        self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))

        self.loss_tracker.update_state(loss)
        self.accuracy.update_state(targets, predictions)
        self.precision.update_state(targets,predictions)
        self.recall.update_state(targets,predictions)
        self.f1.update_state(targets, predictions)
        return {"Accuracy":self.accuracy.result(),"Loss":self.loss_tracker.result(), 
                "Precision":self.precision.result(), "Recall":self.recall.result(),
                "F1":self.f1.result()}

    def test_step(self, data):
        inputs, targets = data

        predictions = []
        
        for _ in range(self.val_samples):
            predictions.append(self(inputs, training=False))
        
        predictions = tf.math.reduce_mean(tf.stack(predictions, axis=0), axis=0)

        loss = self.compiled_loss(targets, predictions, regularization_losses=self.losses)
        
        self.loss_tracker.update_state(loss)
        self.accuracy.update_state(targets, predictions)
        self.precision.update_state(targets,predictions)
        self.recall.update_state(targets,predictions)
        self.f1.update_state(targets, predictions)
        return {"Accuracy":self.accuracy.result(),"Loss":self.loss_tracker.result(),
                "Precision":self.precision.result(), "Recall":self.recall.result(),
                "F1":self.f1.result()}
    
    @property
    def metrics(self):
        return [self.accuracy,self.loss_tracker, self.precision, self.recall, self.f1]

Source code / logs.

Epoch 1/2000
Traceback (most recent call last):
  File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/data/kraken/john.fischer/projects/passive_sonar_models/scripts/../../passive_sonar_models/__main__.py", line 110, in <module>
    main()
  File "/data/kraken/john.fischer/projects/passive_sonar_models/scripts/../../passive_sonar_models/__main__.py", line 37, in main
    train_model.main(args)
  File "/data/kraken/john.fischer/projects/passive_sonar_models/scripts/../../passive_sonar_models/task/train_model.py", line 139, in main
    model.fit(train_data, epochs=args.num_epochs, validation_data=validate_data, #steps_per_epoch=steps_per_epoch, validation_steps=val_steps,
  File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-packages/keras/src/utils/traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/tmp/__autograph_generated_file3ywpkuyj.py", line 15, in tf__train_function
    retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
  File "/data/kraken/john.fischer/projects/passive_sonar_models/scripts/../../passive_sonar_models/models/mc_dropout_CNN.py", line 42, in train_step
    self.f1.update_state(targets,predictions)
ValueError: in user code:

    File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-packages/keras/src/engine/training.py", line 1338, in train_function  *
        return step_function(self, iterator)
    File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-packages/keras/src/engine/training.py", line 1322, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-packages/keras/src/engine/training.py", line 1303, in run_step  **
        outputs = model.train_step(data)
    File "/data/kraken/john.fischer/projects/passive_sonar_models/scripts/../../passive_sonar_models/models/mc_dropout_CNN.py", line 42, in train_step
        self.f1.update_state(targets,predictions)
    File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-packages/keras/src/utils/metrics_utils.py", line 77, in decorated
        update_op = update_state_fn(*args, **kwargs)
    File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-packages/keras/src/metrics/base_metric.py", line 140, in update_state_fn
        return ag_update_state(*args, **kwargs)
    File "/home/john.fischer/.conda/envs/psonar2/lib/python3.9/site-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 'cond/Identity_4:0' shape=(None,) dtype=int32>

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions