Update keras, tf and new model usage, numpy 2.0 updates#1206
Conversation
| :param fn: Plugin function | ||
| :return: function | ||
| """ | ||
| global plugins_dict |
There was a problem hiding this comment.
global is only needed when a function rebinds a module variable, like plugins_dict = {...}.
|
@shania-m this is the final PR that will update TF and keras to be current! |
|
@shania-m I've updated numpy to allow for 2.0+ as well here! |
|
@JGSweets please let me know when it’s ready for review |
|
@shania-m fixed all the issues related. Updating mypy was more complicated than expected when trying to handle the numpy update! |
|
@shania-m it is ready for review! |
| """Compiles the loss for the given model and number of labels.""" | ||
| # Compile the model | ||
| softmax_output_layer_name = model.output_names[0] | ||
| # losses = {softmax_output_layer_name: "categorical_crossentropy"} |
| # Compile the model | ||
| softmax_output_layer_name = model.output_names[0] | ||
| # losses = {softmax_output_layer_name: "categorical_crossentropy"} | ||
| losses = ["categorical_crossentropy", None, None] |
There was a problem hiding this comment.
Quick question — the loss assignment changed from dict-based (by output name) to list-based (by position):
CharacterLevelCnnModel (3 outputs)
losses = ["categorical_crossentropy", None, None]
CharLoadTFModel (2 outputs)
losses = ["categorical_crossentropy", None]
Can you confirm the output ordering is stable and these align correctly with the model outputs? Just want to make sure the positional
assignment matches up since the dict approach was order-independent.
There was a problem hiding this comment.
Good call out! I believe the previous layers were list based which is why in keras 3 it required the list losses. This code matched that, however, like you I prefer the order-independent approach and am looking into the requirements of that and ensuring the backwards compatibility of loading a model that was list based initially.
|
Few small things, thanks for the contribution! |
|
|
||
| def _compile_model(self, num_labels: int) -> None: | ||
| """Compile the model with dict-based losses and metrics.""" | ||
| losses = { |
There was a problem hiding this comment.
ensure we utilize dict based solution
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| cls, softmax_output: tf.Tensor, argmax_output: tf.Tensor | None = None | ||
| ) -> dict[str, tf.Tensor]: | ||
| """Return normalized dict outputs for training and inference.""" | ||
| if argmax_output is None: |
There was a problem hiding this comment.
ensure normalized dict based model outputs
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
| @classmethod | ||
| def _normalize_model_outputs(cls, model: tf.keras.Model) -> tf.keras.Model: | ||
| """Convert list-style outputs to the normalized dict structure.""" | ||
| return labeler_utils.normalize_tf_model_outputs( |
There was a problem hiding this comment.
conversion of previous style for consistency requirement by keras 3
|
|
||
| # boolean if the label mapping requires the mapping for index 0 reserved | ||
| requires_zero_mapping: bool = True | ||
| _SOFTMAX_OUTPUT = "softmax_output" |
There was a problem hiding this comment.
normalize layer names
|
|
||
| # boolean if the label mapping requires the mapping for index 0 reserved | ||
| requires_zero_mapping = False | ||
| _SOFTMAX_OUTPUT = "softmax_output" |
There was a problem hiding this comment.
normalize layer names
| num_labels, activation="softmax", name="softmax_output" | ||
| num_labels, | ||
| activation="softmax", | ||
| name=self._new_softmax_head_name(), |
There was a problem hiding this comment.
allows iteration on layer name due to keras reqs
| acc_value = next( | ||
| (value for key, value in model_results.items() if key.endswith("acc")), | ||
| np.nan, | ||
| ) | ||
| f1_value = next( | ||
| (value for key, value in model_results.items() if "f1" in key.lower()), | ||
| np.nan, | ||
| ) |
There was a problem hiding this comment.
due to dict based output
| BaseModel.__init__(self, label_mapping, parameters) | ||
|
|
||
| @classmethod | ||
| def _create_model_outputs( |
There was a problem hiding this comment.
similar to char_load_tf_model.py but with the threshargmax
| acc_value = next( | ||
| (value for key, value in model_results.items() if key.endswith("acc")), | ||
| np.nan, | ||
| ) | ||
| f1_value = next( | ||
| (value for key, value in model_results.items() if "f1" in key.lower()), | ||
| np.nan, | ||
| ) |
There was a problem hiding this comment.
due to dict based change
| return None | ||
|
|
||
|
|
||
| def normalize_tf_model_outputs( |
There was a problem hiding this comment.
this allows us backwards compatibility with the list based models.
|
@shania-m sorry to add so much more, but this should be safer since it has the dict mapping back! |
|
Thanks for the contributions!
|
Thanks! |
@JGSweets i need to review these before approving |
|
@shania-m of course! ty for working with me on this! |
|
After this goes in, what would be the steps needed to make a release? I assume I cannot be part of that, but if so I'm happy to help achieve that as well! |
|
I realized it might also be good to add py3.12 / py3.13 to the test list, especially since py3.10 reaches EOL this fall. Will do that in a subsequent PR. |
this pr:
NOTES: