Transformers documentation

RWKV

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

تمت مساهمة هذا النموذج في Hugging Face Transformers في 2023-05-09.

RWKV

نظرة عامة

قُدِّم نموذج RWKV (الإصدار 4) في هذا المستودع

يقترح إجراء تعديل على آلية الانتباه التقليدية في Transformer لجعلها خطية. وبهذه الطريقة، يمكن استخدام النموذج كشبكة عودية: فتمرير المدخلات الخاصة بالطابع الزمني 0 والطابع الزمني 1 معًا يعادل تمرير المدخلات عند الطابع الزمني 0، ثم تمرير المدخلات عند الطابع الزمني 1 مع حالة الطابع الزمني 0 (انظر المثال أدناه).

يمكن أن يكون هذا أكثر كفاءة من نموذج Transformer العادي، ويمكنه التعامل مع جمل بأي طول (حتى لو كان النموذج يستخدم طول سياق ثابتاً للتدريب).

تمت مساهمة هذا النموذج من قِبل sgugger. يمكن العثور على الكود الأصلي هنا.

مثال على الاستخدام

import torch

from transformers import AutoTokenizer, RwkvModel


model = RwkvModel.from_pretrained("sgugger/rwkv-430M-pile", device_map="auto")
tokenizer = AutoTokenizer.from_pretrained("sgugger/rwkv-430M-pile")

inputs = tokenizer("This is an example.", return_tensors="pt").to(model.device)
# Feed everything to the model
outputs = model(inputs["input_ids"])
output_whole = outputs.last_hidden_state

outputs = model(inputs["input_ids"][:, :2])
output_one = outputs.last_hidden_state

# Using the state computed on the first inputs, we will get the same output
outputs = model(inputs["input_ids"][:, 2:], state=outputs.state)
output_two = outputs.last_hidden_state

torch.allclose(torch.cat([output_one, output_two], dim=1), output_whole, atol=1e-5)

إذا كنت ترغب في التأكد من توقف النموذج عن التوليد عند اكتشاف '\n\n'، فننصحك باستخدام معايير التوقف التالية:

from transformers import StoppingCriteria


class RwkvStoppingCriteria(StoppingCriteria):
    def __init__(self, eos_sequence = [187,187], eos_token_id = 537):
        self.eos_sequence = eos_sequence
        self.eos_token_id = eos_token_id

    def __call__(self, input_ids: torch.LongTensor, scores: torch.Tensor, **kwargs) -> bool:
        last_2_ids = input_ids[:,-2:].tolist()
        return self.eos_sequence in last_2_ids


output = model.generate(inputs["input_ids"], max_new_tokens=64, stopping_criteria = [RwkvStoppingCriteria()])

ملاحظات

  • استخدم التعبئة اليسرى (left padding) للتوليد المجمّع. راجع جانب التعبئة.

RwkvConfig

فئة transformers.RwkvConfig

< >

( transformers_version: str | None = Nonearchitectures: list[str] | None = Noneoutput_hidden_states: bool | None = Falsereturn_dict: bool | None = Truedtype: str | torch.dtype | None = Nonechunk_size_feed_forward: int = 0is_encoder_decoder: bool = Falseid2label: dict[int, str] | dict[str, str] | None = Nonelabel2id: dict[str, int] | dict[str, str] | None = Noneproblem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = Nonevocab_size: int = 50277context_length: int = 1024hidden_size: int = 4096num_hidden_layers: int = 32attention_hidden_size: int | None = Noneintermediate_size: int | None = Nonelayer_norm_epsilon: float = 1e-05bos_token_id: int | None = 0eos_token_id: int | list[int] | None = 0rescale_every: int = 6tie_word_embeddings: bool = Falseuse_cache: bool = True )

المعاملات

  • vocab_size (int، اختياري، القيمة الافتراضية 50277) — حجم مفردات النموذج. يحدد عدد الرموز المختلفة التي يمكن تمثيلها بواسطة input_ids.
  • context_length (int، اختياري، القيمة الافتراضية 1024) — أقصى طول تسلسل يمكن استخدام هذا النموذج معه في تمريرة أمامية واحدة (يُتيح استخدامه في وضع RNN استخدام أي طول تسلسل).
  • hidden_size (int، اختياري، القيمة الافتراضية 4096) — أبعاد التمثيلات المخفية.
  • num_hidden_layers (int، اختياري، القيمة الافتراضية 32) — عدد الطبقات المخفية في مُفكِّك Transformer.
  • attention_hidden_size (int, اختياري) — أبعاد حالات الانتباه المخفية. إذا لم يتم ضبطه، فسيتم افتراض hidden_size.
  • intermediate_size (int، اختياري) — أبعاد تمثيلات MLP.
  • layer_norm_epsilon (float، اختياري، القيمة الافتراضية 1e-05) — قيمة الإيبسلون المستخدمة في طبقات تطبيع الطبقة.
  • bos_token_id (int, اختياري، القيمة الافتراضية 0) — معرّف الرمز المستخدم لبدء البث في المفردات.
  • eos_token_id (Union[int, list[int]]، اختياري، القيمة الافتراضية 0) — معرّف الرمز المستخدم لنهاية التدفق في المفردات.
  • rescale_every (int، اختياري، القيمة الافتراضية 6) — عند الاستدلال، تُقسَّم الحالات المخفية (وأوزان طبقات الإخراج المقابلة) على 2 كل rescale_every طبقة. إذا تم ضبطها على 0 أو رقم سالب، فلن يتم إجراء أي إعادة تحجيم.
  • tie_word_embeddings (bool، اختياري، القيمة الافتراضية False) — ما إذا كان سيتم ربط ترميزات الأوزان وفقاً لخريطة tied_weights_keys الخاصة بالنموذج.
  • use_cache (bool، اختياري، القيمة الافتراضية True) — ما إذا كان يجب على النموذج إرجاع قيم المفاتيح/القيم الأخيرة للانتباه (لا تستخدمها جميع النماذج). لا ينطبق إلا إذا كان config.is_decoder=True أو إذا كان النموذج نموذجًا توليديًا يعتمد على المُفكِّك فقط.

هذه فئة الإعدادات المخزنة لإعدادات نموذج RwkvModel. تُستخدم لتوليد نموذج Rwkv وفقاً للحجج المحددة، مع تعريف بنية النموذج. إن إنشاء إعدادات باستخدام القيم الافتراضية سيؤدي إلى الحصول على إعدادات مشابهة لتلك الخاصة بـ RWKV/rwkv-4-169m-pile

ترث كائنات التهيئة من PreTrainedConfig ويمكن استخدامها للتحكم في مخرجات النموذج. اقرأ التوثيق الخاص بـ PreTrainedConfig لمزيد من المعلومات.

مثال:

>>> from transformers import RwkvConfig, RwkvModel

>>> # Initializing a Rwkv configuration
>>> configuration = RwkvConfig()

>>> # Initializing a model (with random weights) from the configuration
>>> model = RwkvModel(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config

RwkvModel

فئة transformers.RwkvModel

< >

( config: RwkvConfig )

المعاملات

  • config (RwkvConfig) — فئة إعدادات النموذج التي تحتوي على جميع معاملات النموذج. لا يؤدي التهيئة باستخدام ملف الإعداد إلى تحميل الأوزان المرتبطة بالنموذج، بل الإعدادات فقط. راجع طريقة from_pretrained() لتحميل أوزان النموذج.

نموذج Rwkv الأساسي الذي يُخرج حالات مخفية خام دون أي رأس محدد في الأعلى.

يرث هذا النموذج من PreTrainedModel. راجع توثيق الفئة الأصلية لمعرفة الطرق العامة التي تنفذها المكتبة لجميع نماذجها (مثل التحميل أو الحفظ، وتغيير حجم تضمينات الإدخال، وقص الرؤوس، وما إلى ذلك).

هذا النموذج هو أيضًا فئة فرعية من torch.nn.Module في PyTorch. استخدمه كوحدة PyTorch عادية، وارجع إلى توثيق PyTorch لكل ما يتعلق بالاستخدام العام والسلوك.

forward

< >

( input_ids: typing.Optional[torch.LongTensor] = Noneattention_mask: typing.Optional[torch.LongTensor] = Noneinputs_embeds: typing.Optional[torch.Tensor] = Nonestate: list[torch.Tensor] | None = Noneuse_cache: bool | None = Noneoutput_attentions: bool | None = Noneoutput_hidden_states: bool | None = Nonereturn_dict: bool | None = None**kwargs ) → RwkvOutput or tuple(torch.Tensor)

المعاملات

  • input_ids (torch.LongTensor بشكل (batch_size, input_ids_length)) — input_ids_length = sequence_length إذا كان past_key_values هو None وإلا past_key_values.get_seq_length() (sequence_length طول سلسلة الإدخال لحالات المفاتيح والقيم السابقة). فهارس رموز سلسلة الإدخال في قاموس النموذج.

    إذا تم استخدام past_key_values، فيجب تمرير input_ids التي لم يتم حساب قيمها السابقة فقط كـ input_ids.

    يمكن الحصول على الفهارس باستخدام AutoTokenizer. راجع PreTrainedTokenizer.encode() و PreTrainedTokenizer.call() للتفاصيل.

    ما هي معرّفات الإدخال؟

  • attention_mask (torch.LongTensor بشكل (batch_size, sequence_length), اختياري) — قناع لتجنب تنفيذ الانتباه على فهارس رموز الحشو. القيم المختارة للقناع في [0, 1]:
    • 1 للرموز التي لم تُقنَّع،
    • 0 للرموز التي تم إخفاؤها.

    ما هي أقنعة الانتباه؟

  • inputs_embeds (torch.Tensor من الشكل (batch_size, sequence_length, hidden_size)، اختياري) — اختياريًا، بدلاً من تمرير input_ids، يمكنك اختيار تمرير تمثيل مضمّن مباشرة. وهذا مفيد إذا كنت ترغب في الحصول على مزيد من التحكم في كيفية تحويل فهارس input_ids إلى المتجهات المرتبطة بها، مقارنةً بمصفوفة البحث المضمّنة الداخلية للنموذج.
  • state (tuple من خمسة torch.Tensor على شكل (batch_size, hidden_size, num_hidden_layers)، اختياري) — إذا تم تمريره، يستخدم النموذج الحالة السابقة في جميع الكتل (مما سيُنتج المخرجات الخاصة بـ input_ids المُقدَّمة وكأن النموذج أضاف state_input_ids + input_ids كسياق).
  • use_cache (bool، اختياري) — إذا تم تعيينه إلى True، يُعاد آخر حالة ويمكن استخدامه لتوليد logits التالية بسرعة.
  • output_attentions (bool، اختياري) — ما إذا كان يجب إرجاع تensors الانتباه لجميع طبقات الانتباه أم لا. راجع attentions ضمن tensors المُرجعة لمزيد من التفاصيل.
  • output_hidden_states (bool، اختياري) — ما إذا كان يجب إرجاع حالات الطبقات المخفية لجميع الطبقات. راجع hidden_states ضمن الموترات المُرجعة للحصول على مزيد من التفاصيل.
  • return_dict (bool، اختياري) — ما إذا كان يجب إرجاع ModelOutput بدلاً من tuple عادي.

يعيد

RwkvOutput أو tuple(torch.Tensor)

RwkvOutput أو مجموعة مرتبة من torch.Tensor (في حال تمرير return_dict=False أو عندما يكون config.return_dict=False) وتتضمن عناصر مختلفة تعتمد على الإعداد (RwkvConfig) والمدخلات.

تتجاوز طريقة RwkvModel الخاصة بالتقديم (forward) الطريقة الخاصة __call__.

على الرغم من أنه يجب تعريف وصفة المرور الأمامي داخل هذه الدالة، إلا أنه ينبغي استدعاء كائن Module بدلاً من هذه الدالة، لأن الكائن يتولى تنفيذ خطوات المعالجة المسبقة والمعالجة اللاحقة، بينما تتجاهل الدالة هذه الخطوات بصمت.

  • last_hidden_state (torch.Tensor من الشكل (batch_size, sequence_length, hidden_size)، اختياري) — تسلسل حالات مخفية عند مخرجات الطبقة الأخيرة من النموذج.

  • state (list من خمسة torch.Tensor بأبعاد (batch_size, hidden_size, num_hidden_layers)) — حالة النموذج عند آخر خطوة زمنية. يمكن استخدامها في طريقة forward مع input_ids التالية لتجنب تقديم input_ids القديمة.

  • hidden_states (tuple[torch.Tensor, ...]، اختياري، يُعاد عند تمرير output_hidden_states=True أو عند تعيين config.output_hidden_states=True) — مجموعة من torch.Tensor (واحدة لإخراج الطبقات المضمنة، إذا كان النموذج يحتوي على طبقة تضمين، + واحدة لإخراج كل طبقة) بأبعاد (batch_size, sequence_length, hidden_size).

    حالات النموذج المخفية عند مخرج كل طبقة بالإضافة إلى مخرجات التضمين الأولي الاختيارية.

  • attentions (tuple[torch.Tensor, ...]، اختياري، يُعاد عند تمرير output_attentions=True أو عند تعيين config.output_attentions=True) — مجموعة من torch.Tensor (واحدة لكل طبقة) بأبعاد (batch_size, num_heads, sequence_length, sequence_length).

    أوزان الانتباه بعد تطبيق دالة softmax على الانتباه، وتُستخدم لحساب المتوسط الموزون في رؤوس الانتباه الذاتي.

RwkvLMHeadModel

فئة transformers.RwkvForCausalLM

< >

( config: RwkvConfig )

المعاملات

  • config (RwkvConfig) — فئة إعدادات النموذج التي تحتوي على جميع معاملات النموذج. لا يؤدي التهيئة باستخدام ملف الإعداد إلى تحميل الأوزان المرتبطة بالنموذج، بل الإعدادات فقط. راجع طريقة from_pretrained() لتحميل أوزان النموذج.

نموذج RWKV Transformer مع رأس لنمذجة اللغة في الأعلى (طبقة خطية بأوزان مرتبطة بتضمينات الإدخال).

يرث هذا النموذج من PreTrainedModel. راجع توثيق الفئة الأصلية لمعرفة الطرق العامة التي تنفذها المكتبة لجميع نماذجها (مثل التحميل أو الحفظ، وتغيير حجم تضمينات الإدخال، وقص الرؤوس، وما إلى ذلك).

هذا النموذج هو أيضًا فئة فرعية من torch.nn.Module في PyTorch. استخدمه كوحدة PyTorch عادية، وارجع إلى توثيق PyTorch لكل ما يتعلق بالاستخدام العام والسلوك.

forward

< >

( input_ids: typing.Optional[torch.LongTensor] = Noneattention_mask: typing.Optional[torch.LongTensor] = Noneinputs_embeds: typing.Optional[torch.Tensor] = Nonestate: list[torch.Tensor] | None = Nonelabels: typing.Optional[torch.LongTensor] = Noneuse_cache: bool | None = Noneoutput_attentions: bool | None = Noneoutput_hidden_states: bool | None = Nonereturn_dict: bool | None = Nonelogits_to_keep: typing.Union[int, torch.Tensor] = 0**kwargs ) → RwkvCausalLMOutput or tuple(torch.Tensor)

المعاملات

  • input_ids (torch.LongTensor بشكل (batch_size, input_ids_length)) — input_ids_length = sequence_length إذا كان past_key_values هو None وإلا past_key_values.get_seq_length() (sequence_length طول سلسلة الإدخال لحالات المفاتيح والقيم السابقة). فهارس رموز سلسلة الإدخال في قاموس النموذج.

    إذا تم استخدام past_key_values، فيجب تمرير input_ids التي لم يتم حساب قيمها السابقة فقط كـ input_ids.

    يمكن الحصول على الفهارس باستخدام AutoTokenizer. راجع PreTrainedTokenizer.encode() و PreTrainedTokenizer.call() للتفاصيل.

    ما هي معرّفات الإدخال؟

  • attention_mask (torch.LongTensor بشكل (batch_size, sequence_length), اختياري) — قناع لتجنب تنفيذ الانتباه على فهارس رموز الحشو. القيم المختارة للقناع في [0, 1]:
    • 1 للرموز التي لم تُقنَّع،
    • 0 للرموز التي تم إخفاؤها.

    ما هي أقنعة الانتباه؟

  • inputs_embeds (torch.Tensor من الشكل (batch_size, sequence_length, hidden_size)، اختياري) — اختياريًا، بدلاً من تمرير input_ids، يمكنك اختيار تمرير تمثيل مضمّن مباشرة. وهذا مفيد إذا كنت ترغب في الحصول على مزيد من التحكم في كيفية تحويل فهارس input_ids إلى المتجهات المرتبطة بها، مقارنةً بمصفوفة البحث المضمّنة الداخلية للنموذج.
  • state (tuple من خمسة torch.Tensor على شكل (batch_size, hidden_size, num_hidden_layers)، اختياري) — إذا تم تمريره، يستخدم النموذج الحالة السابقة في جميع الكتل (مما سيُنتج المخرجات الخاصة بـ input_ids المُقدَّمة وكأن النموذج أضاف state_input_ids + input_ids كسياق).
  • labels (torch.LongTensor من الشكل (batch_size, sequence_length)، اختياري) — التسميات لنمذجة اللغة. لاحظ أن التسميات تُزاح داخل النموذج، أي يمكنك تعيين labels = input_ids يتم اختيار الفهارس من [-100, 0, ..., config.vocab_size] تُتجاهل (تُقنَّع) جميع التسميات المعينة إلى -100 ويتم حساب الخسارة فقط للتسميات الموجودة في [0, ..., config.vocab_size]
  • use_cache (bool، اختياري) — إذا تم تعيينه إلى True، يُعاد آخر حالة ويمكن استخدامه لتوليد logits التالية بسرعة.
  • output_attentions (bool، اختياري) — ما إذا كان يجب إرجاع تensors الانتباه لجميع طبقات الانتباه أم لا. راجع attentions ضمن tensors المُرجعة لمزيد من التفاصيل.
  • output_hidden_states (bool، اختياري) — ما إذا كان يجب إرجاع حالات الطبقات المخفية لجميع الطبقات. راجع hidden_states ضمن الموترات المُرجعة للحصول على مزيد من التفاصيل.
  • return_dict (bool، اختياري) — ما إذا كان يجب إرجاع ModelOutput بدلاً من tuple عادي.
  • logits_to_keep (Union[int, torch.Tensor]، اختياري، القيمة الافتراضية 0) — إذا كان int، يتم حساب logits لآخر logits_to_keep رموز. إذا كانت القيمة 0، يتم حساب logits لجميع input_ids (حالة خاصة). لا يُحتاج إلى logits إلا للرمز الأخير في عملية التوليد، ويمكن أن يوفر حسابها لذلك الرمز وحده ذاكرة كبيرة، وهو أمر مهم بشكل ملحوظ للتسلسلات الطويلة أو حجم المفردات الكبير. إذا كان torch.Tensor، يجب أن يكون بعدًا واحدًا (1D) ويتوافق مع الفهارس التي يجب الاحتفاظ بها في بُعد طول التسلسل. يكون هذا مفيدًا عند استخدام تنسيق المصفوفات المعبأة (packed tensor format) (بعد واحد لكل من الدفعة وطول التسلسل).

يعيد

RwkvCausalLMOutput أو tuple(torch.Tensor)

RwkvCausalLMOutput أو مجموعة مرتبة من torch.Tensor (في حال تمرير return_dict=False أو عندما يكون config.return_dict=False) وتتضمن عناصر مختلفة تعتمد على الإعداد (RwkvConfig) والمدخلات.

تُعيد طريقة RwkvForCausalLM الخاصة بالتقديم (forward) تعريف الطريقة الخاصة __call__.

على الرغم من أنه يجب تعريف وصفة المرور الأمامي داخل هذه الدالة، إلا أنه ينبغي استدعاء كائن Module بدلاً من هذه الدالة، لأن الكائن يتولى تنفيذ خطوات المعالجة المسبقة والمعالجة اللاحقة، بينما تتجاهل الدالة هذه الخطوات بصمت.

  • loss (torch.Tensor of shape (1,), اختياري, يُعاد عند توفير labels) — خسارة نمذجة اللغة (لتوقع الرمز التالي).

  • logits (torch.Tensor من الشكل (batch_size, sequence_length, config.vocab_size)) — درجات التنبؤ لرأس نمذجة اللغة (درجات لكل رمز في المفردات قبل SoftMax).

  • state (list من خمسة torch.Tensor بأبعاد (batch_size, hidden_size, num_hidden_layers)) — حالة النموذج عند آخر خطوة زمنية. يمكن استخدامها في طريقة الأمامية مع input_ids التالية لتجنب تقديم input_ids القديمة.

  • hidden_states (tuple[torch.Tensor, ...]، اختياري، يُعاد عند تمرير output_hidden_states=True أو عند تعيين config.output_hidden_states=True) — مجموعة من torch.Tensor (واحدة لإخراج الطبقات المضمنة، إذا كان النموذج يحتوي على طبقة تضمين، + واحدة لإخراج كل طبقة) بأبعاد (batch_size, sequence_length, hidden_size).

    حالات النموذج المخفية عند مخرج كل طبقة بالإضافة إلى مخرجات التضمين الأولي الاختيارية.

  • attentions (tuple[torch.Tensor, ...]، اختياري، يُعاد عند تمرير output_attentions=True أو عند تعيين config.output_attentions=True) — مجموعة من torch.Tensor (واحدة لكل طبقة) بأبعاد (batch_size, num_heads, sequence_length, sequence_length).

    أوزان الانتباه بعد تطبيق دالة softmax على الانتباه، وتُستخدم لحساب المتوسط الموزون في رؤوس الانتباه الذاتي.

مثال:

انتباه Rwkv والصيغ التكرارية

في نموذج Transformer ذاتي التوليد تقليدي، تُكتب عملية الانتباه على النحو التالي O=softmax(QKT/d)VO = \hbox{softmax}(QK^{T} / \sqrt{d}) V

مع $Q$، KK و VV مصفوفات ذات أبعاد seq_len x hidden_size تُسمى الاستعلام والمفتاح والقيمة (في الواقع هي مصفوفات أكبر تحتوي على بُعد الدفعة وبُعد رأس الانتباه، لكننا نهتم فقط بالأبعاد الأخيرة حيث يتم حساب ضرب المصفوفات، لذا سنكتفي بها فقط من أجل التبسيط). يكون ناتج الضرب QKTQK^{T} ذو أبعاد seq_len x seq_len ونستطيع أخذ ضرب المصفوفات مع VV للحصول على المخرج OO ذو الأبعاد نفسها مثل المصفوفات الأخرى.

عند استبدال softmax بقيمته نحصل على: Oi=∑j=1ieQiKjT/dVj∑j=1ieQiKjT/dO_{i} = \frac{\sum_{j=1}^{i} e^{Q_{i} K_{j}^{T} / \sqrt{d}} V_{j}}{\sum_{j=1}^{i} e^{Q_{i} K_{j}^{T} / \sqrt{d}}}

لاحظ أن العناصر في QKTQK^{T} المقابلة لـ $j > i$ تكون مقنّعة (تتوقف عملية الجمع عند j) لأن الانتباه لا يُسمح له بالنظر إلى الرموز المستقبلية (بل إلى الرموز السابقة فقط).

بالمقارنة، تُعطى آلية الانتباه في RWKV بالصيغة التالية Oi=σ(Ri)∑j=1ieWi−j+KjVj∑j=1ieWi−j+KjO_{i} = \sigma(R_{i}) \frac{\sum_{j=1}^{i} e^{W_{i-j} + K_{j}} V_{j}}{\sum_{j=1}^{i} e^{W_{i-j} + K_{j}}}

حيث RR مصفوفة جديدة يسمّيها المؤلف مصفوفة الاستجابة، KK و VV ما زالا المفتاح والقيمة (حيث $\sigma$ هنا هي دالة سيجمويد). WW متجه جديد يمثل موضع الرمز ويُعطى بـ W0=u and Wk=(k−1)w for k≥1W_{0} = u \hbox{ and } W_{k} = (k-1)w \hbox{ for } k \geq 1

مع uu و ww معلمات قابلة للتعلم تُسمى في الكود time_first و time_decay على التوالي. يمكن التعبير عن البسط والمقام بشكل تكراري. إذا سمّيناها NiN_{i} و DiD_{i} فإننا نحصل على: Ni=eu+KiVi+N^i where N^i=eKi−1Vi−1+ew+Ki−2Vi−2⋯+e(i−2)w+K1V1N_{i} = e^{u + K_{i}} V_{i} + \hat{N}_{i} \hbox{ where } \hat{N}_{i} = e^{K_{i-1}} V_{i-1} + e^{w + K_{i-2}} V_{i-2} \cdots + e^{(i-2)w + K_{1}} V_{1}

بحيث N^i\hat{N}_{i} (المُسمّى numerator_state في الكود) يحقق N^0=0 and N^j+1=eKjVj+ewN^j\hat{N}_{0} = 0 \hbox{ and } \hat{N}_{j+1} = e^{K_{j}} V_{j} + e^{w} \hat{N}_{j}

و Di=eu+Ki+D^i where D^i=eKi−1+ew+Ki−2⋯+e(i−2)w+K1D_{i} = e^{u + K_{i}} + \hat{D}_{i} \hbox{ where } \hat{D}_{i} = e^{K_{i-1}} + e^{w + K_{i-2}} \cdots + e^{(i-2)w + K_{1}}

لذا D^i\hat{D}_{i} (المعروف باسم denominator_state في الكود) يحقق D^0=0 and D^j+1=eKj+ewD^j\hat{D}_{0} = 0 \hbox{ and } \hat{D}_{j+1} = e^{K_{j}} + e^{w} \hat{D}_{j}

الصيغة التكرارية الفعلية المستخدمة أكثر تعقيدًا قليلاً، فبدافع الاستقرار العددي، لا نرغب في حساب أسس أرقام كبيرة. عادةً لا يُحسب softmax كما هو، بل يُقسَّم الأس الأقصى على البسط والمقام: exi∑j=1nexj=exi−M∑j=1nexj−M\frac{e^{x_{i}}}{\sum_{j=1}^{n} e^{x_{j}}} = \frac{e^{x_{i} - M}}{\sum_{j=1}^{n} e^{x_{j} - M}}

مع MM القيمة العظمى لجميع $x_{j}$. لذا، هنا، بالإضافة إلى حفظ حالة البسط ($\hat{N}$) وحالة المقام ($\hat{D}$)، نتتبع أيضًا القيمة العظمى لجميع الحدود التي تظهر في الدوال الأسية. لذا، نستخدم فعليًا N~i=e−MiN^i and D~i=e−MiD^i\tilde{N}_{i} = e^{-M_{i}} \hat{N}_{i} \hbox{ and } \tilde{D}_{i} = e^{-M_{i}} \hat{D}_{i}

المُعرَّفة بالمعادلات التكرارية التالية: N~0=0 and N~j+1=eKj−qVj+ew+Mj−qN~j where q=max⁡(Kj,w+Mj)\tilde{N}_{0} = 0 \hbox{ and } \tilde{N}_{j+1} = e^{K_{j} - q} V_{j} + e^{w + M_{j} - q} \tilde{N}_{j} \hbox{ where } q = \max(K_{j}, w + M_{j})

و D~0=0 and D~j+1=eKj−q+ew+Mj−qD~j where q=max⁡(Kj,w+Mj)\tilde{D}_{0} = 0 \hbox{ and } \tilde{D}_{j+1} = e^{K_{j} - q} + e^{w + M_{j} - q} \tilde{D}_{j} \hbox{ where } q = \max(K_{j}, w + M_{j})

و $M_{j+1} = q$. باستخدام هذه القيم، يمكننا بعد ذلك حساب Ni=eu+Ki−qVi+eMiN~i where q=max⁡(u+Ki,Mi)N_{i} = e^{u + K_{i} - q} V_{i} + e^{M_{i}} \tilde{N}_{i} \hbox{ where } q = \max(u + K_{i}, M_{i})

و Di=eu+Ki−q+eMiD~i where q=max⁡(u+Ki,Mi)D_{i} = e^{u + K_{i} - q} + e^{M_{i}} \tilde{D}_{i} \hbox{ where } q = \max(u + K_{i}, M_{i})

والذي يمنحنا في النهاية Oi=σ(Ri)NiDiO_{i} = \sigma(R_{i}) \frac{N_{i}}{D_{i}}

Update on GitHub