Description
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')