I am trying to prune InceptionNetV3 from keras trained on imagenet, right now I am using a tensorflow-datasets which has a subset of imagenet which I use for pruning. Currently my pruned models do not work and returns garbage data when tested using the same dataset it was pruned on. How do I prune without losing all accuracy? Here is my code:
Imports:
import logging
import tempfile
from pathlib import Path
import tensorflow as tf
from tensorflow import keras
import numpy as np
import tensorflow_datasets as tfds
from cv2 import cv2 # Pylint now views cv2 as a library
import tensorflow_model_optimization as tfmot
All of these imports are up to date, I'm currently using Python 3.10.1.
Here is the code I am using to prune the model.
v2_path = 'C:\\temp\\imagenet_v2'
inception_image_size = (299, 299)
image_count = 5
batch_size = 512
epochs = 4
dataset = tfds.load(name='imagenet_v2', split='test', data_dir=v2_path)
numpy_dataset = tfds.as_numpy(dataset)
layer_count = 313
count = [1]
def main():
v2_full_path = 'C:\\temp\\imagenet_v2\\downloads\\extracted\\TAR_GZ.s3-us-west-2_image_image-match-frequ8MN_35JZFrGeoTI82aIgjNtpWbosMu7yp_w5ODXJynw.tar.gz\\imagenetv2-matched-frequency-format-val'
dataset_train = tf.keras.utils.image_dataset_from_directory(directory=v2_full_path, image_size=inception_image_size,
label_mode='categorical')
inception_model = tf.keras.applications.InceptionV3(weights='imagenet',
pooling='avg',
input_shape=(299, 299, 3))
def apply_pruning_to_dense(layer):
count[0] += 1 # Python throws a fit if I use a normal variable, but doesn't mind layer_count
if layer_count - count[0] < 5:
return tfmot.sparsity.keras.prune_low_magnitude(layer)
return layer
model_for_pruning = tf.keras.models.clone_model(
inception_model,
clone_function=apply_pruning_to_dense,
)
inception_model = tf.keras.applications.InceptionV3(weights="imagenet")
logdir = tempfile.mkdtemp()
callbacks = [
tfmot.sparsity.keras.UpdatePruningStep(),
tfmot.sparsity.keras.PruningSummaries(log_dir=logdir),
]
model_for_pruning.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.SGD(learning_rate=1e-3),
metrics=['accuracy'])
model_for_pruning.fit(dataset_train,
batch_size=batch_size,
epochs=epochs,
callbacks=callbacks,
use_multiprocessing=True)
save_test_model(inception_model, ".tflite")
save_test_model(model_for_pruning, "_prune.tflite")
When I run the model through model_for_pruning.fit(...)
the accuracy rating is only around 1% - 2%. Though it used to be around .16% per epoch. I fixed this by adding label_mode='categorical'
when obtaining the dataset which leads me to believe that the issue is somehow with either my dataset or how I use it.
The resulting pruned tensorflow lite model has a 0% accuracy rating when tested against the imagenet_v2 subset while the upruned one gets around a 40% accuracy rating.