Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Beschneiden im Keras-Beispiel

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Überblick

Willkommen zu einem End-to-End-Beispiel für das Beschneiden auf Gewichtsbasis .

Andere Seiten

Eine Einführung in das Beschneiden und eine Bestimmung, ob Sie es verwenden sollten (einschließlich der unterstützten Funktionen), finden Sie auf der Übersichtsseite .

Informationen zum schnellen Auffinden der für Ihren Anwendungsfall erforderlichen APIs (über das vollständige Beschneiden eines Modells mit 80% Sparsity hinaus) finden Sie im umfassenden Handbuch .

Zusammenfassung

In diesem Tutorial werden Sie:

  1. Trainieren Sie ein tf.keras Modell für MNIST von Grund auf neu.
  2. Optimieren Sie das Modell durch Anwenden der Bereinigungs-API und überprüfen Sie die Genauigkeit.
  3. Erstellen Sie aus dem Beschneiden 3x kleinere TF- und TFLite-Modelle.
  4. Erstellen Sie ein 10x kleineres TFLite-Modell aus der Kombination von Beschneiden und Quantisierung nach dem Training.
  5. Sehen Sie die Beständigkeit der Genauigkeit von TF bis TFLite.

Konfiguration

 pip install -q tensorflow-model-optimization
WARNING: You are using pip version 20.2.2; however, version 20.2.3 is available.
You should consider upgrading via the '/tmpfs/src/tf_docs_env/bin/python -m pip install --upgrade pip' command.

import tempfile
import os

import tensorflow as tf
import numpy as np

from tensorflow import keras

%load_ext tensorboard

Trainieren Sie ein Modell für MNIST, ohne es zu beschneiden

# Load MNIST dataset
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# Normalize the input image so that each pixel value is between 0 to 1.
train_images = train_images / 255.0
test_images = test_images / 255.0

# Define the model architecture.
model = keras.Sequential([
  keras.layers.InputLayer(input_shape=(28, 28)),
  keras.layers.Reshape(target_shape=(28, 28, 1)),
  keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation='relu'),
  keras.layers.MaxPooling2D(pool_size=(2, 2)),
  keras.layers.Flatten(),
  keras.layers.Dense(10)
])

# Train the digit classification model
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(
  train_images,
  train_labels,
  epochs=4,
  validation_split=0.1,
)
Epoch 1/4
1688/1688 [==============================] - 7s 4ms/step - loss: 0.3422 - accuracy: 0.9004 - val_loss: 0.1760 - val_accuracy: 0.9498
Epoch 2/4
1688/1688 [==============================] - 7s 4ms/step - loss: 0.1813 - accuracy: 0.9457 - val_loss: 0.1176 - val_accuracy: 0.9698
Epoch 3/4
1688/1688 [==============================] - 7s 4ms/step - loss: 0.1220 - accuracy: 0.9648 - val_loss: 0.0864 - val_accuracy: 0.9770
Epoch 4/4
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0874 - accuracy: 0.9740 - val_loss: 0.0763 - val_accuracy: 0.9787

<tensorflow.python.keras.callbacks.History at 0x7f32cbeb9550>

Bewerten Sie die Genauigkeit des Basistests und speichern Sie das Modell für die spätere Verwendung.

_, baseline_model_accuracy = model.evaluate(
    test_images, test_labels, verbose=0)

print('Baseline test accuracy:', baseline_model_accuracy)

_, keras_file = tempfile.mkstemp('.h5')
tf.keras.models.save_model(model, keras_file, include_optimizer=False)
print('Saved baseline model to:', keras_file)
Baseline test accuracy: 0.972599983215332
Saved baseline model to: /tmp/tmp6quew9ig.h5

Feinabstimmung des vorgefertigten Modells mit Schnitt

Definieren Sie das Modell

Sie wenden das Bereinigen auf das gesamte Modell an und sehen dies in der Modellzusammenfassung.

In diesem Beispiel starten Sie das Modell mit 50% Sparsity (50% Nullen in Gewichten) und enden mit 80% Sparsity.

In der umfassenden Anleitung erfahren Sie, wie Sie einige Ebenen für Verbesserungen der Modellgenauigkeit beschneiden.

import tensorflow_model_optimization as tfmot

prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude

# Compute end step to finish pruning after 2 epochs.
batch_size = 128
epochs = 2
validation_split = 0.1 # 10% of training set will be used for validation set. 

num_images = train_images.shape[0] * (1 - validation_split)
end_step = np.ceil(num_images / batch_size).astype(np.int32) * epochs

# Define model for pruning.
pruning_params = {
      'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.50,
                                                               final_sparsity=0.80,
                                                               begin_step=0,
                                                               end_step=end_step)
}

model_for_pruning = prune_low_magnitude(model, **pruning_params)

# `prune_low_magnitude` requires a recompile.
model_for_pruning.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model_for_pruning.summary()
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_model_optimization/python/core/sparsity/keras/pruning_wrapper.py:220: Layer.add_variable (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.add_weight` method instead.
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
prune_low_magnitude_reshape  (None, 28, 28, 1)         1         
_________________________________________________________________
prune_low_magnitude_conv2d ( (None, 26, 26, 12)        230       
_________________________________________________________________
prune_low_magnitude_max_pool (None, 13, 13, 12)        1         
_________________________________________________________________
prune_low_magnitude_flatten  (None, 2028)              1         
_________________________________________________________________
prune_low_magnitude_dense (P (None, 10)                40572     
=================================================================
Total params: 40,805
Trainable params: 20,410
Non-trainable params: 20,395
_________________________________________________________________

Trainieren und bewerten Sie das Modell anhand der Basislinie

Feinabstimmung mit Schnitt für zwei Epochen.

tfmot.sparsity.keras.UpdatePruningStep ist während des Trainings erforderlich, und tfmot.sparsity.keras.PruningSummaries bietet Protokolle zum Verfolgen des Fortschritts und zum Debuggen.

logdir = tempfile.mkdtemp()

callbacks = [
  tfmot.sparsity.keras.UpdatePruningStep(),
  tfmot.sparsity.keras.PruningSummaries(log_dir=logdir),
]
  
model_for_pruning.fit(train_images, train_labels,
                  batch_size=batch_size, epochs=epochs, validation_split=validation_split,
                  callbacks=callbacks)
Epoch 1/2
  1/422 [..............................] - ETA: 0s - loss: 0.2689 - accuracy: 0.8984WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.
Instructions for updating:
use `tf.profiler.experimental.stop` instead.
422/422 [==============================] - 3s 7ms/step - loss: 0.1105 - accuracy: 0.9691 - val_loss: 0.1247 - val_accuracy: 0.9682
Epoch 2/2
422/422 [==============================] - 3s 6ms/step - loss: 0.1197 - accuracy: 0.9667 - val_loss: 0.0969 - val_accuracy: 0.9763

<tensorflow.python.keras.callbacks.History at 0x7f32422a9550>

In diesem Beispiel ist die Testgenauigkeit nach dem Beschneiden im Vergleich zur Basislinie minimal beeinträchtigt.

_, model_for_pruning_accuracy = model_for_pruning.evaluate(
   test_images, test_labels, verbose=0)

print('Baseline test accuracy:', baseline_model_accuracy) 
print('Pruned test accuracy:', model_for_pruning_accuracy)
Baseline test accuracy: 0.972599983215332
Pruned test accuracy: 0.9689000248908997

Die Protokolle zeigen das Fortschreiten der Sparsity pro Schicht.

%tensorboard --logdir={logdir}

Für Nicht-Colab-Benutzer können Sie die Ergebnisse einer früheren Ausführung dieses Codeblocks auf TensorBoard.dev anzeigen .

Erstellen Sie 3x kleinere Modelle aus dem Beschneiden

Sowohl tfmot.sparsity.keras.strip_pruning als auch die Anwendung eines Standardkomprimierungsalgorithmus (z. B. über gzip) sind erforderlich, um die Komprimierungsvorteile des Bereinigens zu erkennen.

  • strip_pruning ist erforderlich, da es alle tf.Variable entfernt, die das Bereinigen nur während des Trainings benötigt, was sonst die Modellgröße während der Inferenz erhöhen würde
  • Die Anwendung eines Standardkomprimierungsalgorithmus ist erforderlich, da die serialisierten Gewichtsmatrizen dieselbe Größe haben wie vor dem Beschneiden. Beim Beschneiden werden jedoch die meisten Gewichtungen auf Null gesetzt, was zu einer zusätzlichen Redundanz führt, die Algorithmen verwenden können, um das Modell weiter zu komprimieren.

Erstellen Sie zunächst ein komprimierbares Modell für TensorFlow.

model_for_export = tfmot.sparsity.keras.strip_pruning(model_for_pruning)

_, pruned_keras_file = tempfile.mkstemp('.h5')
tf.keras.models.save_model(model_for_export, pruned_keras_file, include_optimizer=False)
print('Saved pruned Keras model to:', pruned_keras_file)
Saved pruned Keras model to: /tmp/tmpu92n0irx.h5

Erstellen Sie dann ein komprimierbares Modell für TFLite.

converter = tf.lite.TFLiteConverter.from_keras_model(model_for_export)
pruned_tflite_model = converter.convert()

_, pruned_tflite_file = tempfile.mkstemp('.tflite')

with open(pruned_tflite_file, 'wb') as f:
  f.write(pruned_tflite_model)

print('Saved pruned TFLite model to:', pruned_tflite_file)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
INFO:tensorflow:Assets written to: /tmp/tmpunez1uhy/assets
Saved pruned TFLite model to: /tmp/tmp9oa2swr6.tflite

Definieren Sie eine Hilfsfunktion, um die Modelle tatsächlich über gzip zu komprimieren und die Größe des Reißverschlusses zu messen.

def get_gzipped_model_size(file):
  # Returns size of gzipped model, in bytes.
  import os
  import zipfile

  _, zipped_file = tempfile.mkstemp('.zip')
  with zipfile.ZipFile(zipped_file, 'w', compression=zipfile.ZIP_DEFLATED) as f:
    f.write(file)

  return os.path.getsize(zipped_file)

Vergleichen Sie und sehen Sie, dass die Modelle vom Beschneiden 3x kleiner sind.

print("Size of gzipped baseline Keras model: %.2f bytes" % (get_gzipped_model_size(keras_file)))
print("Size of gzipped pruned Keras model: %.2f bytes" % (get_gzipped_model_size(pruned_keras_file)))
print("Size of gzipped pruned TFlite model: %.2f bytes" % (get_gzipped_model_size(pruned_tflite_file)))
Size of gzipped baseline Keras model: 78048.00 bytes
Size of gzipped pruned Keras model: 25680.00 bytes
Size of gzipped pruned TFlite model: 24946.00 bytes

Erstellen Sie ein 10x kleineres Modell aus der Kombination von Beschneiden und Quantisieren

Sie können die Quantisierung nach dem Training auf das beschnittene Modell anwenden, um zusätzliche Vorteile zu erzielen.

converter = tf.lite.TFLiteConverter.from_keras_model(model_for_export)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
quantized_and_pruned_tflite_model = converter.convert()

_, quantized_and_pruned_tflite_file = tempfile.mkstemp('.tflite')

with open(quantized_and_pruned_tflite_file, 'wb') as f:
  f.write(quantized_and_pruned_tflite_model)

print('Saved quantized and pruned TFLite model to:', quantized_and_pruned_tflite_file)

print("Size of gzipped baseline Keras model: %.2f bytes" % (get_gzipped_model_size(keras_file)))
print("Size of gzipped pruned and quantized TFlite model: %.2f bytes" % (get_gzipped_model_size(quantized_and_pruned_tflite_file)))
INFO:tensorflow:Assets written to: /tmp/tmpf68nyuwr/assets

INFO:tensorflow:Assets written to: /tmp/tmpf68nyuwr/assets

Saved quantized and pruned TFLite model to: /tmp/tmp85dhxupl.tflite
Size of gzipped baseline Keras model: 78048.00 bytes
Size of gzipped pruned and quantized TFlite model: 7663.00 bytes

Siehe Beständigkeit der Genauigkeit von TF bis TFLite

Definieren Sie eine Hilfsfunktion, um das TF Lite-Modell im Testdatensatz auszuwerten.

import numpy as np

def evaluate_model(interpreter):
  input_index = interpreter.get_input_details()[0]["index"]
  output_index = interpreter.get_output_details()[0]["index"]

  # Run predictions on ever y image in the "test" dataset.
  prediction_digits = []
  for i, test_image in enumerate(test_images):
    if i % 1000 == 0:
      print('Evaluated on {n} results so far.'.format(n=i))
    # Pre-processing: add batch dimension and convert to float32 to match with
    # the model's input data format.
    test_image = np.expand_dims(test_image, axis=0).astype(np.float32)
    interpreter.set_tensor(input_index, test_image)

    # Run inference.
    interpreter.invoke()

    # Post-processing: remove batch dimension and find the digit with highest
    # probability.
    output = interpreter.tensor(output_index)
    digit = np.argmax(output()[0])
    prediction_digits.append(digit)

  print('\n')
  # Compare prediction results with ground truth labels to calculate accuracy.
  prediction_digits = np.array(prediction_digits)
  accuracy = (prediction_digits == test_labels).mean()
  return accuracy

Sie bewerten das beschnittene und quantisierte Modell und stellen fest, dass die Genauigkeit von TensorFlow für das TFLite-Backend erhalten bleibt.

interpreter = tf.lite.Interpreter(model_content=quantized_and_pruned_tflite_model)
interpreter.allocate_tensors()

test_accuracy = evaluate_model(interpreter)

print('Pruned and quantized TFLite test_accuracy:', test_accuracy)
print('Pruned TF test accuracy:', model_for_pruning_accuracy)
Evaluated on 0 results so far.
Evaluated on 1000 results so far.
Evaluated on 2000 results so far.
Evaluated on 3000 results so far.
Evaluated on 4000 results so far.
Evaluated on 5000 results so far.
Evaluated on 6000 results so far.
Evaluated on 7000 results so far.
Evaluated on 8000 results so far.
Evaluated on 9000 results so far.


Pruned and quantized TFLite test_accuracy: 0.9692
Pruned TF test accuracy: 0.9689000248908997

Fazit

In diesem Tutorial haben Sie gesehen, wie Sie mit der TensorFlow Model Optimization Toolkit-API für TensorFlow und TFLite spärliche Modelle erstellen. Anschließend haben Sie das Beschneiden mit der Quantisierung nach dem Training kombiniert, um zusätzliche Vorteile zu erzielen.

Sie haben ein 10x kleineres Modell für MNIST mit minimalem Genauigkeitsunterschied erstellt.

Wir empfehlen Ihnen, diese neue Funktion auszuprobieren, die für die Bereitstellung in Umgebungen mit eingeschränkten Ressourcen besonders wichtig sein kann.