このページは Cloud Translation API によって翻訳されました。
Switch to English

Kerasの例における重みのクラスタリング

TensorFlow.orgで見る Google Colabで実行 GitHubでソースを表示する ノートブックをダウンロード

概観

TensorFlowモデル最適化ツールキットの一部である重みクラスタリングのエンドツーエンドの例へようこそ。

他のページ

重みクラスタリングの概要と 、それを使用する必要があるかどうか(サポートされているものを含む)を判断するには、 概要ページを参照してください

ユースケースに必要なAPIをすばやく見つけるには(16クラスターのモデルを完全にクラスター化する以外に)、 包括的なガイドを参照してください

目次

チュートリアルでは、次のことを行います。

  1. MNISTデータセットのtf.kerasモデルを最初からトレーニングします。
  2. 重みクラスタリングAPIを適用してモデルを微調整し、精度を確認します。
  3. クラスタリングから6倍のTFおよびTFLiteモデルを作成します。
  4. 重みのクラスタリングとトレーニング後の量子化を組み合わせて、8倍のTFLiteモデルを作成します。
  5. TFからTFLiteまでの精度の持続性を確認してください。

セットアップ

このJupyter Notebookは、ローカルのvirtualenvまたはcolabで実行できます。依存関係の設定の詳細については、 インストールガイドを参照してください

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

import numpy as np
import tempfile
import zipfile
import os
 

クラスタリングなしでMNISTのtf.kerasモデルをトレーニングする

 # 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=tf.nn.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,
    validation_split=0.1,
    epochs=10
)
 
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step
Epoch 1/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.3352 - accuracy: 0.9039 - val_loss: 0.1543 - val_accuracy: 0.9575
Epoch 2/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.1535 - accuracy: 0.9559 - val_loss: 0.0948 - val_accuracy: 0.9745
Epoch 3/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.1003 - accuracy: 0.9715 - val_loss: 0.0750 - val_accuracy: 0.9788
Epoch 4/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0791 - accuracy: 0.9768 - val_loss: 0.0652 - val_accuracy: 0.9828
Epoch 5/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0669 - accuracy: 0.9803 - val_loss: 0.0663 - val_accuracy: 0.9807
Epoch 6/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0589 - accuracy: 0.9820 - val_loss: 0.0581 - val_accuracy: 0.9833
Epoch 7/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0528 - accuracy: 0.9840 - val_loss: 0.0584 - val_accuracy: 0.9832
Epoch 8/10
1688/1688 [==============================] - 8s 5ms/step - loss: 0.0479 - accuracy: 0.9854 - val_loss: 0.0560 - val_accuracy: 0.9838
Epoch 9/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0434 - accuracy: 0.9867 - val_loss: 0.0550 - val_accuracy: 0.9853
Epoch 10/10
1688/1688 [==============================] - 7s 4ms/step - loss: 0.0393 - accuracy: 0.9880 - val_loss: 0.0571 - val_accuracy: 0.9845

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

ベースラインモデルを評価し、後で使用するために保存する

 _, 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.9805999994277954
Saving model to:  /tmp/tmpphs68ctq.h5

クラスタリングで事前学習済みモデルを微調整する

事前にトレーニングされたモデル全体にcluster_weights() APIを適用して、適切な精度を維持しながらzipを適用した後のモデルサイズを縮小する効果を実証します。ユースケースの精度と圧縮率の最適なバランスをとる方法については、 包括的なガイドのレイヤーごとの例を参照してください。

モデルを定義し、クラスタリングAPIを適用する

モデルをクラスタリングAPIに渡す前に、モデルがトレーニングされており、ある程度の許容可能な精度を示していることを確認してください。

 import tensorflow_model_optimization as tfmot

cluster_weights = tfmot.clustering.keras.cluster_weights
CentroidInitialization = tfmot.clustering.keras.CentroidInitialization

clustering_params = {
  'number_of_clusters': 16,
  'cluster_centroids_init': CentroidInitialization.LINEAR
}

# Cluster a whole model
clustered_model = cluster_weights(model, **clustering_params)

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

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

clustered_model.summary()
 
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_reshape (ClusterWeig (None, 28, 28, 1)         0         
_________________________________________________________________
cluster_conv2d (ClusterWeigh (None, 26, 26, 12)        136       
_________________________________________________________________
cluster_max_pooling2d (Clust (None, 13, 13, 12)        0         
_________________________________________________________________
cluster_flatten (ClusterWeig (None, 2028)              0         
_________________________________________________________________
cluster_dense (ClusterWeight (None, 10)                20306     
=================================================================
Total params: 20,442
Trainable params: 54
Non-trainable params: 20,388
_________________________________________________________________

モデルを微調整し、ベースラインに対して精度を評価する

1エポックのクラスタリングでモデルを微調整します。

 # Fine-tune model
clustered_model.fit(
  train_images,
  train_labels,
  batch_size=500,
  epochs=1,
  validation_split=0.1)
 
108/108 [==============================] - 2s 16ms/step - loss: 0.0535 - accuracy: 0.9821 - val_loss: 0.0692 - val_accuracy: 0.9803

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

この例では、ベースラインと比較して、クラスタリング後のテスト精度の損失は最小限です。

 _, clustered_model_accuracy = clustered_model.evaluate(
  test_images, test_labels, verbose=0)

print('Baseline test accuracy:', baseline_model_accuracy)
print('Clustered test accuracy:', clustered_model_accuracy)
 
Baseline test accuracy: 0.9805999994277954
Clustered test accuracy: 0.9753000140190125

クラスタリングから6倍の小さいモデルを作成する

クラスタリングの圧縮の利点を確認するには、 strip_clusteringと標準の圧縮アルゴリズム(gzipなど)の適用の両方が必要です。

まず、TensorFlowの圧縮可能なモデルを作成します。ここで、 strip_clustering (例えば、すべての変数削除tf.Variableクラスタリングだけそう推論中にモデルのサイズに追加する訓練、中に必要であることをクラスタ重心とインデックスを格納するため)。

 final_model = tfmot.clustering.keras.strip_clustering(clustered_model)

_, clustered_keras_file = tempfile.mkstemp('.h5')
print('Saving clustered model to: ', clustered_keras_file)
tf.keras.models.save_model(final_model, clustered_keras_file, 
                           include_optimizer=False)
 
Saving clustered model to:  /tmp/tmpfnmtfvf8.h5

次に、TFLiteの圧縮可能なモデルを作成します。クラスターモデルを、対象のバックエンドで実行可能な形式に変換できます。 TensorFlow Liteは、モバイルデバイスへのデプロイに使用できる例です。

 clustered_tflite_file = '/tmp/clustered_mnist.tflite'
converter = tf.lite.TFLiteConverter.from_keras_model(final_model)
tflite_clustered_model = converter.convert()
with open(clustered_tflite_file, 'wb') as f:
  f.write(tflite_clustered_model)
print('Saved clustered TFLite model to:', clustered_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/tmpe966h_56/assets
Saved clustered TFLite model to: /tmp/clustered_mnist.tflite

gzipを介してモデルを実際に圧縮し、zipしたサイズを測定するヘルパー関数を定義します。

 def get_gzipped_model_size(file):
  # It returns the size of the 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)
 

比較して、モデルがクラスタリングよりも6倍小さいことを確認します

 print("Size of gzipped baseline Keras model: %.2f bytes" % (get_gzipped_model_size(keras_file)))
print("Size of gzipped clustered Keras model: %.2f bytes" % (get_gzipped_model_size(clustered_keras_file)))
print("Size of gzipped clustered TFlite model: %.2f bytes" % (get_gzipped_model_size(clustered_tflite_file)))
 
Size of gzipped baseline Keras model: 78076.00 bytes
Size of gzipped clustered Keras model: 13362.00 bytes
Size of gzipped clustered TFlite model: 12982.00 bytes

重みのクラスタリングとトレーニング後の量子化を組み合わせて、 8倍の TFLiteモデルを作成します

追加の利点を得るために、トレーニング後の量子化をクラスターモデルに適用できます。

 converter = tf.lite.TFLiteConverter.from_keras_model(final_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_quant_model = converter.convert()

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

with open(quantized_and_clustered_tflite_file, 'wb') as f:
  f.write(tflite_quant_model)

print('Saved quantized and clustered TFLite model to:', quantized_and_clustered_tflite_file)
print("Size of gzipped baseline Keras model: %.2f bytes" % (get_gzipped_model_size(keras_file)))
print("Size of gzipped clustered and quantized TFlite model: %.2f bytes" % (get_gzipped_model_size(quantized_and_clustered_tflite_file)))
 
INFO:tensorflow:Assets written to: /tmp/tmpg0gw8r5x/assets

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

Saved quantized and clustered TFLite model to: /tmp/tmp43crqft1.tflite
Size of gzipped baseline Keras model: 78076.00 bytes
Size of gzipped clustered and quantized TFlite model: 9830.00 bytes

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('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
 

クラスタ化および量子化されたモデルを評価し、TensorFlowからTFLiteバックエンドまで持続する精度を確認します。

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

test_accuracy = eval_model(interpreter)

print('Clustered and quantized TFLite test_accuracy:', test_accuracy)
print('Clustered TF test accuracy:', clustered_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.


Clustered and quantized TFLite test_accuracy: 0.975
Clustered TF test accuracy: 0.9753000140190125

結論

このチュートリアルでは、TensorFlow Model Optimization Toolkit APIを使用してクラスターモデルを作成する方法を確認しました。より具体的には、精度の違いを最小限に抑えてMNISTの8倍小さいモデルを作成するためのエンドツーエンドの例を確認しました。この新しい機能を試すことをお勧めします。これは、リソースに制約のある環境での展開に特に重要な場合があります。