Özel TensorFlow Keras optimize edici


30

tf.kerasAPI (TensorFlow sürümü> = 2.0 kullanarak) ile uyumlu bir özel optimizer sınıfı yazmak istediğinizi varsayalım . Uygulamalarda yapılanlara karşı bunu yapmanın belgelenmiş yolu hakkında kafam karıştı.

tf.keras.optimizers.Optimizer Devletler için belgeler ,

  ### Write a customized optimizer.
  If you intend to create your own optimization algorithm, simply inherit from
  this class and override the following methods:

    - resource_apply_dense (update variable given gradient tensor is dense)
    - resource_apply_sparse (update variable given gradient tensor is sparse)
    - create_slots (if your optimizer algorithm requires additional variables)

Bununla birlikte, mevcut tf.keras.optimizers.Optimizeruygulama bir tanımlamıyor resource_apply_denseyöntemi, ancak vermez özel görünümlü tanımlamak _resource_apply_denseyöntem saplama . Benzer şekilde, hiçbir yöntem resource_apply_sparseveya create_slotsyöntem yoktur , ancak bir _resource_apply_sparseyöntem saplaması ve bir _create_slotsyöntem çağrısı vardır .

Resmi olarak tf.keras.optimizers.Optimizer(kullanarak alt sınıflarından tf.keras.optimizers.Adamörneğin) vardır _resource_apply_dense, _resource_apply_sparseve _create_slotsyöntemler ve önde gelen çizgi olmadan böyle bir yöntem vardır.

Performansı biraz daha düşük resmî benzer lider-çizgi yöntemi vardır tf.keras.optimizers.Optimizer(örneğin, alt sınıfları tfa.optimizers.MovingAverage: TensorFlow Eklentileri dan _resource_apply_dense, _resource_apply_sparse, _create_slots).

Benim için bir başka kafa karıştırıcı nokta, TensorFlow Addons optimizer'larının bazılarının daapply_gradients yöntemi (örneğin tfa.optimizers.MovingAverage) geçersiz kılması , tf.keras.optimizersoptimizasyonların yapmamasıdır.

Dahası, apply_gradientsyöntem tf.keras.optimizers.Optimizeryönteminin çağırdığını_create_slots fark ettim , ancak temel tf.keras.optimizers.Optimizersınıfın bir _create_slotsyöntemi yok. Bu nedenle, eğer bu alt sınıf geçersiz kılmıyorsa, bir optimize edici alt sınıfında bir _create_slotsyöntemin tanımlanması gerektiği görülmektedir apply_gradients.


Sorular

A alt sınıfını almanın doğru yolu nedir tf.keras.optimizers.Optimizer? özellikle,

  1. tf.keras.optimizers.OptimizerÜstte listelenen belgeler, bahsettikleri yöntemlerin (örneğin, _resource_apply_denseyerine resource_apply_dense) önde gelen alt çizgi sürümlerini geçersiz kılmak mı anlamına geliyor ? Öyleyse, TensorFlow'un gelecekteki sürümlerinde davranışlarını değiştirmeyen bu özel görünümlü yöntemlerle ilgili herhangi bir API garantisi var mı? Bu yöntemlerin imzaları nelerdir?
  2. Yöntemlere apply_gradientsek olarak ne zaman geçersiz kılınır _apply_resource_[dense|sparse]?

Düzenle. GitHub'da açılan sorun: # 36449


1
Bu, geliştiricilere dokümantasyon sorunu olarak bildirilecek bir şey olabilir. Kesinlikle geçersiz kılma yöntemlerinin belgelere ilk alt çizgiyi içermesi gerekir, ancak her durumda, dediğiniz gibi, imzaları ve kesin amaçları hakkında hiçbir bilgi yoktur. Ayrıca alt çizgisi olmayan (ve belgelenen) yöntem adlarının (gibi get_config) eklenmesi planlanmış olabilir , ancak bunlar henüz genel dokümanlarda görünmemelidir .
jdehesa

İmzalar için, _resource_apply_denseveya ifadesine her zaman bakabilir _resource_apply_sparseve bunların uygulanmış optimize edicilerdeki kullanımlarını görebilirsiniz. Bence, kararlılık garantili genel API olmasa da, bunları kullanmanın oldukça güvenli olduğunu söyleyebilirim. Sadece bu açıdan daha iyi rehberlik sağlamalıdırlar.
jdehesa

Bunun TensorFlow ile ilgili bir belge sorunu olduğunu kabul ediyorum. Tf Github deposunda bunun için bir sorun oluşturdunuz mu? Öyleyse, bağlantıyı burada paylaşabilir misiniz?
jpgard

Yanıtlar:


3

Keras AdamW'ı tüm TF & Keras sürümlerinde uyguladım - sizi optimizers_v2.py'yi incelemeye davet ediyorum . Birkaç puan:

  • Miras almalısınız OptimizerV2, ki bu aslında bağlandığınız şeydir; tf.kerasoptimize ediciler için en yeni ve mevcut temel sınıftır
  • (1) 'de haklısınız - bu bir dokümantasyon hatasıdır; yöntemler kullanıcı tarafından doğrudan kullanılması amaçlanmadığından özeldir.
  • apply_gradients(veya başka bir yöntem) yalnızca varsayılan, belirli bir optimize edici için gerekli olanı gerçekleştiremezse geçersiz kılınır; bağlantılı örneğinizde, orijinaline sadece tek katmanlı bir eklenti
  • "Öyleyse, _create_slotsbir alt sınıf geçersiz kılmıyorsa, bir optimize edici alt sınıfında bir yöntemin tanımlanması gerektiği görülmektedir apply_gradients" - ikisi birbiriyle ilgisiz; tesadüf.

  • Arasındaki fark nedir _resource_apply_denseve _resource_apply_sparse?

İkincisi seyrek katmanlarla ilgilenir - örneğin Embedding- ve diğer her şeyle eski; örnek .

  • Ne zaman kullanmalıyım _create_slots()?

Eğitilebilir tf.Variable s tanımlarken ; örnek: ağırlıkların birinci ve ikinci derece momentleri (örn. Adam). Kullanır add_slot().

Hemen hemen hiç kullanmadığınızda _create_slots(); sınıf özniteliklerini ayarlamak gibi, ancak kullanımda doğruluğu sağlamak için ekstra önişleme adımlarıyla. Yani Python int, float, tf.Tensor, tf.Variable, ve diğerleri. (Daha çok Keras AdamW'da kullanmalıydım).


Not : Bağlantılı optimize edicilerim düzgün çalışıyor ve orijinaller kadar hızlı olsa da, kod en iyi TensorFlow uygulamalarını takip ediyor ve yine de daha hızlı olabilir; "İdeal referans" olarak tavsiye etmiyorum. Örneğin, bazı Python nesneleri (örn. int) Tensörler olmalıdır; eta_tbir şekilde tanımlanır tf.Variable, ancak hemen olarak değiştirileceğini tf.Tensoriçinde _applyyöntemler. Mutlaka büyük bir anlaşma değil, sadece yenilemek için zaman yoktu.


2
  1. Evet, bu bir dokümantasyon hatası gibi görünüyor. Önceki alt çizgi adları geçersiz kılmak için doğru yöntemlerdir. İlgili, bunların hepsini tanımlamış ancak temel sınıfta uygulanmamış olan Keras Optimizer olmayan https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/training/optimizer.py
  def _create_slots(self, var_list):
    """Create all slots needed by the variables.
    Args:
      var_list: A list of `Variable` objects.
    """
    # No slots needed by default
    pass

  def _resource_apply_dense(self, grad, handle):
    """Add ops to apply dense gradients to the variable `handle`.
    Args:
      grad: a `Tensor` representing the gradient.
      handle: a `Tensor` of dtype `resource` which points to the variable
       to be updated.
    Returns:
      An `Operation` which updates the value of the variable.
    """
    raise NotImplementedError()

  def _resource_apply_sparse(self, grad, handle, indices):
    """Add ops to apply sparse gradients to the variable `handle`.
    Similar to `_apply_sparse`, the `indices` argument to this method has been
    de-duplicated. Optimizers which deal correctly with non-unique indices may
    instead override `_resource_apply_sparse_duplicate_indices` to avoid this
    overhead.
    Args:
      grad: a `Tensor` representing the gradient for the affected indices.
      handle: a `Tensor` of dtype `resource` which points to the variable
       to be updated.
      indices: a `Tensor` of integral type representing the indices for
       which the gradient is nonzero. Indices are unique.
    Returns:
      An `Operation` which updates the value of the variable.
    """
    raise NotImplementedError()
  1. Bilmiyorum apply_dense. Bir kere, onu geçersiz kılarsanız, kod çoğaltma başına DistributionStrategy'nin "tehlikeli" olabileceğinden bahseder
    # TODO(isaprykin): When using a DistributionStrategy, and when an
    # optimizer is created in each replica, it might be dangerous to
    # rely on some Optimizer methods.  When such methods are called on a
    # per-replica optimizer, an exception needs to be thrown.  We do
    # allow creation per-replica optimizers however, because the
    # compute_gradients()->apply_gradients() sequence is safe.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.