Skip to content

Subclassing tf.keras.models.Model save_model saves h5py but not h5/hdf5 file types #29545

Closed
@Ryandry1st

Description

@Ryandry1st

Please make sure that this is a bug. As per our GitHub Policy, we only address code/doc bugs, performance issues, feature requests and build/installation issues on GitHub. tag:bug_template

System information

  • Have I written custom code (as opposed to using a stock example script provided in TensorFlow): Yes
  • OS Platform and Distribution (e.g., Linux Ubuntu 16.04): Google Colab
  • TensorFlow installed from (source or binary): Pip
  • TensorFlow version (use command below): 2.0.0b
  • Python version: 3.6.7
  • GPU model and memory: Tesla T4

Describe the current behavior
-Using tf 2.0.0b-gpu on google colab.

While using the subclassing API for a subclassed layer and model, I was unable to use the model.save_model() function for h5 or hdf5 file types, but I could successfully save and load the model if it was saved as h5py file type. In the toy example being used it worked correctly, although this may not be the case. Note that the get_config method was implemented in the custom layer and custom model.

Describe the expected behavior
Either the save_model should always work (I believe this is a feature goal) and the documentation should reflect this, or if the save is likely to produce incorrect results it should raise an error and the documentation should continue to suggest that custom models can only be saved with the save_weights feature.

Code to reproduce the issue

import tensorflow as tf
from tensorflow import keras

class resblock(keras.layers.Layer):
    def __init__(self, n_layers, n_neurons, **kwargs):
        super().__init__(**kwargs)
        self.hidden = [keras.layers.Dense(n_neurons,
                                          activation='elu',
                                          kernel_initializer='he_normal')
                       for _ in range(n_layers)]
        
    def call(self, inputs):
        z = inputs
        for layer in self.hidden:
            z = layer(z)
        return inputs + z
    
    def get_config(self):
        base_config = super().get_config()
        return {**base_config}

class res_mod(keras.models.Model):
    def __init__(self, output_dim, activation=None, **kwargs):
        super().__init__(**kwargs)
        self.f1 = keras.layers.Flatten()
        self.hidden1 = keras.layers.Dense(100, activation='elu', kernel_initializer='he_normal')
        self.b1 = resblock(2, 100)
        self.b2 = resblock(2, 100)
        self.output1 = keras.layers.Dense(output_dim, activation=keras.activations.get(activation))
        
    def call(self, inputs):
        z = self.f1(inputs)
        z = self.hidden1(z)
        for _ in range(4):
            z = self.b1(z)
        z = self.b2(z)
        return self.output1(z)
    
    def get_config(self):
        base_config = super().get_config()
        return{**base_config, "output_dim" : output_dim, "activation": activation}
    

model = res_mod(10, activation='softmax')
model.compile(loss='sparse_categorical_crossentropy', optimizer='nadam', metrics=['accuracy'])

model.fit(train, epochs=25, validation_data=test)
# This is able to save and works correctly, returning the trained model
model.save('custom_model.h5py')
del model
model = keras.models.load_model('custom_model.h5py', custom_objects={'resblock': resblock})

Other info / logs
This will raise an error that only sequential or functional models can be saved
model.save('custom_model.h5')

Metadata

Metadata

Assignees

Labels

TF 2.0Issues relating to TensorFlow 2.0comp:kerasKeras related issuestype:bugBug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions