เครื่องมือเพิ่มประสิทธิภาพ TensorFlow Keras แบบกำหนดเอง


30

สมมติว่าฉันต้องการเขียนคลาสของเครื่องมือเพิ่มประสิทธิภาพแบบกำหนดเองที่สอดคล้องกับtf.kerasAPI (โดยใช้รุ่น TensorFlow> = 2.0) ฉันสับสนเกี่ยวกับวิธีการทำเอกสารกับสิ่งที่ทำในการนำไปใช้งาน

เอกสารประกอบสำหรับtf.keras.optimizers.Optimizer รัฐ ,

  ### 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)

แต่ในปัจจุบันtf.keras.optimizers.Optimizerการดำเนินงานไม่ได้กำหนดresource_apply_denseวิธีการ แต่ไม่กำหนดเอกชนมองหาวิธีการต้นขั้ว_resource_apply_dense ในทำนองเดียวกันไม่มีresource_apply_sparseหรือcreate_slotsวิธีการ แต่มี_resource_apply_sparseต้นขั้ววิธีการและวิธีการเรียก_create_slots

อย่างเป็นทางการในtf.keras.optimizers.Optimizersubclasses (โดยใช้tf.keras.optimizers.Adamเป็นตัวอย่าง) มี_resource_apply_dense, _resource_apply_sparseและ_create_slotsวิธีการและไม่มีวิธีการดังกล่าวได้โดยไม่ต้องขีดชั้นนำ

มีวิธีการชั้นนำขีดที่คล้ายกันในเล็กน้อยน้อยอย่างเป็นทางการtf.keras.optimizers.Optimizersubclasses (เช่นtfa.optimizers.MovingAverageจาก TensorFlow Addons: _resource_apply_dense, _resource_apply_sparse, _create_slots)

อีกจุดที่น่าประหลาดใจสำหรับฉันคือบางส่วนของเครื่องมือเพิ่มประสิทธิภาพ TensorFlow Addons ยังแทนที่apply_gradientsวิธี (เช่นtfa.optimizers.MovingAverage) ในขณะที่tf.keras.optimizersเครื่องมือเพิ่มประสิทธิภาพไม่ได้

ยิ่งกว่านั้นฉันสังเกตเห็นว่าapply_gradientsวิธีการของtf.keras.optimizers.Optimizerการเรียก_create_slotsเมธอดแต่tf.keras.optimizers.Optimizerคลาสพื้นฐานไม่มี_create_slotsเมธอด ดังนั้นจึงดูเหมือนว่า_create_slotsวิธีการจะต้องมีการกำหนดไว้ใน subclass apply_gradientsเพิ่มประสิทธิภาพถ้าคลาสย่อยที่ไม่ได้แทนที่


คำถาม

วิธีที่ถูกต้องในการ subclass tf.keras.optimizers.Optimizerคืออะไร? โดยเฉพาะอย่างยิ่ง

  1. ที่ไม่tf.keras.optimizers.Optimizerเอกสารที่ระบุไว้ที่ด้านบนเพียงหมายถึงการแทนที่รุ่นชั้นนำขีดของวิธีการที่พวกเขาพูดถึง (เช่น_resource_apply_denseแทนresource_apply_dense)? ถ้าใช่มีการรับประกัน API เกี่ยวกับวิธีการดูส่วนตัวเหล่านี้ซึ่งไม่เปลี่ยนพฤติกรรมของพวกเขาในรุ่นอนาคตของ TensorFlow หรือไม่? ลายเซ็นของวิธีการเหล่านี้คืออะไร?
  2. เมื่อใดที่จะแทนที่apply_gradientsนอกเหนือจาก_apply_resource_[dense|sparse]วิธีการ?

แก้ไข ปัญหาที่เปิดใน GitHub: # 36449


1
นี่อาจเป็นสิ่งที่ต้องรายงานว่าเป็นปัญหาเกี่ยวกับเอกสารของ devs แน่นอนที่สุดดูเหมือนว่าวิธีการที่จะแทนที่ควรรวมขีดเส้นใต้เริ่มต้นในเอกสาร แต่ในกรณีใด ๆ เช่นคุณพูดว่าไม่มีข้อมูลเกี่ยวกับลายเซ็นและวัตถุประสงค์ที่แน่นอน นอกจากนี้ยังอาจเป็นไปได้ว่าชื่อวิธีโดยไม่ต้องขีดล่าง (เอกสาร) มีการวางแผนที่จะเพิ่ม (เช่นเดียวกับget_config) แต่แล้วพวกเขาก็ยังไม่ควรปรากฏในเอกสารสาธารณะ
jdehesa

สำหรับลายเซ็นคุณสามารถดูการประกาศ_resource_apply_denseหรือ_resource_apply_sparseและดูการใช้ในเครื่องมือเพิ่มประสิทธิภาพที่นำมาใช้ ในขณะที่มันอาจไม่เป็นเช่นนั้นฉันคิดว่า API สาธารณะที่รับประกันความเสถียร แต่ฉันคิดว่ามันค่อนข้างปลอดภัยที่จะใช้พวกเขา พวกเขาควรให้แนวทางที่ดีกว่าในด้านนี้
jdehesa

ฉันยอมรับว่านี่เป็นปัญหาเกี่ยวกับเอกสารของ TensorFlow คุณสร้างปัญหาให้กับสิ่งนี้ใน tf Github repo หรือไม่? ถ้าเป็นเช่นนั้นคุณสามารถแชร์ลิงค์ที่นี่ได้ไหม?
jpgard

คำตอบ:


3

ฉันได้ดำเนินการKeras AdamWในทุก TF สำคัญและ Keras รุ่น - ผมขอเชิญคุณที่จะตรวจสอบoptimizers_v2.py หลายจุด:

  • คุณควรสืบทอดOptimizerV2ซึ่งเป็นสิ่งที่คุณเชื่อมโยง เป็นคลาสพื้นฐานล่าสุดและปัจจุบันสำหรับtf.kerasเครื่องมือเพิ่มประสิทธิภาพ
  • คุณถูกต้องใน (1) - นี่เป็นข้อผิดพลาดของเอกสาร; วิธีการนั้นเป็นแบบส่วนตัวเนื่องจากผู้ใช้ไม่ได้ใช้งานโดยตรง
  • apply_gradients(หรือวิธีอื่นใด) จะถูกแทนที่หากค่าเริ่มต้นไม่สำเร็จตามที่ต้องการสำหรับเครื่องมือเพิ่มประสิทธิภาพที่กำหนด ในตัวอย่างที่เชื่อมโยงของคุณมันเป็นเพียงแค่ส่วนเสริมเดียวกับต้นฉบับ
  • "ดังนั้นดูเหมือนว่า_create_slotsต้องมีการกำหนดวิธีการในคลาสย่อยของเครื่องมือเพิ่มประสิทธิภาพหากคลาสย่อยนั้นไม่ได้แทนที่apply_gradients" - ทั้งสองไม่เกี่ยวข้องกัน มันเป็นเรื่องบังเอิญ

  • ความแตกต่างระหว่าง_resource_apply_denseและ_resource_apply_sparseคืออะไร?

ข้อตกลงหลังมีเลเยอร์เบาบาง - เช่นEmbedding- และอดีตกับทุกอย่างอื่น; ตัวอย่าง

  • ฉันควรใช้เมื่อ_create_slots()ใด

เมื่อกำหนดs trainable tf.Variable ; ตัวอย่าง: ช่วงเวลาการสั่งซื้อครั้งแรกและครั้งที่สองของน้ำหนัก (เช่นอดัม) add_slot()มันใช้

  • ฉันควรใช้เมื่อ_set_hyper()ใด

ค่อนข้างทุกครั้งที่ไม่ได้ใช้_create_slots(); มันเหมือนกับการตั้งค่าคุณสมบัติคลาส แต่มีขั้นตอนการประมวลผลล่วงหน้าเพิ่มเติมเพื่อให้แน่ใจว่าถูกต้องในการใช้งาน ดังนั้นงูหลามint, float, tf.Tensor, tf.Variable, และอื่น ๆ (ฉันควรจะใช้มันมากกว่านี้ใน Keras AdamW)


หมายเหตุ : ในขณะที่เครื่องมือเพิ่มประสิทธิภาพที่เชื่อมโยงของฉันทำงานได้อย่างถูกต้องและเร็วเท่ากับต้นฉบับรหัสจะเป็นไปตามแนวทางปฏิบัติของ TensorFlow ที่ดีที่สุดและยังคงเร็วกว่า ฉันไม่แนะนำเพราะเป็น "ข้อมูลอ้างอิงที่เหมาะ" เช่นวัตถุหลาม (เช่นint) ควรเป็นเทนเซอร์ eta_tถูกกำหนดเป็น a tf.Variableแต่แทนที่ overriden ทันทีเป็นเมธอดtf.Tensorin _applyไม่จำเป็นต้องเป็นเรื่องใหญ่เพียงแค่ไม่มีเวลาทำการปรับปรุง


2
  1. ใช่นี่เป็นข้อผิดพลาดของเอกสาร ชื่อขีดล่างก่อนหน้าเป็นวิธีที่ถูกต้องในการแทนที่ ที่เกี่ยวข้องคือเครื่องมือเพิ่มประสิทธิภาพที่ไม่ใช่ Keras ซึ่งได้กำหนดไว้ทั้งหมด แต่ไม่ได้นำไปใช้ในคลาสพื้นฐาน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. apply_denseผมไม่ทราบว่าเกี่ยวกับ สำหรับสิ่งหนึ่งถ้าคุณลบล้างรหัสกล่าวว่าการกระจายแบบจำลองอาจเป็น "อันตราย"
    # 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.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.