Google I/O สำเร็จแล้ว! ติดตามเซสชัน TensorFlow ดูเซสชัน

คู่มือรวมการจัดกลุ่มน้ำหนัก

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

ยินดีต้อนรับสู่คู่มือที่ครอบคลุมสำหรับการจัดกลุ่มน้ำหนักส่วนหนึ่งของชุดเครื่องมือ TensorFlow รุ่นเพิ่มประสิทธิภาพ

หน้านี้จัดทำเอกสารกรณีการใช้งานต่างๆ และแสดงวิธีใช้ API สำหรับแต่ละกรณี เมื่อคุณทราบว่า API ที่คุณต้องการหาพารามิเตอร์และรายละเอียดในระดับต่ำใน เอกสาร API :

ในคู่มือนี้ จะครอบคลุมกรณีการใช้งานต่อไปนี้:

  • กำหนดโมเดลคลัสเตอร์
  • ตรวจสอบและดีซีเรียลไลซ์โมเดลคลัสเตอร์
  • ปรับปรุงความแม่นยำของโมเดลคลัสเตอร์
  • สำหรับการปรับใช้เท่านั้น คุณต้องทำตามขั้นตอนเพื่อดูประโยชน์ของการบีบอัด

ติดตั้ง

! pip install -q tensorflow-model-optimization

import tensorflow as tf
import numpy as np
import tempfile
import os
import tensorflow_model_optimization as tfmot

input_dim = 20
output_dim = 20
x_train = np.random.randn(1, input_dim).astype(np.float32)
y_train = tf.keras.utils.to_categorical(np.random.randn(1), num_classes=output_dim)

def setup_model():
  model = tf.keras.Sequential([
      tf.keras.layers.Dense(input_dim, input_shape=[input_dim]),
      tf.keras.layers.Flatten()
  ])
  return model

def train_model(model):
  model.compile(
      loss=tf.keras.losses.categorical_crossentropy,
      optimizer='adam',
      metrics=['accuracy']
  )
  model.summary()
  model.fit(x_train, y_train)
  return model

def save_model_weights(model):
  _, pretrained_weights = tempfile.mkstemp('.h5')
  model.save_weights(pretrained_weights)
  return pretrained_weights

def setup_pretrained_weights():
  model= setup_model()
  model = train_model(model)
  pretrained_weights = save_model_weights(model)
  return pretrained_weights

def setup_pretrained_model():
  model = setup_model()
  pretrained_weights = setup_pretrained_weights()
  model.load_weights(pretrained_weights)
  return model

def save_model_file(model):
  _, keras_file = tempfile.mkstemp('.h5') 
  model.save(keras_file, include_optimizer=False)
  return keras_file

def get_gzipped_model_size(model):
  # It returns the size of the gzipped model in bytes.
  import os
  import zipfile

  keras_file = save_model_file(model)

  _, zipped_file = tempfile.mkstemp('.zip')
  with zipfile.ZipFile(zipped_file, 'w', compression=zipfile.ZIP_DEFLATED) as f:
    f.write(keras_file)
  return os.path.getsize(zipped_file)

setup_model()
pretrained_weights = setup_pretrained_weights()
2021-08-31 11:04:26.070553: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected

กำหนดแบบจำลองคลัสเตอร์

จัดกลุ่มทั้งโมเดล (ตามลำดับและใช้งานได้)

เคล็ดลับเพื่อความถูกต้องรูปแบบที่ดีกว่า:

  • คุณต้องผ่านโมเดลที่ได้รับการฝึกอบรมล่วงหน้าซึ่งมีความแม่นยำที่ยอมรับได้ไปยัง API นี้ โมเดลการฝึกอบรมตั้งแต่เริ่มต้นพร้อมการจัดกลุ่มส่งผลให้มีความแม่นยำต่ำกว่ามาตรฐาน
  • ในบางกรณี การจัดกลุ่มเลเยอร์บางชั้นมีผลเสียต่อความแม่นยำของแบบจำลอง ตรวจสอบ "คลัสเตอร์บางเลเยอร์" เพื่อดูวิธีข้ามการจัดกลุ่มเลเยอร์ที่ส่งผลต่อความแม่นยำมากที่สุด

คลัสเตอร์ทุกชั้นใช้ tfmot.clustering.keras.cluster_weights โมเดล

import tensorflow_model_optimization as tfmot

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

clustering_params = {
  'number_of_clusters': 3,
  'cluster_centroids_init': CentroidInitialization.KMEANS_PLUS_PLUS
}

model = setup_model()
model.load_weights(pretrained_weights)

clustered_model = cluster_weights(model, **clustering_params)

clustered_model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_2 (ClusterWeig (None, 20)                823       
_________________________________________________________________
cluster_flatten_2 (ClusterWe (None, 20)                0         
=================================================================
Total params: 823
Trainable params: 423
Non-trainable params: 400
_________________________________________________________________

จัดคลัสเตอร์บางเลเยอร์ (โมเดลตามลำดับและใช้งานได้)

เคล็ดลับเพื่อความถูกต้องรูปแบบที่ดีกว่า:

  • คุณต้องผ่านโมเดลที่ได้รับการฝึกอบรมล่วงหน้าซึ่งมีความแม่นยำที่ยอมรับได้ไปยัง API นี้ โมเดลการฝึกอบรมตั้งแต่เริ่มต้นพร้อมการจัดกลุ่มส่งผลให้มีความแม่นยำต่ำกว่ามาตรฐาน
  • Cluster ชั้นในภายหลังด้วยพารามิเตอร์ซ้ำซ้อนมากขึ้น (เช่น tf.keras.layers.Dense , tf.keras.layers.Conv2D ) เมื่อเทียบกับชั้นต้น
  • ตรึงเลเยอร์แรกๆ ก่อนเลเยอร์ที่คลัสเตอร์ระหว่างการปรับแบบละเอียด ปฏิบัติต่อจำนวนชั้นที่แช่แข็งเป็นไฮเปอร์พารามิเตอร์ สังเกตได้จากการแช่แข็งเลเยอร์แรกเริ่มส่วนใหญ่เหมาะสำหรับ API การทำคลัสเตอร์ปัจจุบัน
  • หลีกเลี่ยงการจัดกลุ่มเลเยอร์ที่สำคัญ (เช่น กลไกการเอาใจใส่)

เพิ่มเติมที่: tfmot.clustering.keras.cluster_weights เอกสาร API ให้รายละเอียดเกี่ยวกับวิธีการที่แตกต่างกันการกำหนดค่าการจัดกลุ่มต่อชั้น

# Create a base model
base_model = setup_model()
base_model.load_weights(pretrained_weights)

# Helper function uses `cluster_weights` to make only 
# the Dense layers train with clustering
def apply_clustering_to_dense(layer):
  if isinstance(layer, tf.keras.layers.Dense):
    return cluster_weights(layer, **clustering_params)
  return layer

# Use `tf.keras.models.clone_model` to apply `apply_clustering_to_dense` 
# to the layers of the model.
clustered_model = tf.keras.models.clone_model(
    base_model,
    clone_function=apply_clustering_to_dense,
)

clustered_model.summary()
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_3 (ClusterWeig (None, 20)                823       
_________________________________________________________________
flatten_3 (Flatten)          (None, 20)                0         
=================================================================
Total params: 823
Trainable params: 423
Non-trainable params: 400
_________________________________________________________________

คลัสเตอร์เลเยอร์ Keras แบบกำหนดเองหรือระบุน้ำหนักของเลเยอร์ที่จะคลัสเตอร์

tfmot.clustering.keras.ClusterableLayer ทำหน้าที่สองกรณีการใช้งาน:

  1. จัดกลุ่มเลเยอร์ใดๆ ที่ไม่ได้รับการสนับสนุนโดยกำเนิด รวมถึงเลเยอร์ Keras ที่กำหนดเอง
  2. ระบุน้ำหนักของเลเยอร์ที่รองรับที่จะทำคลัสเตอร์

ตัวอย่างเช่นค่าเริ่มต้น API เพื่อการจัดกลุ่มเพียงเคอร์เนลของ Dense ชั้น ตัวอย่างด้านล่างแสดงวิธีการแก้ไขเพื่อจัดกลุ่มอคติด้วย ทราบว่าเมื่อมาจากชั้น keras คุณต้องแทนที่ฟังก์ชัน get_clusterable_weights ที่คุณระบุชื่อของตัวแปรสุวินัยที่จะคลัสเตอร์และตัวแปรสุวินัยตัวเอง ตัวอย่างเช่น หากคุณส่งคืนรายการว่าง [] จะไม่มีการจัดกลุ่มน้ำหนักใดๆ

ข้อผิดพลาดทั่วไป: การจัดกลุ่มอคติมักจะเป็นอันตรายต่อความถูกต้องของรูปแบบมากเกินไป

class MyDenseLayer(tf.keras.layers.Dense, tfmot.clustering.keras.ClusterableLayer):

  def get_clusterable_weights(self):
   # Cluster kernel and bias. This is just an example, clustering
   # bias usually hurts model accuracy.
   return [('kernel', self.kernel), ('bias', self.bias)]

# Use `cluster_weights` to make the `MyDenseLayer` layer train with clustering as usual.
model_for_clustering = tf.keras.Sequential([
  tfmot.clustering.keras.cluster_weights(MyDenseLayer(20, input_shape=[input_dim]), **clustering_params),
  tf.keras.layers.Flatten()
])

model_for_clustering.summary()
Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_my_dense_layer (Clus (None, 20)                846       
_________________________________________________________________
flatten_4 (Flatten)          (None, 20)                0         
=================================================================
Total params: 846
Trainable params: 426
Non-trainable params: 420
_________________________________________________________________

นอกจากนี้คุณยังอาจจะใช้ tfmot.clustering.keras.ClusterableLayer คลัสเตอร์ชั้น keras ที่กำหนดเอง การทำเช่นนี้คุณขยาย tf.keras.Layer ตามปกติและใช้ __init__ , call และ build ฟังก์ชั่น แต่คุณยังต้องการที่จะขยาย clusterable_layer.ClusterableLayer ระดับและดำเนินการ:

  1. get_clusterable_weights ที่คุณระบุเคอร์เนลน้ำหนักที่จะคลัสเตอร์ที่แสดงข้างต้น
  2. get_clusterable_algorithm ที่คุณระบุขั้นตอนวิธีการจัดกลุ่มสำหรับเมตริกซ์น้ำหนัก เนื่องจากคุณต้องระบุวิธีการกำหนดน้ำหนักของเลเยอร์ที่กำหนดเองสำหรับการจัดกลุ่ม กลับมาจัดกลุ่มระดับขั้นตอนวิธีการที่ควรจะมาจาก clustering_algorithm.ClusteringAlgorithm ชั้นเรียนและฟังก์ชั่น get_pulling_indices ควรจะถูกเขียนทับ ตัวอย่างของฟังก์ชั่นนี้ซึ่งรองรับน้ำหนักของการจัดอันดับ 1D, 2D, 3D และสามารถพบได้ ที่นี่

ตัวอย่างของการใช้กรณีนี้สามารถพบได้ ที่นี่

ตรวจสอบและดีซีเรียลไลซ์โมเดลคลัสเตอร์

กรณีการใช้งานของคุณ: รหัสนี้เป็นสิ่งจำเป็นสำหรับรูปแบบรูปแบบ HDF5 (ไม่ใช่ HDF5 น้ำหนักหรือรูปแบบอื่น ๆ )

# Define the model.
base_model = setup_model()
base_model.load_weights(pretrained_weights)
clustered_model = cluster_weights(base_model, **clustering_params)

# Save or checkpoint the model.
_, keras_model_file = tempfile.mkstemp('.h5')
clustered_model.save(keras_model_file, include_optimizer=True)

# `cluster_scope` is needed for deserializing HDF5 models.
with tfmot.clustering.keras.cluster_scope():
  loaded_model = tf.keras.models.load_model(keras_model_file)

loaded_model.summary()
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:No training configuration found in the save file, so the model was *not* compiled. Compile it manually.
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
cluster_dense_4 (ClusterWeig (None, 20)                823       
_________________________________________________________________
cluster_flatten_5 (ClusterWe (None, 20)                0         
=================================================================
Total params: 823
Trainable params: 423
Non-trainable params: 400
_________________________________________________________________

ปรับปรุงความแม่นยำของโมเดลคลัสเตอร์

สำหรับกรณีการใช้งานเฉพาะของคุณ มีเคล็ดลับที่คุณสามารถพิจารณาได้:

  • การเริ่มต้น Centroid มีบทบาทสำคัญในความแม่นยำของแบบจำลองที่ปรับให้เหมาะสมขั้นสุดท้าย โดยทั่วไป การกำหนดค่าเริ่มต้น kmeans++ มีประสิทธิภาพดีกว่าการกำหนดค่าเริ่มต้นแบบเชิงเส้น ความหนาแน่น และแบบสุ่ม เมื่อไม่ได้ใช้ kmeans++ การเริ่มต้นเชิงเส้นมักจะมีประสิทธิภาพเหนือกว่าความหนาแน่นและการเริ่มต้นแบบสุ่ม เนื่องจากจะไม่พลาดน้ำหนักที่มาก อย่างไรก็ตาม การเริ่มต้นความหนาแน่นได้รับการสังเกตเพื่อให้มีความแม่นยำที่ดีขึ้นสำหรับกรณีของการใช้คลัสเตอร์น้อยมากกับตุ้มน้ำหนักที่มีการแจกแจงแบบไบโมดอล

  • กำหนดอัตราการเรียนรู้ที่ต่ำกว่าที่ใช้ในการฝึกอบรมเมื่อปรับแต่งโมเดลคลัสเตอร์อย่างละเอียด

  • สำหรับแนวคิดทั่วไปในการปรับปรุงความแม่นยำของแบบจำลอง ให้ค้นหาเคล็ดลับสำหรับกรณีการใช้งานของคุณภายใต้ "กำหนดแบบจำลองคลัสเตอร์"

การปรับใช้

ส่งออกโมเดลด้วยการบีบอัดขนาด

ความผิดพลาดที่พบบ่อยทั้ง strip_clustering และใช้วิธีการบีบอัดมาตรฐาน (เช่นผ่าน gzip) มีความจำเป็นที่จะต้องเห็นประโยชน์ของการบีบอัดการจัดกลุ่ม

model = setup_model()
clustered_model = cluster_weights(model, **clustering_params)

clustered_model.compile(
    loss=tf.keras.losses.categorical_crossentropy,
    optimizer='adam',
    metrics=['accuracy']
)

clustered_model.fit(
    x_train,
    y_train
)

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

print("final model")
final_model.summary()

print("\n")
print("Size of gzipped clustered model without stripping: %.2f bytes" 
      % (get_gzipped_model_size(clustered_model)))
print("Size of gzipped clustered model with stripping: %.2f bytes" 
      % (get_gzipped_model_size(final_model)))
1/1 [==============================] - 0s 343ms/step - loss: 16.1181 - accuracy: 0.0000e+00
final model
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 20)                420       
_________________________________________________________________
flatten_6 (Flatten)          (None, 20)                0         
=================================================================
Total params: 420
Trainable params: 420
Non-trainable params: 0
_________________________________________________________________


Size of gzipped clustered model without stripping: 3447.00 bytes
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.
Size of gzipped clustered model with stripping: 1433.00 bytes