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

prune_low_magnitude retruns None #12

Closed
youssefsalah76 opened this issue Jun 18, 2019 · 12 comments
Closed

prune_low_magnitude retruns None #12

youssefsalah76 opened this issue Jun 18, 2019 · 12 comments
Assignees
Labels
technique:pruning Regarding tfmot.sparsity.keras APIs and docs

Comments

@youssefsalah76
Copy link

I am trying to prune a trained model , but model is saved a model_architecture.json and weights.h5 and model is loaded as follows:
with open(modeljson) as f:
self.model = model_from_json(f.read())
self.model.load_weights(modelfile)

But whenever I try to prune it the output from:
new_pruned_model = sparsity.prune_low_magnitude(model, **new_pruning_params)
is always none so it crashes at the model.compile part as type none has no attribute compile
Any help please

@liyunlu0618 liyunlu0618 self-assigned this Jun 23, 2019
@zhoujungis
Copy link

How do you solve it? I encounter the similar problem and could you help me?

@s36srini
Copy link

s36srini commented Jul 22, 2019

Make sure you're using Keras from Tensorflow-Python. Try this:
from tensorflow.python import keras # Important: TensorFlow-Optimization uses this version of Keras. And then from tensorflow_model_optimization.sparsity import keras as sparsity. Your model must be built using the right version of Keras, otherwise it will return a Null model as per their source code. Let me know if this works, I had a similar issue a while ago.

@blakete
Copy link

blakete commented Aug 29, 2019

Make sure you're using Keras from Tensorflow-Python. Try this:
from tensorflow.python import keras # Important: TensorFlow-Optimization uses this version of Keras. And then from tensorflow_model_optimization.sparsity import keras as sparsity. Your model must be built using the right version of Keras, otherwise it will return a Null model as per their source code. Let me know if this works, I had a similar issue a while ago.

This did not seem to work for me. What version of Keras is considered correct?

@blakete
Copy link

blakete commented Aug 29, 2019

I am trying to prune a trained model , but model is saved a model_architecture.json and weights.h5 and model is loaded as follows:
with open(modeljson) as f:
self.model = model_from_json(f.read())
self.model.load_weights(modelfile)

But whenever I try to prune it the output from:
new_pruned_model = sparsity.prune_low_magnitude(model, **new_pruning_params)
is always none so it crashes at the model.compile part as type none has no attribute compile
Any help please

Did you ever find a solution to this problem?

@s36srini
Copy link

considered

You want to be using tf.keras for all sequential models. from tensorflow.python import keras, this effectively does the same thing, it's up to you as to whether you want to be explicit or not. What in specific isn't working for you? Are you getting a NoneType returned from the prune_low_magnitude wrapper?

@blakete
Copy link

blakete commented Aug 29, 2019

Yes, I am getting a NoneType returned from prune_low_magnitude.

Here is my output:
[info] applying pruning techniques to the provided model Traceback (most recent call last): File "train.py", line 72, in <module> main() File "train.py", line 55, in main student = prune(teacher, X_train, Y_train, X_test, Y_test, len(X_train), 256, 100, logdir) File "PrunePipeline.py", line 10, in prune studentOne = sparsePrune(model, X_train, Y_train, X_test, Y_test, numTrainingSamples, batchSize, epochs, logdir) File "PrunePipeline.py", line 24, in sparsePrune new_model.compile( AttributeError: 'NoneType' object has no attribute 'compile'

Here is the pruning code I am working with:
end_step = np.ceil(1.0 * num_train_samples / batch_size).astype(np.int32) * epochs new_pruning_params = { 'pruning_schedule': sparsity.PolynomialDecay(initial_sparsity=0.01, final_sparsity=0.1, begin_step=0, end_step=end_step, frequency=100) } new_model = sparsity.prune_low_magnitude(model, **new_pruning_params) new_model.compile( loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])

When putting a breakpoint on the compile, where I am getting the error, I see that the new_model is None.

These are the imports I am using for the model I am training and attempting to prune:
import os import tensorflow as tf from tensorflow.python.keras.layers import MaxPooling2D, Dropout, Dense, Flatten, Activation, Conv2D from tensorflow.python.keras.models import Model, Sequential, model_from_json import numpy as np from HelperUtil import HelpfulFunctions import datetime helpful = HelpfulFunctions()

Is this the incorrect way to go about it?

@s36srini
Copy link

Your imports look fine to me. Check the type of the model you generated: type(my_model) and lmk what the output is, it should be a tf.keras Model - it cannot be a Sequential Model, you need to convert it. This source code explains why you're getting a NoneType returned:


  if isinstance(to_prune, list):
    return _prune_list(to_prune, **params)
  elif isinstance(to_prune, keras.Model):
    return keras.models.clone_model(
        to_prune, input_tensors=None, clone_function=_add_pruning_wrapper)
  elif isinstance(to_prune, keras.layers.Layer):
    params.update(kwargs)
    return pruning_wrapper.PruneLowMagnitude(to_prune, **params)

Take a look at: https://github.com/tensorflow/model-optimization/blob/master/tensorflow_model_optimization/python/core/sparsity/keras/prune.py

Btw, just outta curiosity what do you plan on using pruning for? With this package as it is, you're only going to save footprint size when using a compression utility (e.g gzip). You're also not going to obtain any faster inference time, unless you've enabled some sort of meta parameter on your hardware device.

@s36srini
Copy link

You can convert it like this:

from keras import layers, models

input_layer = layers.Input(batch_shape=seqmodel.layers[0].input_shape)
prev_layer = input_layer
for layer in seqmodel.layers:
    prev_layer = layer(prev_layer)

funcmodel = models.Model([input_layer], [prev_layer])

@blakete
Copy link

blakete commented Aug 29, 2019

Your imports look fine to me. Check the type of the model you generated: type(my_model) and lmk what the output is, it should be a tf.keras Model - it cannot be a Sequential Model, you need to convert it. This source code explains why you're getting a NoneType returned:


  if isinstance(to_prune, list):
    return _prune_list(to_prune, **params)
  elif isinstance(to_prune, keras.Model):
    return keras.models.clone_model(
        to_prune, input_tensors=None, clone_function=_add_pruning_wrapper)
  elif isinstance(to_prune, keras.layers.Layer):
    params.update(kwargs)
    return pruning_wrapper.PruneLowMagnitude(to_prune, **params)

Take a look at: https://github.com/tensorflow/model-optimization/blob/master/tensorflow_model_optimization/python/core/sparsity/keras/prune.py

Btw, just outta curiosity what do you plan on using pruning for? With this package as it is, you're only going to save footprint size when using a compression utility (e.g gzip). You're also not going to obtain any faster inference time, unless you've enabled some sort of meta parameter on your hardware device.

This revealed the problem to me. I was returning my model incorrectly. I was not using the getter method in my custom class that contained my model. Thank you so much!

@alanchiao
Copy link

alanchiao commented Sep 14, 2019

@blakeedwards823 : it works with pruning a Sequential model. Sequential is an instance of keras.Model (see these docs).

@bothrasumit
Copy link

The pruned model type is <class 'NoneType'>
Hence, it does not work with other calls such as complie or fit or evaluate.
Suggest any solution.

@alanchiao alanchiao self-assigned this Dec 3, 2019
@alanchiao
Copy link

alanchiao commented Dec 3, 2019

Closing this issue since Blake has found a resolution here.
From my guesses, Blake did something effectively like this:

  model_wrapper = ModelWrapper()
  model_wrapper.model = model_from_json(...)
  sparsity.prune(model_wrapper)

instead of

  sparsity.prune(model_wrapper.model)

In other words, the actual Keras model object was not passed. I have filled an issue to add an error message when a Keras model object is not passed.

@blakeedwards823 : if I'm wrong, please correct me and share the before/after code that demonstrates your resolution.

@bothrasumit: let's move the discussion to your issue and see if Blake's problem is the same one you ran into from his response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
technique:pruning Regarding tfmot.sparsity.keras APIs and docs
Projects
None yet
Development

No branches or pull requests

7 participants