Masking دستی و Ragged Tensor | استفادهٔ مجدد از Embedding و Language Modelهای Pretrained

Masking دستی و Ragged Tensor | استفادهٔ مجدد از Embedding و Language Modelهای Pretrained

توسط admin | گروه هوش مصنوعی | 1405/06/01

نظرات 0

Masking دستی و Ragged Tensor | استفادهٔ مجدد از Embedding و Language Modelهای Pretrained

کتاب
Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow
بخش منبع
Reusing Pretrained Embeddings and Language Models; Encoder-Decoder for Neural Machine Translation; Bidirectional RNNs; Beam Search; Attention Mechanisms
صفحات این PDF
56-69
صفحات چاپی کتاب
592-605
جایگاه در مجموعه
65 / Machine_Learning_405_06; parent: Machine_Learning_405_06_01.html

Masking دستی و Ragged Tensor

Masking خودکار برای Modelهای ساده عالی است، اما وقتی Conv1D، چند Branch یا Layerهای Custom با Recurrent Layerها ترکیب شوند، گاهی باید Mask را دستی محاسبه کرد. در Functional API می‌توان IDهای غیرصفر را به‌عنوان Mask ساخت و مستقیماً به GRU یا LSTM داد:

inputs = tf.keras.layers.Input(shape=[], dtype=tf.string)
token_ids = text_vec_layer(inputs)
mask = tf.math.not_equal(token_ids, 0)
Z = tf.keras.layers.Embedding(vocab_size, embed_size)(token_ids)
Z = tf.keras.layers.GRU(128, dropout=0.2)(Z, mask=mask)
outputs = tf.keras.layers.Dense(1, activation="sigmoid")(Z)
model = tf.keras.Model(inputs=[inputs], outputs=[outputs])

راه دیگر استفاده از Ragged Tensor است. با ragged=True در TextVectorization، Sequenceهای با طول متفاوت بدون Padding در یک RaggedTensor نگهداری می‌شوند. Recurrent Layerهای Keras از RaggedTensor پشتیبانی می‌کنند، بنابراین نیازی به mask_zero=True نیست.

استفادهٔ مجدد از Embedding و Language Modelهای Pretrained

Embedding آموخته‌شده از فقط ۲۵هزار Review می‌تواند مفید باشد، اما Corpusهای عظیم Representationهای قوی‌تری تولید می‌کنند. Word2vec، GloVe و FastText نمونه‌هایی از Word Embeddingهای Pretrained هستند. محدودیت مهم آن‌ها این است که یک Word همیشه یک Vector ثابت دارد؛ مثلاً معنای «right» در «left and right» و «right and wrong» متفاوت است، اما Embedding کلاسیک تفاوت Context را نمی‌بیند.

مدل ELMo این محدودیت را با Contextual Embedding حل کرد: Representation یک Word از Hidden Stateهای یک Language Model دوطرفه به دست می‌آید و بنابراین به جمله وابسته است. اندکی بعد ULMFiT نشان داد Pretraining بدون Label روی Corpus عظیم و سپس Fine-tuning روی Task خاص می‌تواند با Label بسیار کمتر به Accuracy خوب برسد. این نقطه شروع دوره‌ای شد که Reuse کردن Language Modelهای Pretrained در NLP به استاندارد تبدیل شد.

Universal Sentence Encoder از TensorFlow Hub

import os
import tensorflow_hub as hub

os.environ["TFHUB_CACHE_DIR"] = "my_tfhub_cache"
model = tf.keras.Sequential([
    hub.KerasLayer(
        "https://tfhub.dev/google/universal-sentence-encoder/4",
        trainable=True, dtype=tf.string, input_shape=[]),
    tf.keras.layers.Dense(64, activation="relu"),
    tf.keras.layers.Dense(1, activation="sigmoid")
])
model.compile(loss="binary_crossentropy", optimizer="nadam",
              metrics=["accuracy"])

با trainable=True خود Universal Sentence Encoder نیز Fine-tune می‌شود. Model نزدیک 1GB است و بهتر است Cache Directory مشخص شود تا هر بار Download نشود. Accuracy Validation این مثال از 90% عبور می‌کند.

Encoder-Decoder برای Neural Machine Translation

اکنون یک Model برای ترجمهٔ English به Spanish می‌سازیم. English Sentence وارد Encoder می‌شود و Decoder ترجمهٔ Spanish را تولید می‌کند. هنگام Training، Target اسپانیایی یک Step Shift می‌شود و Word صحیح قبلی به Decoder داده می‌شود. این روش Teacher Forcing نام دارد و Training را بسیار سریع‌تر و پایدارتر می‌کند.

Decoder با Token ویژهٔ <sos> شروع می‌کند و باید جمله را با <eos> تمام کند. در هر Step، Dense+Softmax یک Probability برای هر Word در Vocabulary مقصد می‌سازد.

16-3 - Encoder-Decoder برای Neural Machine Translation
شکل 16-3. Encoder-Decoder برای Neural Machine Translation

در Inference دیگر Target واقعی در اختیار Decoder نیست؛ بنابراین Word تولیدشده در Step قبلی به‌عنوان Input Step بعد استفاده می‌شود.

16-4 - Encoder-Decoder برای Neural Machine Translation
شکل 16-4. Encoder-Decoder برای Neural Machine Translation

آماده‌سازی Dataset دوزبانه

Dataset شامل جفت Sentenceهای English/Spanish است. برای هر زبان TextVectorization جدا ساخته و روی Text همان زبان Adapt می‌شود. Vocabulary مقصد شامل Tokenهای SOS و EOS نیز هست. سپس Dataset به Inputهای Encoder، Inputهای Decoder و Targetهای Decoder تقسیم می‌شود.

text_vec_layer_en = tf.keras.layers.TextVectorization(
    max_tokens=vocab_size, output_sequence_length=max_length)
text_vec_layer_es = tf.keras.layers.TextVectorization(
    max_tokens=vocab_size, output_sequence_length=max_length,
    standardize=strip_chars)

در عمل Sentenceهای بسیار بلند می‌توانند Truncate شوند و Padding برای Batch شدن استفاده می‌شود.

ساخت Encoder و Decoder با Functional API

Model دو Input دارد؛ یکی برای Sentence English و دیگری برای Spanish Shift‌شده. Word IDها Embedding می‌شوند. Encoder یک LSTM است که State کوتاه‌مدت و بلندمدت نهایی را تولید می‌کند و این Stateها به Decoder به‌عنوان Initial State داده می‌شوند:

encoder_inputs = tf.keras.layers.Input(shape=[], dtype=tf.string)
decoder_inputs = tf.keras.layers.Input(shape=[], dtype=tf.string)

encoder_input_ids = text_vec_layer_en(encoder_inputs)
decoder_input_ids = text_vec_layer_es(decoder_inputs)

embed_size = 128
encoder_embedding_layer = tf.keras.layers.Embedding(vocab_size, embed_size,
                                                     mask_zero=True)
decoder_embedding_layer = tf.keras.layers.Embedding(vocab_size, embed_size,
                                                     mask_zero=True)
encoder_embeddings = encoder_embedding_layer(encoder_input_ids)
decoder_embeddings = decoder_embedding_layer(decoder_input_ids)

encoder = tf.keras.layers.LSTM(512, return_state=True)
encoder_outputs, *encoder_state = encoder(encoder_embeddings)

decoder = tf.keras.layers.LSTM(512, return_sequences=True)
decoder_outputs = decoder(decoder_embeddings,
                          initial_state=encoder_state)

output_layer = tf.keras.layers.Dense(vocab_size, activation="softmax")
Y_proba = output_layer(decoder_outputs)
model = tf.keras.Model(inputs=[encoder_inputs, decoder_inputs], outputs=[Y_proba])

Loss همان Sparse Categorical Cross-Entropy است. در Inference یک Function ترجمه، Decoder Input را از SOS شروع می‌کند، Model را اجرا می‌کند، Word بعدی را برمی‌گزیند و آن را به Sentence جزئی اضافه می‌کند تا EOS تولید شود.

Bidirectional RNN

Encoder معمولی در هر Time Step فقط Past را دیده است. اما برای Encode کردن یک Sentence کامل، Future نیز از قبل موجود است. بنابراین Encoder می‌تواند یک RNN Forward و یک RNN Backward داشته باشد و Output آن‌ها را ترکیب کند.

16-5 - Bidirectional RNN
شکل 16-5. Bidirectional RNN

در Keras با Wrapper زیر ساخته می‌شود:

encoder = tf.keras.layers.Bidirectional(
    tf.keras.layers.LSTM(256, return_state=True))

چون هر Direction در LSTM دو State دارد، Wrapper چهار State برمی‌گرداند. می‌توان Short-term Stateهای Forward/Backward را Concatenate کرد و همین کار را برای Long-term Stateها انجام داد تا Decoder با State 512بعدی Initialize شود.

Beam Search

Greedy Decoding در هر Step فقط محتمل‌ترین Word را نگه می‌دارد، اما انتخاب محلی ممکن است به Translation ضعیف منجر شود. Beam Search چند Candidate برتر را هم‌زمان دنبال می‌کند. اگر Beam Width برابر 3 باشد، در Step اول سه Word برتر نگه داشته می‌شوند؛ در Step بعد هر Candidate با هزاران Word ممکن توسعه می‌یابد و از میان همهٔ Sequenceهای جدید فقط سه Sequence با Probability تجمعی بهتر باقی می‌مانند.

16-6 - Beam Search
شکل 16-6. Beam Search

Beam Search بدون Retrain کردن Model می‌تواند Translation را به‌طور محسوسی بهتر کند، ولی Cost محاسباتی متناسب با Beam Width افزایش می‌یابد.

چرا Encoder-Decoder ساده روی Sentenceهای طولانی ضعیف می‌شود؟

در معماری ساده، تمام اطلاعات Sentence ورودی باید در Final State فشرده شود و Decoder فقط همین Vector را به‌عنوان Summary دریافت می‌کند. برای Sentence کوتاه کافی است، اما در Sentence بلند اطلاعات اولیه به‌تدریج از State محو می‌شوند. راه‌حل مهم این مشکل Attention است: Decoder به‌جای اتکا فقط به Final State، در هر Step می‌تواند مستقیماً به همهٔ Outputهای Encoder نگاه کند و بخش مرتبط را وزن بیشتری بدهد. بخش بعد این Mechanism را دقیق بررسی می‌کند.

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

0 / 500

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620