مشاهده در 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 یک رابط برای آزمایش استراتژیهای رمزگشایی مختلف در مدلهای رگرسیون خودکار فراهم میکند.
استراتژیهای نمونهگیری زیر در sampling_module.py ارائه شدهاند که از کلاس Decoding پایه به ارث میرسد:
جستجوی پرتو در 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)