-
Notifications
You must be signed in to change notification settings - Fork 19.5k
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
Bring back loss information for multiple outputs #20023
Bring back loss information for multiple outputs #20023
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #20023 +/- ##
==========================================
+ Coverage 79.26% 79.27% +0.01%
==========================================
Files 500 501 +1
Lines 46842 46890 +48
Branches 8626 8637 +11
==========================================
+ Hits 37127 37172 +45
Misses 7977 7977
- Partials 1738 1741 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
b0a318c
to
6da46d3
Compare
6da46d3
to
6c68683
Compare
Still some bugs need to be resolved. |
da41073
to
c28cf75
Compare
This PR should be ready now. |
c28cf75
to
320b7d7
Compare
320b7d7
to
97915e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
This is an important feature, especially for a multi-modal model
What's wrong with just letting users specify what they want to monitor via the metrics
argument?
I think that if we're going to do this, we should find a solution that only adds a minimal amount of complexity, e.g. if the loss is non-unary, add the loss configuration to CompileMetrics
.
keras/src/trainers/trainer.py
Outdated
|
||
# If in symbolic scope, skip `self.losses` to ensure we don't access | ||
# any variables. Otherwise, it might break. | ||
if not in_symbolic_scope(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels quite brittle -- compute_loss
is a method that is intended to be overridden by users in various cases, and those users should not need to be aware of SymbolicScope
. Why is it necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a workaround specific to the torch backend.
The root cause is that backend.get_stateless_scope().get_current_value(variable)
in _get_regularization_losses
in self.losses
returns None
, which breaks the following computation within backend.compute_output_spec
.
Let me try to fix it another way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have moved the logic to Layer._get_regularization_losses
.
This should be more robust now.
It is fine if the loss computation is not intensive; the redundancy in import numpy as np
from keras import backend
from keras import layers
from keras import models
np.random.seed(42)
x = np.random.rand(8, 3)
y1 = np.random.rand(8, 1)
y2 = np.random.randint(0, 2, (8, 1))
inputs = layers.Input(shape=(3,), name="inputs")
output_a = layers.Dense(1, name="a")(inputs)
output_b = layers.Dense(1, name="b")(inputs)
model = models.Model(inputs, {"a": output_a, "b": output_b})
model.compile(
optimizer="sgd",
loss={"a": "mean_squared_error", "b": "binary_crossentropy"},
metrics={"a": "mean_squared_error", "b": "binary_crossentropy"},
)
if backend.backend() != "numpy":
model.fit(x, (y1, y2), batch_size=2, epochs=1, shuffle=False, verbose=1)
logs = model.evaluate(x, (y1, y2), batch_size=2, verbose=1, return_dict=True) However, things become noticeably complicated if we override Additionally, it is inconvenient to require users to implement almost the same logic in
I don't think adding the loss config to |
181033b
to
8ef4d64
Compare
3d162f8
to
603525c
Compare
@fchollet Please let me know if this PR is a good fit or not for Keras3. Just pinging some comments for visibility:
There is a comment mentioning the clarity of logs: #19159 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the latest update, I think this change can be merged. Thank you for the contribution!
this is just a random comment for the most part but shouldn't also should use lists instead of dicts imho, as it makes it confusing ? since it's |
Hey @ghsanti |
i see it was for showing the losses, ty for the reply! |
This covers the case that a single loss is assigned to each output. How would I do this in case of a model with more losses than outputs? For instance, a variational autoencoder that has a single output (the decoded image), but multiple losses (reconstruction loss + KL loss)? How can I make sure that both losses are logged separately? |
Closes #18993
Closes #19219
Related to #18467
This is an important feature, especially for a multi-modal model, that is currently missing in Keras 3 compared to Keras 2.
The implementation is quite simple by adding the
Mean
metric inCompileLoss
.All TODOs in
model_tests.py
have been resolved.A simple demo:
Got this:
EDITED:
I have introduced a new scope (
SymbolicScope
) to control the behavior incompute_loss
. The reason is thatself.losses
will break when usingbackend.compute_output_spec
. Some edge cases in CI also require this.