Skip to content

En/review eg/losse val grad#39

Open
eduardolneto wants to merge 3 commits into
eg/analysisfrom
en/review_eg/losse_val_grad
Open

En/review eg/losse val grad#39
eduardolneto wants to merge 3 commits into
eg/analysisfrom
en/review_eg/losse_val_grad

Conversation

@eduardolneto

Copy link
Copy Markdown
Contributor

Modifying losses.py to allow custom_losses to have a val_and_grad function instead of only a grad function. This is necessary for the augmented lagragian modifications in the parallel pull request, since in lbfgsb the val_and_grad option is more efficient and the only viable option. Changes on losses.py.

…ction instead of only a grad function. This is necessary for the augmented lagragian modifications in the parallel pull request, since in lbfgsb the val_and_grad option is more efficient and the only viable option.
@eduardolneto eduardolneto changed the base branch from main to eg/analysis June 27, 2026 14:29

@EstevaoMGomes EstevaoMGomes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Great changes!

Comment thread essos/losses.py
args = tuple_unraveler(dofs)
return {name: value for name, value in zip(self.args_names, args)}

self._dofs_to_pytree = _named_unraveler

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This fixes the problem that we had, that the custom_loss did not have a named unraveler, only the composite loss, right?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would need to test this to make sure everything works properly. In theory, it makes sense, but I need more time to figure it out properly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, The examples to be added after were technically working. I guess we could add more later?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added some tests on test_multiobjectives.py

Comment thread essos/losses.py
self._dofs_to_args = None

def _ensure_unravelers(self):
if self._starting_dofs is None or self._dofs_to_args is None or self._dofs_to_pytree is None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe use and instead of or

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am not sure I understand this change. If none of those are defined donn't we always want to define them?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You are right.

@rogeriojorge rogeriojorge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly 3 minor stuff:

  1. losses.py:111, custom_loss.call_pytree():
    dofs_to_pytree now returns a named dict, but call_pytree() still does self.fun(*dofs_pytree, **self.kwargs). If dofs_pytree is a dict, this passes the keys as positional args. I think this should either be:

args = tuple(dofs_pytree[name] for name in self.args_names)
return self.fun(*args, **self.kwargs)

or, if the custom loss functions are expected to accept keyword args:

return self.fun(**dofs_pytree, **self.kwargs)

  1. losses.py:132-136, custom_loss.grad_pytree()

same things. It currently does *dofs_pytree, which will be wrong if dofs_pytree is the new named dict. I would build

args = tuple(dofs_pytree[name] for name in self.args_names)

and differentiate with those positional args, then put the gradients back into buffer.

  1. losses.py:80, _ensure_unravelers

I think "or" is actually the right condition here. Using "and" would only rebuild when all of them are None, which could leave _dofs_to_args or _dofs_to_pytree unset. But not sure.


A small test for custom_loss.value_and_grad() with two dependencies, and dofs_to_pytree() followed by call_pytree() / grad_pytree() would probably catch the dict-vs-tuple issue above.

@eduardolneto

Copy link
Copy Markdown
Contributor Author

I think I addressed all the comments for this PR.

@rogeriojorge

Copy link
Copy Markdown
Member

Can you just add one assertion for value_and_grad() itself in test_custom_loss_named_unraveler()?
Otherwise, it's good for me to merge

@rogeriojorge rogeriojorge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you just add one assertion for value_and_grad() itself in test_custom_loss_named_unraveler()?
Otherwise, it's good for me to merge

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.

3 participants