TensorFlow 2'deki TF Hub'dan SavedModels

TensorFlow 2'nin SavedModel formatı, önceden eğitilmiş modelleri ve model parçalarını TensorFlow Hub'da paylaşmanın önerilen yoludur. Eski TF1 Hub formatının yerini alır ve yeni bir API seti ile birlikte gelir.

Bu sayfada, düşük seviyeli hub.load() API'si ve onun hub.KerasLayer sarmalayıcısıyla bir TensorFlow 2 programında TF2 SavedModels'in nasıl yeniden kullanılacağı açıklanmaktadır. (Genellikle hub.KerasLayer , bir Keras modeli veya TF2 Tahmincisi'nin model_fn oluşturmak için diğer tf.keras.layers ile birleştirilir.) Bu API'ler aynı zamanda eski modelleri TF1 Hub formatında da yükleyebilir; sınırlar dahilinde, uyumluluk kılavuzuna bakın.

TensorFlow 1 kullanıcıları TF 1.15'e güncelleyebilir ve ardından aynı API'leri kullanabilir. TF1'in eski sürümleri çalışmıyor.

TF Hub'dan SavedModels'ı kullanma

Keras'ta SavedModel kullanma

Keras, Keras Layer nesneleri oluşturarak derin öğrenme modelleri oluşturmaya yönelik TensorFlow'un üst düzey API'sidir. tensorflow_hub kitaplığı, bir SavedModel'in URL'si (veya dosya sistemi yolu) ile başlatılan ve ardından önceden eğitilmiş ağırlıkları da dahil olmak üzere SavedModel'den hesaplama sağlayan hub.KerasLayer sınıfını sağlar.

Önceden eğitilmiş bir metin yerleştirmenin kullanımına bir örnek:

import tensorflow as tf
import tensorflow_hub as hub

hub_url = "https://tfhub.dev/google/nnlm-en-dim128/2"
embed = hub.KerasLayer(hub_url)
embeddings = embed(["A long sentence.", "single-word", "http://example.com"])
print(embeddings.shape, embeddings.dtype)

Bundan, her zamanki Keras yöntemiyle bir metin sınıflandırıcı oluşturulabilir:

model = tf.keras.Sequential([
    embed,
    tf.keras.layers.Dense(16, activation="relu"),
    tf.keras.layers.Dense(1, activation="sigmoid"),
])

Metin sınıflandırma ortak çalışması , böyle bir sınıflandırıcının nasıl eğitilip değerlendirileceğine dair eksiksiz bir örnektir.

Bir hub.KerasLayer model ağırlıkları.KerasLayer, varsayılan olarak eğitilemez olarak ayarlanmıştır. Bunu nasıl değiştireceğinizi öğrenmek için aşağıdaki ince ayar bölümüne bakın. Ağırlıklar, Keras'ta her zamanki gibi aynı katman nesnesinin tüm uygulamaları arasında paylaşılır.

Tahmincide SavedModel Kullanma

Dağıtılmış eğitim için TensorFlow'un Estimator API kullanıcıları, model_fn diğer tf.keras.layers yanı sıra hub.KerasLayer cinsinden yazarak TF Hub'dan SavedModels'ı kullanabilirler.

Kamera arkası: SavedModel'i indirme ve önbelleğe alma

TensorFlow Hub'dan (veya barındırma protokolünü uygulayan diğer HTTPS sunucularından) SavedModel'i kullanmak, halihazırda mevcut değilse onu yerel dosya sistemine indirir ve sıkıştırmasını açar. TFHUB_CACHE_DIR ortam değişkeni, indirilen ve sıkıştırılmamış SavedModel'lerin önbelleğe alınması için varsayılan geçici konumu geçersiz kılacak şekilde ayarlanabilir. Ayrıntılar için bkz . Önbelleğe Alma.

Düşük seviyeli TensorFlow'da SavedModel kullanma

Model Kulpları

SavedModels, handle bir dosya sistemi yolu olduğu, geçerli bir TFhub.dev model URL'si (örn. "https://tfhub.dev/...") belirtilen bir handle yüklenebilir. Kaggle Modelleri URL'leri, TFhub.dev'in Şartlarımıza ve model varlıklarla ilişkili lisansa uygun şekilde işlediğini yansıtır, örneğin "https://www.kaggle.com/...". Kaggle Modellerindeki tanıtıcılar, karşılık gelen TFhub.dev tanıtıcısına eşdeğerdir.

hub.load(handle) işlevi bir SavedModel'i indirir ve sıkıştırmasını açar ( handle zaten bir dosya sistemi yolu olmadığı sürece) ve ardından onu TensorFlow'un yerleşik işlevi tf.saved_model.load() ile yüklemenin sonucunu döndürür. Bu nedenle, hub.load() herhangi bir geçerli SavedModel'i işleyebilir (önceki hub.Module for TF1'den farklı olarak).

İleri düzey konu: Yüklemeden sonra SavedModel'den neler beklenmeli?

SavedModel'in içeriğine bağlı olarak, obj = hub.load(...) sonucu çeşitli şekillerde çağrılabilir (TensorFlow'un SavedModel Kılavuzu'nda çok daha ayrıntılı olarak açıklandığı gibi):

  • SavedModel'in hizmet imzaları (varsa) somut işlevler sözlüğü olarak temsil edilir ve tensors_out = obj.signatures["serving_default"](**tensors_in) gibi çağrılabilir, ilgili giriş ve çıkış tarafından anahtarlanan tensör sözlükleri ile adlar ve imzanın şekli ve türü kısıtlamalarına tabidir.

  • Kaydedilen nesnenin (varsa) @tf.function -decoated yöntemleri, kaydetmeden önce tf.function'ın izlendiği Tensor ve Tensor olmayan bağımsız değişkenlerin tüm kombinasyonları tarafından çağrılabilen tf.function nesneleri olarak geri yüklenir. Özellikle, uygun izlere sahip bir obj.__call__ yöntemi varsa, obj kendisi bir Python işlevi gibi çağrılabilir. Basit bir örnek output_tensor = obj(input_tensor, training=False) gibi görünebilir.

Bu, SavedModels'ın uygulayabileceği arayüzlerde muazzam bir özgürlük bırakır. obj için Yeniden Kullanılabilir SavedModels arabirimi, hub.KerasLayer gibi bağdaştırıcılar da dahil olmak üzere istemci kodunun SavedModel'in nasıl kullanılacağını bilmesini sağlayan kurallar oluşturur.

Bazı SavedModel'ler, özellikle daha büyük modellerde yeniden kullanılması amaçlanmayan modellerin tamamı bu kurala uymayabilir ve yalnızca sunum imzaları sağlayabilir.

SavedModel'deki eğitilebilir değişkenler eğitilebilir olarak yeniden yüklenir ve tf.GradientTape bunları varsayılan olarak izleyecektir. Bazı uyarılar için aşağıdaki ince ayar bölümüne bakın ve yeni başlayanlar için bundan kaçınmayı düşünün. İnce ayar yapmak isteseniz bile, obj.trainable_variables başlangıçta eğitilebilir değişkenlerin yalnızca bir alt kümesini yeniden eğitmeyi tavsiye edip etmediğini görmek isteyebilirsiniz.

TF Hub için SavedModels Oluşturma

Genel Bakış

SavedModel, TensorFlow'un eğitilmiş modeller veya model parçaları için standart serileştirme formatıdır. Hesaplamayı gerçekleştirmek için modelin eğitilmiş ağırlıklarını tam TensorFlow işlemleriyle birlikte saklar. Onu oluşturan koddan bağımsız olarak kullanılabilir. Özellikle Keras gibi farklı üst düzey model oluşturma API'lerinde yeniden kullanılabilir çünkü TensorFlow işlemleri bunların ortak temel dilidir.

Keras'tan kaydetme

TensorFlow 2'den başlayarak, tf.keras.Model.save() ve tf.keras.models.save_model() varsayılan olarak SavedModel formatına (HDF5 değil) sahiptir. Ortaya çıkan ve kullanıma sunuldukça hub.load() , hub.KerasLayer ve diğer yüksek düzey API'ler için benzer adaptörlerle kullanılabilen SavedModels.

Tam bir Keras Modelini paylaşmak için onu include_optimizer=False ile kaydetmeniz yeterlidir.

Bir Keras Modelinin bir parçasını paylaşmak için parçayı kendi içinde bir Model yapın ve ardından kaydedin. Kodu en baştan bu şekilde düzenleyebilirsiniz ....

piece_to_share = tf.keras.Model(...)
full_model = tf.keras.Sequential([piece_to_share, ...])
full_model.fit(...)
piece_to_share.save(...)

...ya da parçayı kestikten sonra paylaşabilirsiniz (eğer tam modelinizin katmanlaması ile uyumluysa):

full_model = tf.keras.Model(...)
sharing_input = full_model.get_layer(...).get_output_at(0)
sharing_output = full_model.get_layer(...).get_output_at(0)
piece_to_share = tf.keras.Model(sharing_input, sharing_output)
piece_to_share.save(..., include_optimizer=False)

GitHub'daki TensorFlow Modelleri, BERT için eski yaklaşımı kullanır (bkz. nlp/tools/export_tfhub_lib.py , dışa aktarma için core_model ile kontrol noktasını geri yüklemek için pretrainer arasındaki ayrıma dikkat edin) ve ResNet için ikinci yaklaşımı kullanır (bkz . eski/image_classification/tfhub_export.py ).

Düşük seviyeli TensorFlow'dan tasarruf etme

Bu, TensorFlow'un SavedModel Kılavuzuna iyi derecede aşina olmayı gerektirir.

Yalnızca bir sunum imzasından fazlasını sağlamak istiyorsanız, Yeniden Kullanılabilir SavedModel arayüzünü uygulamanız gerekir. Kavramsal olarak bu şuna benziyor

class MyMulModel(tf.train.Checkpoint):
  def __init__(self, v_init):
    super().__init__()
    self.v = tf.Variable(v_init)
    self.variables = [self.v]
    self.trainable_variables = [self.v]
    self.regularization_losses = [
        tf.function(input_signature=[])(lambda: 0.001 * self.v**2),
    ]

  @tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.float32)])
  def __call__(self, inputs):
    return tf.multiply(inputs, self.v)

tf.saved_model.save(MyMulModel(2.0), "/tmp/my_mul")

layer = hub.KerasLayer("/tmp/my_mul")
print(layer([10., 20.]))  # [20., 40.]
layer.trainable = True
print(layer.trainable_weights)  # [2.]
print(layer.losses)  # 0.004

İnce ayar

İçe aktarılan bir SavedModel'in önceden eğitilmiş değişkenlerini etrafındaki modelin değişkenleriyle birlikte eğitmeye SavedModel'de ince ayar yapma denir. Bu, daha iyi kaliteyle sonuçlanabilir, ancak genellikle eğitimi daha zorlu hale getirir (daha fazla zaman alabilir, optimize ediciye ve onun hiperparametrelerine daha fazla bağlı olabilir, aşırı uyum riskini artırabilir ve özellikle CNN'ler için veri kümesinin artırılmasını gerektirebilir). SavedModel tüketicilerine yalnızca iyi bir eğitim rejimi oluşturduktan sonra ve yalnızca SavedModel yayıncısının tavsiye etmesi durumunda ince ayar yapmalarını tavsiye ediyoruz.

İnce ayar, eğitilen "sürekli" model parametrelerini değiştirir. Metin girişini simgeleştirmek ve belirteçleri bir gömme matrisindeki karşılık gelen girişlerle eşlemek gibi sabit kodlanmış dönüşümleri değiştirmez.

SavedModel tüketicileri için

Bir hub.KerasLayer benzeri oluşturma

layer = hub.KerasLayer(..., trainable=True)

katman tarafından yüklenen SavedModel'de ince ayar yapılmasını sağlar. SavedModel'de bildirilen eğitilebilir ağırlıkları ve ağırlık düzenleyicileri Keras modeline ekler ve SavedModel'in hesaplamasını eğitim modunda çalıştırır (bırakmayı vb. düşünün).

Görüntü sınıflandırma ortak çalışması, isteğe bağlı ince ayar içeren uçtan uca bir örnek içerir.

İnce ayar sonucunu yeniden dışa aktarma

İleri düzey kullanıcılar, ince ayarın sonuçlarını, orijinal olarak yüklenen modelin yerine kullanılabilecek bir SavedModel'e geri kaydetmek isteyebilir. Bu gibi kodlarla yapılabilir

loaded_obj = hub.load("https://tfhub.dev/...")
hub_layer = hub.KerasLayer(loaded_obj, trainable=True, ...)

model = keras.Sequential([..., hub_layer, ...])
model.compile(...)
model.fit(...)

export_module_dir = os.path.join(os.getcwd(), "finetuned_model_export")
tf.saved_model.save(loaded_obj, export_module_dir)

SavedModel yaratıcıları için

TensorFlow Hub'da paylaşmak üzere bir SavedModel oluştururken, tüketicilerin buna ince ayar yapıp yapmayacağını ve nasıl yapması gerektiğini önceden düşünün ve belgelerde rehberlik sağlayın.

Keras Modelinden kaydetme, tüm ince ayar mekaniğinin çalışmasını sağlamalıdır (ağırlık düzenleme kayıplarından tasarruf etmek, eğitilebilir değişkenler bildirmek, hem training=True hem de training=False için __call__ izleme, vb.)

Gradyan akışıyla iyi çalışan bir model arayüzü seçin; örneğin, softmax olasılıkları veya top-k tahminleri yerine çıktı logitleri.

Modelde bırakma, toplu normalleştirme veya hiperparametreler içeren benzer eğitim teknikleri kullanılıyorsa, bunları beklenen birçok hedef sorun ve toplu iş boyutu açısından anlamlı olan değerlere ayarlayın. (Bu yazının yazıldığı an itibarıyla Keras'tan tasarruf etmek tüketicilerin bunları ayarlamasına izin vermeyi kolaylaştırmıyor.)

Bireysel katmanlardaki ağırlık düzenleyiciler kaydedilir (düzenleme gücü katsayılarıyla birlikte), ancak optimize edicinin içinden ağırlık düzenleme ( tf.keras.optimizers.Ftrl.l1_regularization_strength=...) gibi) kaybolur. SavedModel'inizin tüketicilerine buna göre tavsiyelerde bulunun.