פענוח API

הצג באתר TensorFlow.org הפעל בגוגל קולאב הצג ב-GitHub הורד מחברת

סקירה כללית

בעבר הקרוב, היה הרבה מחקר ביצירת שפות עם מודלים אוטומטיים רגרסיביים. בדור אוטומטי שפה-רגרסיבי, התפלגות ההסתברות של אסימון בשלב זמן K תלוי-תחזיות האסימון של המודל עד K-1 הצעד. עבור דגמים אלה, אסטרטגיות פענוח כגון חיפוש Beam, חמדן, Top-p, ו Top-k הם מרכיבים קריטיים של המודל בעיקר להשפיע על סגנון / אופי הפלט שנוצר אסימון בכל K צעד זמן נתון.

לדוגמא, חיפוש Beam מפחית את הסיכון של אסימוני הסתברות גבוהה מוסתרים חסרים ידי שמירה על num_beams סביר להניח השערות בכול שלב זמן ובסופו של דבר בוחר את ההשערה כי יש את הסיכוי הגבוה ביותר הכולל. Murray et al. (2018) ו יאנג ואח '. (2018) מראים כי חיפוש קרן עובד היטב במשימות תרגום מכונה. שניהם חיפוש Beam & אסטרטגיות חמדן יש אפשרות של יצירת אסימונים חוזרים.

מניפה א. אל (2018) הציג דגימת Top-K, שבו K אסימונים הסבירים ביותר מסוננים ואת מסת ההסתברות מחדש בין אלה אסימוני K בלבד.

ארי הולצמן א. אל (2019) הציג דגימת Top-p, אשר בוחרת מהמערך הקטן ביותר האפשרי של אסימונים עם הסתברות מצטברת המוסיפה upto ההסתברות P. מסת ההסתברות מחולקת מחדש בין קבוצה זו. בדרך זו, גודל קבוצת האסימונים יכול להגדיל ולהקטין באופן דינמי. Top-p, Top-k משמש בדרך כלל משימות כגון דור סיפור.

ה-API לפענוח מספק ממשק להתנסות באסטרטגיות פענוח שונות במודלים אוטומטיים רגרסיביים.

  1. אסטרטגיות הדגימה הבאות מסופקות ב-sampling_module.py, שיורשת ממחלקת הפענוח הבסיסית:

  2. חיפוש קרן מסופק ב-beam_search.py. github

להכין

pip install -q -U tensorflow-text
pip install -q tf-models-nightly
import numpy as np
import matplotlib.pyplot as plt

import tensorflow as tf

from official import nlp
from official.nlp.modeling.ops import sampling_module
from official.nlp.modeling.ops import beam_search
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/pkg_resources/__init__.py:119: PkgResourcesDeprecationWarning: 0.18ubuntu0.18.04.1 is an invalid version and will not be supported in a future release
  PkgResourcesDeprecationWarning,

אתחול מודול הדגימה ב-TF-NLP.

  • symbols_to_logits_fn: השתמש סגירת זה לקרוא את המודל לחזות את logits עבור index+1 צעד. כניסות ויציאות עבור סגירה זו הן כדלקמן:
Args:
  1] ids : Current decoded sequences. int tensor with shape (batch_size, index + 1 or 1 if padded_decode is True)],
  2] index [scalar] : current decoded step,
  3] cache [nested dictionary of tensors] : Only used for faster decoding to store pre-computed attention hidden states for keys and values. More explanation in the cell below.
Returns:
  1] tensor for next-step logits [batch_size, vocab]
  2] the updated_cache [nested dictionary of tensors].

המטמון משמש לפיענוח מהיר יותר. הנה הפניה יישום עבור סגירת לעיל.

  • length_normalization_fn: השתמש סגירה זו להחזרת פרמטר נורמליזצית אורך.
Args: 
  1] length : scalar for decoded step index.
  2] dtype : data-type of output tensor
Returns:
  1] value of length normalization factor.
  • vocab_size: גודל אוצר המילים פלט.

  • max_decode_length: סקלר עבור מספר כולל של צעדי פענוח.

  • eos_id: פענוח יפסיק אם כל מזהי מפוענח התפוקה ב אצווה יש eos_id זה.

  • padded_decode: הגדר ל True אם היא פועלת TPU. הטנזורים מרופדים ל-max_decoding_length אם זה נכון.

  • top_k: top_k מופעלת אם ערך זה הוא> 1.

  • top_p: top_p מופעלת אם ערך זה> 0 ו <1.0

  • sampling_temperature: זה משמש לאמוד מחדש את הפלט softmax. הטמפרטורה מטה את ההתפלגות לכיוון אסימוני סבירות גבוהה ומורידה את המסה בחלוקת הזנב. הערך חייב להיות חיובי. טמפרטורה נמוכה מקבילה לחמדנית והופכת את ההפצה לחדה יותר, בעוד טמפרטורה גבוהה הופכת אותה לשטוחה יותר.

  • enable_greedy: כברירת מחדל, זה נכון ופענוח חמדן מופעל. כדי להתנסות באסטרטגיות אחרות, הגדר זאת כ-False.

אתחול הפרמטרים ההיפרפרמטרים של המודל

params = {}
params['num_heads'] = 2
params['num_layers'] = 2
params['batch_size'] = 2
params['n_dims'] = 256
params['max_decode_length'] = 4

בארכיטקטורות-רגרסיבי אוטומטיות כמו שנאי מבוסס Encoder מפענח דגמים, המטמון משמש פענוח סדרה מהיר. זהו מילון מקונן המאחסן מצבים נסתרים מחושבים מראש (מפתח וערכים בלוקים של תשומת לב עצמית ובבלוקים של תשומת לב צולבת) עבור כל שכבה.

אתחול המטמון.

cache = {
    'layer_%d' % layer: {
        'k': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], int(params['n_dims']/params['num_heads'])], dtype=tf.float32),
        'v': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], int(params['n_dims']/params['num_heads'])], dtype=tf.float32)
        } for layer in range(params['num_layers'])
    }
print("cache key shape for layer 1 :", cache['layer_1']['k'].shape)
cache key shape for layer 1 : (2, 4, 2, 128)

הגדר סגירה לנורמליזציה של אורך במידת הצורך.

זה משמש לנרמול הציונים הסופיים של רצפים שנוצרו והוא אופציונלי

def length_norm(length, dtype):
  """Return length normalization factor."""
  return tf.pow(((5. + tf.cast(length, dtype)) / 6.), 0.0)

צור model_fn

בפועל, זה יוחלף על ידי יישום מודל בפועל כגון כאן

Args:
i : Step that is being decoded.
Returns:
  logit probabilities of size [batch_size, 1, vocab_size]
probabilities = tf.constant([[[0.3, 0.4, 0.3], [0.3, 0.3, 0.4],
                              [0.1, 0.1, 0.8], [0.1, 0.1, 0.8]],
                            [[0.2, 0.5, 0.3], [0.2, 0.7, 0.1],
                              [0.1, 0.1, 0.8], [0.1, 0.1, 0.8]]])
def model_fn(i):
  return probabilities[:, i, :]

אתחול symbols_to_logits_fn

def _symbols_to_logits_fn():
  """Calculates logits of the next tokens."""
  def symbols_to_logits_fn(ids, i, temp_cache):
    del ids
    logits = tf.cast(tf.math.log(model_fn(i)), tf.float32)
    return logits, temp_cache
  return symbols_to_logits_fn

רודף בצע

פענוח חמדן בוחר את מזהה אסימון עם ההסתברות הגבוהה ביותר כמו id הבא שלה: \(id_t = argmax_{w}P(id | id_{1:t-1})\) בכל timestep \(t\). הסקיצה הבאה מציגה פענוח חמדני.

greedy_obj = sampling_module.SamplingModule(
    length_normalization_fn=None,
    dtype=tf.float32,
    symbols_to_logits_fn=_symbols_to_logits_fn(),
    vocab_size=3,
    max_decode_length=params['max_decode_length'],
    eos_id=10,
    padded_decode=False)
ids, _ = greedy_obj.generate(
    initial_ids=tf.constant([9, 1]), initial_cache=cache)
print("Greedy Decoded Ids:", ids)
Greedy Decoded Ids: tf.Tensor(
[[9 1 2 2 2]
 [1 1 1 2 2]], shape=(2, 5), dtype=int32)

top_k דגימה

בשנת דגימת Top-K, K כנראה מזהי אסימון הבא מסוננים ואת מסת ההסתברות מחדש בין רק אלה המזהים K.

top_k_obj = sampling_module.SamplingModule(
    length_normalization_fn=length_norm,
    dtype=tf.float32,
    symbols_to_logits_fn=_symbols_to_logits_fn(),
    vocab_size=3,
    max_decode_length=params['max_decode_length'],
    eos_id=10,
    sample_temperature=tf.constant(1.0),
    top_k=tf.constant(3),
    padded_decode=False,
    enable_greedy=False)
ids, _ = top_k_obj.generate(
    initial_ids=tf.constant([9, 1]), initial_cache=cache)
print("top-k sampled Ids:", ids)
top-k sampled Ids: tf.Tensor(
[[9 1 0 2 2]
 [1 0 1 2 2]], shape=(2, 5), dtype=int32)

top_p דגימה

במקום לדגום רק את אסימון K כנראה מזהים, ב Top-p דגימה בוחרת מהמערך הקטן ביותר האפשרי של מזהים אשר הסתברות מצטברת עולה על הסתברות p.

top_p_obj = sampling_module.SamplingModule(
    length_normalization_fn=length_norm,
    dtype=tf.float32,
    symbols_to_logits_fn=_symbols_to_logits_fn(),
    vocab_size=3,
    max_decode_length=params['max_decode_length'],
    eos_id=10,
    sample_temperature=tf.constant(1.0),
    top_p=tf.constant(0.9),
    padded_decode=False,
    enable_greedy=False)
ids, _ = top_p_obj.generate(
    initial_ids=tf.constant([9, 1]), initial_cache=cache)
print("top-p sampled Ids:", ids)
top-p sampled Ids: tf.Tensor(
[[9 1 1 2 2]
 [1 1 1 0 2]], shape=(2, 5), dtype=int32)

פענוח חיפוש קרן

חיפוש קרן מפחית את הסיכון להחמצת מזהי אסימון מוסתרים בסבירות גבוהה על ידי שמירת מספר ההשערות הסביר ביותר בכל שלב בזמן ובסופו של דבר בחירת ההשערה בעלת ההסתברות הגבוהה ביותר הכוללת.

beam_size = 2
params['batch_size'] = 1
beam_cache = {
    'layer_%d' % layer: {
        'k': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], params['n_dims']], dtype=tf.float32),
        'v': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], params['n_dims']], dtype=tf.float32)
        } for layer in range(params['num_layers'])
    }
print("cache key shape for layer 1 :", beam_cache['layer_1']['k'].shape)
ids, _ = beam_search.sequence_beam_search(
    symbols_to_logits_fn=_symbols_to_logits_fn(),
    initial_ids=tf.constant([9], tf.int32),
    initial_cache=beam_cache,
    vocab_size=3,
    beam_size=beam_size,
    alpha=0.6,
    max_decode_length=params['max_decode_length'],
    eos_id=10,
    padded_decode=False,
    dtype=tf.float32)
print("Beam search ids:", ids)
cache key shape for layer 1 : (1, 4, 2, 256)
Beam search ids: tf.Tensor(
[[[9 0 1 2 2]
  [9 1 2 2 2]]], shape=(1, 2, 5), dtype=int32)