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

Bug in keras.src.saving.saving_lib._save_model_to_dir #20108

Closed
MegaCreater opened this issue Aug 10, 2024 · 6 comments
Closed

Bug in keras.src.saving.saving_lib._save_model_to_dir #20108

MegaCreater opened this issue Aug 10, 2024 · 6 comments

Comments

@MegaCreater
Copy link

MegaCreater commented Aug 10, 2024

tf.keras.__version__ -> "3.4.1"

If model is already saved then method call by keras.src.models.model.Model.save call keras.src.saving.saving_lib._save_model_to_dir, if model is already saved then asset_store = DiskIOStore(assert_dirpath, mode="w") (Line - 178) raise FileExistsError which error handling and finally clause line - asset_store.close() (Line - 189) causes - UnboundLocalError: local variable 'asset_store' referenced before assignment as asset_store is not define.

FileExistsError                           Traceback (most recent call last)
[/usr/local/lib/python3.10/dist-packages/keras/src/saving/saving_lib.py](https://localhost:8080/#) in _save_model_to_dir(model, dirpath, weights_format)
    139             )
--> 140         asset_store = DiskIOStore(assert_dirpath, mode="w")
    141         _save_state(


FileExistsError: [Errno 17] File exists: '/content/.../model_weights/assets'

During handling of the above exception, another exception occurred:

UnboundLocalError                         Traceback (most recent call last)
[/usr/local/lib/python3.10/dist-packages/keras/src/saving/saving_lib.py](https://localhost:8080/#) in _save_model_to_dir(model, dirpath, weights_format)
    148     finally:
    149         weights_store.close()
--> 150         asset_store.close()
    151 
    152 

UnboundLocalError: local variable 'asset_store' referenced before assignment

Solution to move asset_store.close() from finally clause to try clause or check if asset_store is define then only call asset_store.close() (Update from line 158 to line 189 i.e., https://github.com/keras-team/keras/blob/master/keras/src/saving/saving_lib.py#L158-L189)

def _save_model_to_dir(model, dirpath, weights_format):
    if not file_utils.exists(dirpath):
        file_utils.makedirs(dirpath)
    config_json, metadata_json = _serialize_model_as_json(model)
    with open(file_utils.join(dirpath, _METADATA_FILENAME), "w") as f:
        f.write(metadata_json)
    with open(file_utils.join(dirpath, _CONFIG_FILENAME), "w") as f:
        f.write(config_json)
    weights_filepath = file_utils.join(dirpath, _VARS_FNAME_H5)
    assert_dirpath = file_utils.join(dirpath, _ASSETS_DIRNAME)
    try:
        if weights_format == "h5":
            weights_store = H5IOStore(weights_filepath, mode="w")
        elif weights_format == "npz":
            weights_store = NpzIOStore(weights_filepath, mode="w")
        else:
            raise ValueError(
                "Unknown `weights_format` argument. "
                "Expected 'h5' or 'npz'. "
                f"Received: weights_format={weights_format}"
            )
        asset_store = DiskIOStore(assert_dirpath, mode="w")
        _save_state(
            model,
            weights_store=weights_store,
            assets_store=asset_store,
            inner_path="",
            visited_saveables=set(),
        )
    finally:
        weights_store.close()
        if ('asset_store' in locals()): asset_store.close()                 # check if `asset_store` define then only close 
@MegaCreater
Copy link
Author

import tensorflow as tf

class SimpleModel(tf.keras.Model):
    def __init__(self):
        super(SimpleModel, self).__init__()
        # Define layers here
        self.dense1 = tf.keras.layers.Dense(10, activation='relu')
        self.dense2 = tf.keras.layers.Dense(1)  # Output layer with no activation (regression)

    def call(self, inputs):
        # Define forward pass
        x = self.dense1(inputs)
        return self.dense2(x)

# Instantiate the model
model = SimpleModel()

model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=['accuracy']  # For classification tasks, change to appropriate metrics
)

model.save('sample_model',overwrite=True,zipped=False) # this will work 

model.save('sample_model',overwrite=True,zipped=False) # this will cause ERROR - as model is already saved. 

@Grvzard
Copy link
Contributor

Grvzard commented Aug 10, 2024

This issue has been fixed in the mainline (#19924, the commit just after the release of v3.4.1).

@ghsanti
Copy link
Contributor

ghsanti commented Aug 11, 2024

there is a misspelling here:

assert_dirpath = file_utils.join(dirpath, _ASSETS_DIRNAME)

but i shouldn't make a PR for that really, if anyone sees it, they can do it. (assert_dirpath should be asset_dirpath)
it was just slightly confusing upon reading it.

im curious what'd be use-cases for saving unzipped

@sachinprasadhs
Copy link
Collaborator

@MegaCreater , This is working fine with the latest Keras 3.5.0 version, attaching the Gist here
for reference, please verify and close the issue. Thanks

@MegaCreater
Copy link
Author

@sachinprasadhs thanks. It works fine after update.

Copy link

Are you satisfied with the resolution of your issue?
Yes
No

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants