Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-outputs & class_weight #4735

Closed
bityangke opened this issue Dec 15, 2016 · 20 comments
Closed

Multi-outputs & class_weight #4735

bityangke opened this issue Dec 15, 2016 · 20 comments

Comments

@bityangke
Copy link

Assume our model have two outputs :
output 1 'class' for classification
output 2 'location' for regression

Now we have the imbalance dataset(eg. binary classification, class '0': 98 percent, class '1': 2 percent), so we need set the class_weight params in model.fit() function, but for output 2 'location' regression task, we do not need class_weight.
How can we set the class_weight in this situation?
Does "class_weight = {0: ratio 1 , 1: ratio 2} is applied the classification task and ignore the regression task by default?

@bityangke
Copy link
Author

And a second situation is that:
output 1 'class_1' for classification
output 2 'class_2' for classification

Both outputs do the classification, but we want to give each output different class_weight params.
How can we do this? (I am not sure whether this situation makes sense or not. )
Maybe Like this?:
class_weight = { 'class_1': {0: ratio 1 , 1: ratio 2} , 'class_2': {0: ratio 3 , 1: ratio 4} }

@fchollet
Copy link
Member

fchollet commented Dec 15, 2016 via email

@bityangke
Copy link
Author

Thanks for your quick response.
If we use the one-hot code.
For the two classes classification, should the class_weight like this? :
class_weight = {10: weight 1, 11: weight 2}
10 and 11 repesent the one hot codes of the two classes

@fchollet
Copy link
Member

fchollet commented Dec 15, 2016 via email

@olix20
Copy link

olix20 commented May 21, 2017

@fchollet what is the right way to set weights given multi-class, one-hot encoded outputs? e.g. y = [0, 1, 1, 1, 0]

@shamoons
Copy link

shamoons commented Mar 6, 2019

Yup. Same issue

@pratiklodha95
Copy link

@olix20 did you find a solution ?

@QuickLearner171998
Copy link

For a multi output model how can I change class_weights during training ie after each step according to a batch.

@adriangb
Copy link
Contributor

In 2020 / TF 2.3.0 this does not work: class_weights = {'output1': {0: 1, 1: 10}, 'output2': {0: 5, 1: 1, 2: 10}}

@tingjhenjiang
Copy link

tingjhenjiang commented Dec 11, 2020

this discussion should be reopened as of Dec 11, 2020 as this issue is still not resolved.
Here is what it comes to me:
ValueError: Expected ``class_weight`` to be a dict with keys from 0 to one less than the number of classes, found {'THEORETICAL': {0: 0.9251916468411314, 1: 1.0879701585327946}, 'ENGINEERING': {0: 0.9703354588300527, 1: 1.031535514294135}, 'EMPIRICAL': {0: 0.720016457519029, 1: 1.6362786348761102}, 'OTHERS': {0: 0.5192107995846313, 1: 13.513513513513514}}

and this discussion is related to discussion 1 and discussion 2.

@kevinashaw
Copy link

Agreed. This is really needed.

@kevinashaw
Copy link

@fchollet Can we get this re-opened? We are dealing an inherently asymmetric target set with the need for multiple outputs. class_weight is the right way for us to address this. Is there a work around? (Topic is also addressed in tensorflow/tensorflow#41448 (comment))

@MareSeestern
Copy link

Any progress?

@adriangb
Copy link
Contributor

I think class weights can always be implemented via sample weights (see sklearn.utils.class_weight.compute_sample_weight). It seems like Keras does support sample weights for each output, so maybe using compute_sample_weight for each output can work? If you already have sample weights, I think you should be able to do weight = weight * new_weight (but someone with more of a statistics background should confirm this)

@kevinashaw
Copy link

@adriangb Ostensibly, Keras does support class weights with multiple outputs, but the implementation is broken, as noted by the error message shown in this thread. Its unclear to me if sklearn can be used in a tensorflow/keras training pipeline. I find adding outside frameworks can be troublesome when exporting models to TF Serving. But I may not have enough knowledge here.

@adriangb
Copy link
Contributor

I'm not sure either. I'm just offering it as an alternative, but obviously it would still be nice if it got fixed.

@niki-j
Copy link

niki-j commented Apr 6, 2021

Did anyone have any luck with this issue here? The nested dictionary approach as suggested by @fchollet for class_weight earlier seems to be supported for TF <= 2.1.0 only.
A lot of people with such multi-label/multi-output problems seem to have raised this as a big (and unresolved) issue across many recent forums.

@thusinh1969
Copy link

thusinh1969 commented Jun 13, 2021

Keras is going somewhere :( ... Not even a response from https://github.com/fchollet :(

@ThomasHenckel
Copy link

I think class weights can always be implemented via sample weights (see sklearn.utils.class_weight.compute_sample_weight). It seems like Keras does support sample weights for each output, so maybe using compute_sample_weight for each output can work? If you already have sample weights, I think you should be able to do weight = weight * new_weight (but someone with more of a statistics background should confirm this)

Thanks @adriangb
This worked for me, I just wanted to adjust the weight on for the last class

from sklearn.utils.class_weight import compute_sample_weight
class_weight = [{0: 1, 1: 1}, {0: 1, 1: 1}, {0: 1, 1: 1}, {0: 0.8, 1: 1.1}]
sample_weight = compute_sample_weight(class_weight,labels)

Would be nice if Keras would accept the class_weight directly, but until then...

@philosofool
Copy link

sample_weight is not supported when using tf.data.Dataset instances, so the need for class_weight with multilabel models remains.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests