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

Add weighted_metrics arg to compile #7536

Merged
merged 6 commits into from
Aug 12, 2017

Conversation

nicolewhite
Copy link
Contributor

Alternative to #7482.

This implementation is growing on me. I think the flexibility here is nice.

from keras.models import Sequential
from keras.layers import Dense

import numpy as np

X = np.random.normal(size=(100, 10))
y = np.random.randint(2, size=100)
sample_weight = np.random.normal(size=100)
loss = 'binary_crossentropy'

model = Sequential()
model.add(Dense(10, input_shape=(10, )))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss=loss, optimizer='rmsprop', metrics=[loss], weighted_metrics=[loss])

model.fit(X, y, epochs=5, verbose=2, sample_weight=sample_weight)
Epoch 1/5
0s - loss: -1.1340e-01 - binary_crossentropy: 0.7633 - weighted_binary_crossentropy: -1.1340e-01
Epoch 2/5
0s - loss: -1.2764e-01 - binary_crossentropy: 0.7729 - weighted_binary_crossentropy: -1.2764e-01
Epoch 3/5
0s - loss: -1.3798e-01 - binary_crossentropy: 0.7782 - weighted_binary_crossentropy: -1.3798e-01
Epoch 4/5
0s - loss: -1.4393e-01 - binary_crossentropy: 0.7837 - weighted_binary_crossentropy: -1.4393e-01
Epoch 5/5
0s - loss: -1.5062e-01 - binary_crossentropy: 0.7877 - weighted_binary_crossentropy: -1.5062e-01

@fchollet
Copy link
Collaborator

fchollet commented Aug 6, 2017

Could you list a few use cases where this approach is better? This would be useful data for picking one API or the other.

@nicolewhite
Copy link
Contributor Author

nicolewhite commented Aug 7, 2017

I think this approach is better because the flexibility covers both the use cases:

  • someone wants to track both an unweighted and weighted metric
  • someone wants to track only a weighted metric

The other API option, simply setting weigh_metrics=True, only allows for the latter.

You might be interested in tracking both a weighted and unweighted metric when you are optimizing for some weighted sub-problem that you have devised, but you still want to make sure the model is performing its initial job well, that is, its accuracy regardless of the weights (assuming a classification problem). It also seems likely you'd want to understand the relationship between the performance of the weighted and unweighted metrics as you tinker with your sample weights. For example, it might be the case that you are choosing weights that perform really well on your weighted metric but your unweighted metric tanks, which could raise red flags and cause you to reconsider your approach.

It also seems possible in the multi-output scenario that someone would want to compute a weighted metric for one output and an unweighted metric for another. This API would handle that use case very easily, whereas the other would not. For example:

metrics = {'output_1': ['accuracy']}
weighted_metrics = {'output_2': ['accuracy']}

model.compile(..., metrics=metrics, weighted_metrics=weighted_metrics)

I should probably add a test for this use case, actually.

@fchollet
Copy link
Collaborator

I agree this PR is the better approach, so we will go with this one.

Copy link
Collaborator

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: lines in the test are too long, please shorten.

@@ -637,6 +597,8 @@ def compile(self, optimizer, loss, metrics=None, loss_weights=None,
If the model has multiple outputs, you can use a different
`sample_weight_mode` on each output by passing a
dictionary or a list of modes.
weighted_metrics: list of metrics to be evaluated and weighted
by sample_weight or class_weight during training and testing
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation

standard_weight = 1
standard_score_sequential = 0.5

decimal_precision = {
'cntk': 2,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CNTK is only accurate to two decimal places. I'm not sure why.

Copy link
Collaborator

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

@fchollet fchollet merged commit 1bbd52c into keras-team:master Aug 12, 2017
@nicolewhite nicolewhite deleted the weighted-metrics branch August 14, 2017 19:54
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

Successfully merging this pull request may close these issues.

2 participants