65

Training an image classifier using .fit_generator() or .fit() and passing a dictionary to class_weight= as an argument.

I never got errors in TF1.x but in 2.1 I get the following output when starting training:

WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']

What does it mean to coerce something from ... to ['...']?

The source for this warning on tensorflow's repo is here, comments placed are:

Attempt to coerce sample_weight_modes to the target structure. This implicitly depends on the fact that Model flattens outputs for its internal representation.

7
  • 7
    Funny to see such a recent question as the only search result for my own warnings as well.
    – jmkjaer
    Commented Dec 13, 2019 at 13:16
  • 1
    @jorijnsmit can you provide the code to replicate the issue/warning?
    – thushv89
    Commented Dec 16, 2019 at 0:25
  • 2
    Actually switching to TF2 with %tensorflow_version 2.x is enough to make this warning appear: colab.research.google.com/gist/jorijnsmit/…
    – gosuto
    Commented Dec 17, 2019 at 21:18
  • 1
    @jorijnsmit, No, I get the same warning but have actually installed TF2.1 as pip install tensorflow (within pyenv/virtualenv environment)
    – lurix66
    Commented Jan 17, 2020 at 8:37
  • 1
    Yes indeed @lurix66, the code that generates this error is introduced in 2.1.0rc0.
    – gosuto
    Commented Jan 17, 2020 at 8:53

4 Answers 4

23

This seems like a bogus message. I get the same warning message after upgrading to TensorFlow 2.1, but I do not use any class weights or sample weights at all. I do use a generator that returns a tuple like this:

return inputs, targets

And now I just changed it to the following to make the warning go away:

return inputs, targets, [None]

I don't know if this is relevant, but my model uses 3 inputs, so my inputs variable is actually a list of 3 numpy arrays. targets is just a single numpy array.

In any case, it's just a warning. The training works fine either way.

Edit for TensorFlow 2.2:

This bug seems to have been fixed in TensorFlow 2.2, which is great. However the fix above will fail in TF 2.2, because it will try to get the shape of the sample weights, which will obviously fail with AttributeError: 'NoneType' object has no attribute 'shape'. So undo the above fix when upgrading to 2.2.

1
  • OMG this AttributeError was killing me... thank you so much!
    – dexter2406
    Commented Feb 5, 2021 at 2:39
20

I believe this is a bug with tensorflow that will happen when you call model.compile() with default parameter sample_weight_mode=None and then call model.fit() with specified sample_weight or class_weight.

From the tensorflow repos:

  • fit() eventually calls _process_training_inputs()
  • _process_training_inputs() sets sample_weight_modes = [None] based on model.sample_weight_mode = None and then creates a DataAdapter with sample_weight_modes = [None]
  • the DataAdapter calls broadcast_sample_weight_modes() with sample_weight_modes = [None] during initialization
  • broadcast_sample_weight_modes() seems to expect sample_weight_modes = None but receives [None]
  • it asserts that [None] is a different structure from sample_weight / class_weight, overwrites it back to None by fitting to the structure of sample_weight / class_weight and outputs a warning

Warning aside this has no effect on fit() as sample_weight_modes in the DataAdapter is set back to None.

Note that tensorflow documentation states that sample_weight must be a numpy-array. If you call fit() with sample_weight.tolist() instead, you will not get a warning but sample_weight is silently overwritten to None when _process_numpy_inputs() is called in preprocessing and receives an input of length greater than one.

1
  • 2
    A very thorough explanation, thanks. Only thing I don't understand is that the warning describes ... being coerced to [...], whereas in your case [None] is coerced to None...
    – gosuto
    Commented Feb 19, 2020 at 6:16
7
+25

I have taken your Gist and installed Tensorflow 2.0, instead of TFA and it worked without any such Warning.

Here is the Gist of the complete code. Code for installing the Tensorflow is shown below:

!pip install tensorflow==2.0

Screenshot of the successful execution is shown below:

enter image description here

Update: This bug is fixed in Tensorflow Version 2.2.

8
  • 5
    Thank you for your response. You are right, the warning message is not introduced until version 2.1.0rc0. However, I'm afraid my question remains: "What does it mean to coerce something from ... to ['...']?"
    – gosuto
    Commented Dec 19, 2019 at 10:41
  • 3
    I noticed that some probably unintended stuff happens when sample_weight_mode=None and target_structure is of type dict, sample_weight_modes is then [None] and the exception in broadcast_sample_weight_modes is caught due to the dict. Can this be considered as a bug? Commented Dec 19, 2019 at 15:18
  • 3
    Nope. Question keeps gathering views and upvotes but no answers.
    – gosuto
    Commented Jan 30, 2020 at 22:29
  • 1
    @gkennos: If you feel it is a bug, Can you file a Bug in Github Tensorflow Repository.
    – user11530462
    Commented Feb 17, 2020 at 5:00
  • 1
    It's definitely a bug, but it's now fixed in TensorFlow 2.2
    – jlh
    Commented Mar 23, 2020 at 11:11
4

instead of providing a dictionary

weights = {'0': 42.0, '1': 1.0}

i tried a list

weights = [42.0, 1.0]

and the warning disappeared.

2
  • Thanks man! I was trying (unsuccessful) with dictionaries. By using the list the error is fixed! Commented Apr 15, 2020 at 14:44
  • Whilst this does get rid of the error, for me this breaks the weighting for each class produces worse results. I'd check for consistency before switching to a list.
    – CanofDrink
    Commented Apr 23, 2020 at 14:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.