-
Notifications
You must be signed in to change notification settings - Fork 613
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
Point optimizer to tf.keras.optimizer.legacy.Optimizer to be compatib… #2706
Conversation
@rehanguha @lokhande-vishnu @szutenberg @juntang-zhuang @RaphaelMeudec @PhilJd @manzilz @junjiek @CyberZHG @pkan2 @hyang0129 You are owners of some files modified in this pull request. |
changes to yogi.py: LGTM |
changes to adabelief.py LGTM! |
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.
tensorflow_addons/optimizers/cocob.py changes LGTM.
@chenmoneygithub To understand this a little bit:
/cc @seanpmorgan |
@bhack Thanks for your questions! Re your questions:
Hope this would answer your question! |
Yes, thanks for the confirmation.
I have some doubt on this point as it really depends on the Keras, Keras-CV, Keras-NLP roadmaps and how these will overlap with the existing "legacy" components here. If a refactor it is needed probably it is better to evaluate if the single optimizer will be absorbed, with the new inheritance, in any of these Keras-* repos. |
@bhack Yes, I have exactly the same thought - new optimizer-based implementation should be done in Keras repo rather than doing in-place code changes to addon.optimizers. |
Ok. |
Got it, will reflect it in the code. |
Hi @chenmoneygithub , thanks for the PR and keeping us in the loop. As you can see from our CI this appears to be a significant breaking change. TF Addons supports 3 TensorFlow/Keras versions during each release, so implementing this change would require some work arounds on our end. I'm wondering if this is implemented as intended on the Keras side? Has legacy.optimizer been available / has the new optimizer been part of experimental for a few releases? Typically Keras is quite good at backwards compatibility. cc @fchollet |
I didn't see an RFC in keras governance or anything on this, so I suspect more downstream consumers (other than TFA) will be surprised. |
Also isn't not explained what these legacy optimizers are in the official documentation: |
@seanpmorgan yes, your concern is very reasonable. For some background context: In this release (TF/Keras 2.9), our goal is to push out the experimental optimizer, mainly for internal adoptions. Making experimental optimizer the default one will happen in a later release (2.10 or 2.11), and old optimizer deprecation would happen in a much later release (we have not decided which one yet!), but we made this legacy optimizer, which is a mirror of For the question about breakage: the actions failed due to symbol missing, not functionality. I added the version control, which means only use @bhack Yea, this is something we will fix. The page should be more clear. |
I suppose that @seanpmorgan meant that he didn't find any RFC in: Do you meany it will land there before the official deprecation?
If you have added this in Keras directly and you will not do a patch release we need to wait for the next stable to cherry pick this PR as we switch TF/Keras versions every new TF stable release/rc. |
@bhack Thanks! Yes, we will make public notice before taking migration/deprecation actions, now we are focusing on internal optimizer adoptions. Yea at this moment it's hard to edit the page. |
What do you mean? I was mentioning about our dependency on a stable TF release in TFA master instead of TF nightly. |
@bhack Sorry I misread your previous comment, I thought you mean the documentation of Re you previous comment - I don't think cherrypicking is required? I am saying there are two options here:
|
I was talking about this. Can you point me on this version control? |
@bhack My previous push failed due to some merge conflict, I will ping you once I get the latest code uploaded. |
Ok thanks. More in general:
It could be ok for us but you need to consider:
|
d1448ae
to
60e3d3a
Compare
Ok, now I see that we are back on the original idea to conditional control the namespace downstream (in TFA directly). |
Yes, this is what I was afraid of. This PR is sub-optimal because it makes downstream consumers inherit the debt of a quickly implemented public api change to Keras. @chenmoneygithub @fchollet is there anywhere publicly facing from the Keras perspective where we can discuss this? TFA is not the only one impacted by this. cc @joanafilipa |
@bhack I just updated the code with the version control part. Yes, I am aware of the large user group of tf addons, and never want to break their workflows. On Keras it remains unclear to us that when we can completely remove the code of the old optimizer, personally I feel it is a hard task. If you are curious on why we are making the new optimizer even though we are not removing the old code in the short term, briefly we feel the old optimizer's logic and layout are bad, so we replace things like slot variables and fused ops with more understandable code, and split out the distributed training part to a separate class. |
Personally I agree with Sean's vision. For a top namespace change like This time it went like this, probably for a good reasons (I don't know) but I would not feel like promoting this process in general for our community / ecosystem. |
We discussed about RFC when we kicked off the project, and did not go for it because main changes happen on internal logic, while the public API mostly remains identical. Our rollout journey would be hidden for main users, basically the |
I could understand this only eventually for end-users but not for derived/ecosystem projects. I don't think that TFA is a special case for derived projects. |
62625d6
to
743c51d
Compare
@bhack Refactored the code, please take another look when you are free, thanks! |
@@ -14,6 +14,7 @@ | |||
# ============================================================================== | |||
"""Additional optimizers that conform to Keras API.""" | |||
|
|||
from tensorflow_addons.optimizers.constants import BASE_OPTIMIZER_CLASS |
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 breaks alphabetic order
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 order matters, if this line does not go before other optimizers it creates a cyclic importing.
raise TypeError( | ||
"optimizer is not an object of tf.keras.optimizers.Optimizer" | ||
) | ||
if tf.__version__[:3] <= "2.8": |
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.
why do we need this condition? What if we would write (tf.keras.optimizers.Optimizer, BASE_OPTIMIZER_CLASS)
?
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 did this for the error message to be accurate. but rethinking about it, I am doing (tf.keras.optimizers.Optimizer, BASE_OPTIMIZER_CLASS) check and imply that after 2.9 you should expect tf.keras.optimizers.legacy.Optimizer.
@@ -0,0 +1,5 @@ | |||
import tensorflow as tf |
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.
missing copyright header
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.
done
@@ -0,0 +1,5 @@ | |||
import tensorflow as tf | |||
|
|||
BASE_OPTIMIZER_CLASS = tf.keras.optimizers.legacy.Optimizer |
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.
Why not if ... else? It will crash if tf.keras.optimizers.legacy doesn't exist (TF 2.8), right?
Are you sure it has to be CAPITAL_LETTER?
I'd rename it to KerasLegacyOptimizer (or KERAS_LEGACY_OPTIMIZER - I'm not an expert in conventions 😄 ) and rename the file to keras.py.
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! I changed the check condition.
For the naming, yea, we probably want to do camel case since it is a class itself. But I don't want to imply Legacy in the name, which is not yet 100% correct - we still use tf.keras.optimizers.Optimizer
in many places. I am renaming to BaseOptimizerClass
, wdyt?
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.
@chenmoneygithub - I expect that after refactor in keras is done, we will be gradually switching back to tf.keras.optimizers.Optimizer
. BaseOptimizerClass
will be confusing then because it'll be name for the legacy class.
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.
sg, renamed to KerasLegacyOptimizer.
import tensorflow as tf | ||
|
||
BASE_OPTIMIZER_CLASS = tf.keras.optimizers.legacy.Optimizer | ||
if tf.__version__[:3] <= "2.8": |
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.
As I wrote previously:
>>> tf.__version__
'2.10.0-dev20220531'
>>> tf.__version__[:3]
'2.1'
>>> tf.__version__[:3] > "2.8"
False
Please fix this condition (also in other files) or just check if tf.keras.optimizers.legacy
exists, maybe code would be cleaner then...
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.
good catch! done
@@ -16,11 +16,12 @@ | |||
import tensorflow as tf | |||
from tensorflow_addons.utils import types |
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.
isn't required to update types.Optimizer?
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.
good catch! done
@@ -17,12 +17,13 @@ | |||
import tensorflow as tf | |||
from tensorflow_addons.utils.types import FloatTensorLike | |||
|
|||
from tensorflow_addons.optimizers import BASE_OPTIMIZER_CLASS |
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 line should be added after line 17
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.
done
@@ -401,13 +401,17 @@ def test_var_list_with_exclude_list_sgdw(dtype): | |||
) | |||
|
|||
|
|||
if tf.__version__[:3] > "2.8": |
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.
Use from packaging.version import Version
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! I am switching to check if "optimizers.legacy" exists to keep consistency.
@@ -27,8 +27,14 @@ | |||
from typing import Union, Callable | |||
|
|||
|
|||
if tf.__version__[:3] > "2.8": |
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.
Use from packaging.version import Version
@@ -261,10 +261,17 @@ def _do_use_weight_decay(self, var): | |||
return var.ref() in self._decay_var_list | |||
|
|||
|
|||
optimizer_class = Union[ |
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.
Why not BaseOptimizerClass?
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 am renaming this to keras_legacy_optimizer to keep aligned with changes suggested by Michal.
Optimizer = Union[tf.keras.optimizers.Optimizer, str] | ||
if importlib.util.find_spec("tensorflow.keras.optimizers.legacy") is not None: | ||
Optimizer = Union[ | ||
tf.keras.optimizers.Optimizer, tf.keras.optimizers.legacy.Optimizer, str |
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.
Same as above
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 I am using the name "Optimizer" to keep it unchanged.
Hi there, sorry for not updating this for a while. I have been terribly sick for the last a few days, will update this PR when I can work. Thanks! |
Please check ci/cd. |
@fsx950223 I checked the failure log, and it seems to ask for type annotation from source Keras optimizer code not changed I made to addons. Can I ask what should we do here? |
Hi maintainers, the current error message is:
Which does not look like a new issue imported by this PR. Could anyone help check and give some suggestions on how we should handle it? https://github.com/tensorflow/addons/runs/6836413149?check_suite_focus=true I would like to have this PR submitted soon to avoid potential breakage of addons.optimizers in the next TF release. |
@bhack Thanks! But the error is pointing to main Keras repo rather than some classes I am changing in addons repo. Is there any way to exempt the check? |
If can add an exclusion at: https://github.com/tensorflow/addons/blob/master/tools/testing/source_code_test.py#L41 |
8e0439a
to
268d37a
Compare
Description
Brief Description of the PR:
Keras has made a new version of optimizer, check the link here, and in a future TF/Keras release,
tf.keras.optimizers.XXX
will point to the new optimizer, and old optimizers will continue to be supported underlegacy
namespace until further notice. To avoid code breakage, this PR is replacingtf.keras.optimizer.Optimizer
withtf.keras.optimizer.legacy.Optimizer
.Fixes # (issue)
Type of change
Checklist:
How Has This Been Tested?
No new test cases are required, just making sure the current test is not broken due to the change.