رمزگشایی API

مشاهده در TensorFlow.org در Google Colab اجرا شود در GitHub مشاهده کنید دانلود دفترچه یادداشت

بررسی اجمالی

در گذشته اخیر، تحقیقات زیادی در زمینه تولید زبان با مدل‌های خود رگرسیون انجام شده است. در نسل زبان خودکار پسرونده، توزیع احتمال رمز در زمان گام K وابسته به مدل نشانه رمز، پیش بینی تا گام K-1 است. برای این مدل، استراتژی رمزگشایی مانند پرتو جستجو، حریص، بالا-P، و بالا-K اجزای مهم مدل هستند و تا حد زیادی سبک / ماهیت خروجی تولید نشانه در یک زمان معین گام K را تحت تاثیر قرار.

به عنوان مثال، پرتو جستجو خطر از دست رفته پنهان نشانه احتمال بالا با نگه داشتن ترین num_beams احتمال فرضیه در هر مرحله زمان و در نهایت انتخاب فرضیه است که به طور کلی بیشترین احتمال را کاهش می دهد. موری و همکاران (2018) و یانگ و همکاران (2018) نشان می دهد که جستجو پرتو خوبی کار می کند در کارهای ترجمه ماشینی. هر دو پرتو جستجو و استراتژی های حریص یک امکان ایجاد نشانه تکرار.

فن و. AL (2018) معرفی نمونه بالا-K، که در آن K نشانه احتمال زیاد فیلتر شده و احتمال جرم است میان تنها آن نشانه K توزیع شود.

آری هولتزمن و. AL (2019) معرفی نمونه بالا-P، که از کوچکترین مجموعه ای ممکن است از نشانه با احتمال تجمعی که می افزاید: تا احتمال (p) انتخاب می کند. سپس جرم احتمال بین این مجموعه دوباره توزیع می شود. به این ترتیب، اندازه مجموعه توکن ها می تواند به صورت پویا کم و زیاد شود. بالا-P، بالا-K به طور کلی در کارهای مانند داستان نسل استفاده می شود.

Decoding API یک رابط برای آزمایش استراتژی‌های رمزگشایی مختلف در مدل‌های رگرسیون خودکار فراهم می‌کند.

  1. استراتژی‌های نمونه‌گیری زیر در sampling_module.py ارائه شده‌اند که از کلاس Decoding پایه به ارث می‌رسد:

  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: این درست تنظیم اگر در حال اجرا در 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

در معماری خودکار واپسگرا مانند ترانسفورماتور بر اساس تخمین-رسیور مدل، مدل کش برای رمز گشایی پی در پی سریع استفاده می شود. این یک فرهنگ لغت تودرتو است که حالت های پنهان از پیش محاسبه شده (کلید و مقادیر در بلوک های توجه به خود و بلوک های توجه متقابل) را برای هر لایه ذخیره می کند.

کش را راه اندازی کنید.

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, :]

نمادهای_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_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

در نمونه بالا-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 رمز شناسه، در بالا-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)