روز جامعه ML 9 نوامبر است! برای به روز رسانی از TensorFlow، JAX به ما بپیوندید، و بیشتر بیشتر بدانید

هرس حفظ آموزش آگاهی از میزان (PQAT) مثال Keras

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده در GitHub دانلود دفترچه یادداشت

بررسی اجمالی

این پایان دادن به عنوان مثال پایان نشان دادن استفاده از حفظ تدریج آموزش آگاه (PQAT) API هرس، بخشی از خط لوله بهینه سازی مشارکتی TensorFlow مدل بهینه سازی جعبه ابزار است.

صفحات دیگر

برای معرفی به خط لوله و دیگر تکنیک های موجود، مشاهده صفحه مرور کلی بهینه سازی مشترک .

فهرست

در آموزش ، شما موارد زیر را انجام می دهید:

  1. آموزش tf.keras مدل برای مجموعه داده MNIST از ابتدا.
  2. مدل را با هرس ، با استفاده از API پراکنده ، دقیق تنظیم کرده و دقت آن را ببینید.
  3. QAT را اعمال کنید و از بین رفتن پراکنده بودن را مشاهده کنید.
  4. PQAT را اعمال کنید و مشاهده کنید که کمیابی که قبلاً اعمال شده بود حفظ شده است.
  5. یک مدل TFLite ایجاد کنید و اثرات استفاده از PQAT را روی آن مشاهده کنید.
  6. دقت مدل PQAT بدست آمده را با مدلی که با استفاده از کوانتیزاسیون پس از آموزش کوانتیزه شده است ، مقایسه کنید.

برپایی

شما می توانید این Jupyter نوت بوک در محلی خود را اجرا از virtualenv یا COLAB . برای جزئیات راه اندازی وابستگی، لطفا به مراجعه راهنمای نصب و راه اندازی .

 pip install -q tensorflow-model-optimization
import tensorflow as tf

import numpy as np
import tempfile
import zipfile
import os

آموزش مدل tf.keras برای MNIST بدون هرس

# Load MNIST dataset
mnist = tf.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

model = tf.keras.Sequential([
  tf.keras.layers.InputLayer(input_shape=(28, 28)),
  tf.keras.layers.Reshape(target_shape=(28, 28, 1)),
  tf.keras.layers.Conv2D(filters=12, kernel_size=(3, 3),
                         activation=tf.nn.relu),
  tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
  tf.keras.layers.Flatten(),
  tf.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,
    validation_split=0.1,
    epochs=10
)
Epoch 1/10
1688/1688 [==============================] - 8s 4ms/step - loss: 0.2940 - accuracy: 0.9172 - val_loss: 0.1183 - val_accuracy: 0.9693
Epoch 2/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.1150 - accuracy: 0.9674 - val_loss: 0.0863 - val_accuracy: 0.9770
Epoch 3/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0821 - accuracy: 0.9760 - val_loss: 0.0738 - val_accuracy: 0.9797
Epoch 4/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0673 - accuracy: 0.9806 - val_loss: 0.0661 - val_accuracy: 0.9837
Epoch 5/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0583 - accuracy: 0.9826 - val_loss: 0.0632 - val_accuracy: 0.9835
Epoch 6/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0520 - accuracy: 0.9845 - val_loss: 0.0635 - val_accuracy: 0.9820
Epoch 7/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0460 - accuracy: 0.9857 - val_loss: 0.0746 - val_accuracy: 0.9815
Epoch 8/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0423 - accuracy: 0.9875 - val_loss: 0.0601 - val_accuracy: 0.9848
Epoch 9/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0384 - accuracy: 0.9885 - val_loss: 0.0604 - val_accuracy: 0.9855
Epoch 10/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0347 - accuracy: 0.9894 - val_loss: 0.0648 - val_accuracy: 0.9835
<tensorflow.python.keras.callbacks.History at 0x7fb08657b5d0>

مدل پایه را ارزیابی کرده و برای استفاده بعدی ذخیره کنید

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

print('Baseline test accuracy:', baseline_model_accuracy)

_, keras_file = tempfile.mkstemp('.h5')
print('Saving model to: ', keras_file)
tf.keras.models.save_model(model, keras_file, include_optimizer=False)
Baseline test accuracy: 0.9810000061988831
Saving model to:  /tmp/tmp0akp2126.h5

مدل را هرس کرده و با دقت 50 درصد پراکنده کنید

درخواست prune_low_magnitude() API برای هرس کردن تمام مدل های از پیش آموزش دیده برای نشان دادن و مشاهده اثر آن در کاهش اندازه مدل در هنگام استفاده از فایل های فشرده، در حالی که حفظ دقت و صحت. برای اینکه چگونه به بهترین استفاده از API برای رسیدن به بهترین میزان فشرده سازی در حالی که حفظ دقت و صحت هدف خود را، به مراجعه راهنمای جامع هرس .

مدل را تعریف کرده و API sparsity را اعمال کنید

مدل قبل از استفاده از API sparsity نیاز به آموزش قبلی دارد.

import tensorflow_model_optimization as tfmot

prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude

pruning_params = {
      'pruning_schedule': tfmot.sparsity.keras.ConstantSparsity(0.5, begin_step=0, frequency=100)
  }

callbacks = [
  tfmot.sparsity.keras.UpdatePruningStep()
]

pruned_model = prune_low_magnitude(model, **pruning_params)

# Use smaller learning rate for fine-tuning
opt = tf.keras.optimizers.Adam(learning_rate=1e-5)

pruned_model.compile(
  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
  optimizer=opt,
  metrics=['accuracy'])

pruned_model.summary()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py:2191: UserWarning: `layer.add_variable` is deprecated and will be removed in a future version. Please use `layer.add_weight` method instead.
  warnings.warn('`layer.add_variable` is deprecated and '
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
_________________________________________________________________

مدل را دقیق تنظیم کرده و دقت را در برابر خط پایه ارزیابی کنید

مدل را با هرس برای 3 دوره دقیق تنظیم کنید.

# Fine-tune model
pruned_model.fit(
  train_images,
  train_labels,
  epochs=3,
  validation_split=0.1,
  callbacks=callbacks)
Epoch 1/3
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/array_ops.py:5049: calling gather (from tensorflow.python.ops.array_ops) with validate_indices is deprecated and will be removed in a future version.
Instructions for updating:
The `validate_indices` argument has no effect. Indices are always validated on CPU and never validated on GPU.
1688/1688 [==============================] - 9s 5ms/step - loss: 0.1243 - accuracy: 0.9580 - val_loss: 0.1146 - val_accuracy: 0.9650
Epoch 2/3
1688/1688 [==============================] - 8s 4ms/step - loss: 0.0883 - accuracy: 0.9713 - val_loss: 0.0945 - val_accuracy: 0.9720
Epoch 3/3
1688/1688 [==============================] - 8s 4ms/step - loss: 0.0722 - accuracy: 0.9774 - val_loss: 0.0858 - val_accuracy: 0.9753
<tensorflow.python.keras.callbacks.History at 0x7fafb6c80310>

توابع کمکی را برای محاسبه و چاپ پراکندگی مدل تعریف کنید.

def print_model_weights_sparsity(model):

    for layer in model.layers:
        if isinstance(layer, tf.keras.layers.Wrapper):
            weights = layer.trainable_weights
        else:
            weights = layer.weights
        for weight in weights:
            # ignore auxiliary quantization weights
            if "quantize_layer" in weight.name:
                continue
            weight_size = weight.numpy().size
            zero_num = np.count_nonzero(weight == 0)
            print(
                f"{weight.name}: {zero_num/weight_size:.2%} sparsity ",
                f"({zero_num}/{weight_size})",
            )

بررسی کنید که مدل به درستی هرس شده است. ابتدا باید بسته بندی هرس را برداریم.

stripped_pruned_model = tfmot.sparsity.keras.strip_pruning(pruned_model)

print_model_weights_sparsity(stripped_pruned_model)
conv2d/kernel:0: 50.00% sparsity  (54/108)
conv2d/bias:0: 0.00% sparsity  (0/12)
dense/kernel:0: 50.00% sparsity  (10140/20280)
dense/bias:0: 0.00% sparsity  (0/10)

برای این مثال ، در ازای دقت آزمایش پس از هرس ، در مقایسه با خط پایه ، حداقل ضرر وجود دارد.

_, pruned_model_accuracy = pruned_model.evaluate(
  test_images, test_labels, verbose=0)

print('Baseline test accuracy:', baseline_model_accuracy)
print('Pruned test accuracy:', pruned_model_accuracy)
Baseline test accuracy: 0.9810000061988831
Pruned test accuracy: 0.973800003528595

QAT و PQAT را اعمال کنید و در هر دو مورد اثر را روی پراکندگی مدل بررسی کنید

در مرحله بعد ، ما QAT و QAT را برای حفظ هرس (PQAT) در مدل هرس اعمال می کنیم و مشاهده می کنیم که PQAT در مدل هرس شده شما کمیابی را حفظ می کند. توجه داشته باشید که ما لفافه هرس هرس از مدل خود را با تکمیل نشده tfmot.sparsity.keras.strip_pruning قبل از اعمال PQAT API.

# QAT
qat_model = tfmot.quantization.keras.quantize_model(stripped_pruned_model)

qat_model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
print('Train qat model:')
qat_model.fit(train_images, train_labels, batch_size=128, epochs=1, validation_split=0.1)

# PQAT
quant_aware_annotate_model = tfmot.quantization.keras.quantize_annotate_model(
              stripped_pruned_model)
pqat_model = tfmot.quantization.keras.quantize_apply(
              quant_aware_annotate_model,
              tfmot.experimental.combine.Default8BitPrunePreserveQuantizeScheme())

pqat_model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
print('Train pqat model:')
pqat_model.fit(train_images, train_labels, batch_size=128, epochs=1, validation_split=0.1)
Train qat model:
422/422 [==============================] - 4s 8ms/step - loss: 0.0386 - accuracy: 0.9891 - val_loss: 0.0607 - val_accuracy: 0.9832
Train pqat model:
422/422 [==============================] - 4s 8ms/step - loss: 0.0416 - accuracy: 0.9881 - val_loss: 0.0590 - val_accuracy: 0.9832
<tensorflow.python.keras.callbacks.History at 0x7fafb5e48f50>
print("QAT Model sparsity:")
print_model_weights_sparsity(qat_model)
print("PQAT Model sparsity:")
print_model_weights_sparsity(pqat_model)
QAT Model sparsity:
conv2d/bias:0: 0.00% sparsity  (0/12)
conv2d/kernel:0: 6.48% sparsity  (7/108)
dense/bias:0: 0.00% sparsity  (0/10)
dense/kernel:0: 5.67% sparsity  (1149/20280)
PQAT Model sparsity:
conv2d/bias:0: 0.00% sparsity  (0/12)
conv2d/kernel:0: 50.00% sparsity  (54/108)
dense/bias:0: 0.00% sparsity  (0/10)
dense/kernel:0: 50.00% sparsity  (10140/20280)

مزایای فشرده سازی مدل PQAT را مشاهده کنید

تابع کمکی را برای دریافت فایل مدل زیپ شده تعریف کنید.

def get_gzipped_model_size(file):
  # It returns the size of the gzipped model in kilobytes.

  _, 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)/1000

از آنجا که این یک مدل کوچک است ، تفاوت بین دو مدل چندان محسوس نیست. اعمال هرس و PQAT در یک مدل تولید بزرگتر ، فشرده سازی قابل توجهی را به همراه خواهد داشت.

# QAT model
converter = tf.lite.TFLiteConverter.from_keras_model(qat_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
qat_tflite_model = converter.convert()
qat_model_file = 'qat_model.tflite'
# Save the model.
with open(qat_model_file, 'wb') as f:
    f.write(qat_tflite_model)

# PQAT model
converter = tf.lite.TFLiteConverter.from_keras_model(pqat_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
pqat_tflite_model = converter.convert()
pqat_model_file = 'pqat_model.tflite'
# Save the model.
with open(pqat_model_file, 'wb') as f:
    f.write(pqat_tflite_model)

print("QAT model size: ", get_gzipped_model_size(qat_model_file), ' KB')
print("PQAT model size: ", get_gzipped_model_size(pqat_model_file), ' KB')
WARNING:absl:Found untraced functions such as reshape_layer_call_fn, reshape_layer_call_and_return_conditional_losses, conv2d_layer_call_fn, conv2d_layer_call_and_return_conditional_losses, flatten_layer_call_fn while saving (showing 5 of 20). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: /tmp/tmpurndy6nz/assets
INFO:tensorflow:Assets written to: /tmp/tmpurndy6nz/assets
WARNING:absl:Found untraced functions such as reshape_layer_call_fn, reshape_layer_call_and_return_conditional_losses, conv2d_layer_call_fn, conv2d_layer_call_and_return_conditional_losses, flatten_layer_call_fn while saving (showing 5 of 20). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: /tmp/tmpgsy8_zld/assets
INFO:tensorflow:Assets written to: /tmp/tmpgsy8_zld/assets
QAT model size:  16.326  KB
PQAT model size:  14.022  KB

تداوم دقت را از TF به TFLite مشاهده کنید

یک تابع کمکی برای ارزیابی مدل TFLite در مجموعه داده آزمایش تعریف کنید.

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

  # Run predictions on every image in the "test" dataset.
  prediction_digits = []
  for i, test_image in enumerate(test_images):
    if i % 1000 == 0:
      print(f"Evaluated on {i} results so far.")
    # 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

شما مدل را که هرس شده و کمی شده است ، ارزیابی می کنید و سپس می بینید که صحت TensorFlow در باطن TFLite همچنان ادامه دارد.

interpreter = tf.lite.Interpreter(pqat_model_file)
interpreter.allocate_tensors()

pqat_test_accuracy = eval_model(interpreter)

print('Pruned and quantized TFLite test_accuracy:', pqat_test_accuracy)
print('Pruned TF test accuracy:', pruned_model_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.9815
Pruned TF test accuracy: 0.973800003528595

کمی سازی پس از آموزش را اعمال کرده و با مدل PQAT مقایسه کنید

در مرحله بعد ، ما از کوانتیزه معمولی پس از آموزش (بدون تنظیم دقیق) در مدل هرس استفاده می کنیم و صحت آن را در برابر مدل PQAT بررسی می کنیم. این نشان می دهد که چرا شما باید از PQAT برای بهبود دقت مدل کوانتیزه استفاده کنید.

ابتدا ، یک مولد برای مجموعه داده خطاطی از 1000 تصویر آموزشی اولیه تعریف کنید.

def mnist_representative_data_gen():
  for image in train_images[:1000]:  
    image = np.expand_dims(image, axis=0).astype(np.float32)
    yield [image]

مدل را کمی کنید و دقت را با مدل PQAT که قبلاً بدست آورده اید مقایسه کنید. توجه داشته باشید که این مدل با تنظیم دقیق به دقت بالاتری دست می یابد.

converter = tf.lite.TFLiteConverter.from_keras_model(stripped_pruned_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = mnist_representative_data_gen
post_training_tflite_model = converter.convert()
post_training_model_file = 'post_training_model.tflite'
# Save the model.
with open(post_training_model_file, 'wb') as f:
    f.write(post_training_tflite_model)

# Compare accuracy
interpreter = tf.lite.Interpreter(post_training_model_file)
interpreter.allocate_tensors()

post_training_test_accuracy = eval_model(interpreter)

print('PQAT TFLite test_accuracy:', pqat_test_accuracy)
print('Post-training (no fine-tuning) TF test accuracy:', post_training_test_accuracy)
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
INFO:tensorflow:Assets written to: /tmp/tmpk4ymv7ej/assets
INFO:tensorflow:Assets written to: /tmp/tmpk4ymv7ej/assets
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.


PQAT TFLite test_accuracy: 0.9815
Post-training (no fine-tuning) TF test accuracy: 0.9734

نتیجه

در این آموزش ، شما نحوه ایجاد یک مدل ، هرس آن با استفاده از API sparsity و استفاده از آموزش آگاهی بخشی به منظور حفظ پراکنده (PQAT) را برای حفظ کمیابی در حین استفاده از QAT یاد گرفتید. مدل نهایی PQAT با مدل QAT مقایسه شد تا نشان دهد میزان کمی در مدل قبلی حفظ شده و در حالت دوم از بین رفته است. در مرحله بعد ، مدلها به TFLite تبدیل شدند تا مزایای فشرده سازی هرس زنجیره ای و تکنیکهای بهینه سازی مدل PQAT را نشان دهند و مدل TFLite برای اطمینان از صحت در باطن TFLite مورد ارزیابی قرار گرفت. سرانجام ، مدل PQAT با یک مدل هرس شده کمی که با استفاده از API کوانتاسیون پس از آموزش به دست آمد مقایسه شد تا مزیت PQAT را در بازیابی ضایعات دقت از حالت کوانتیزه معمولی نشان دهد.