# پارت 2 : معماری ترنسفورمرها را به صورت جز به جز و قسمت به قسمت کامل باز می کنیم با مثال و کد
ماتریس چیست؟ کنترل. ماتریس یک دنیای رویایی تولید شده توسط کامپیوتر است، ساخته شده تا ما را تحت کنترل نگه دارد به منظور تبدیل یک انسان به این.
The Matrix (1991)
نکته: "تمام کد هایی که در این مقاله آورده شده است در گوگل کلب تست شده و خروجی گرفته شده است کد ها حالت شبه کد دارند و برای پروژه خاصی نیست و بیشتر جنبه فهمیدن کامل تر موضوع را دارند"
در پارت 1 راجع به مهم ترین اصطلاحاتی که در معماری Transformer وجود دارد صحبت کردیم. برای درک بهتر معماری آن باید ابتدا آنها را یاد می گرفتیم. در پارت 2 می خواهیم به صورت کامل معماری اصلی Transformer را قسمت به قسمت بررسی کنیم و منطق پشت آن را بفهمیم و ببینیم که همه اطلاحاتی که در پارت 1 بیان شد چگونه به کار برده می شوند. در واقع می خواهیم ببینیم وظیفه اصلی Transformer چیست ؟ جادویی که الان میبینیم برای ساختن مدلهای قدرتمند مثل Chat GPT یا LlaMA و خیلی از مدل های قدرتمند دیگر چطور به وجود آمده اند. البته این نکته را هم باید ذکر کنیم که بعد از معماری اصلی و اولیه Transformer ها مدل های دیگری هم پیشنهاد شد و تسک های جدیدی هم به آن اظافه شد. از جمله اینکه امروز استفاده از Transformer برای بینایی ماشین (مدلهایی مانند DETR (Detection Transformer) از توجه برای یافتن اشیاء در تصاویر به طور مستقیم، بدون نیاز به مراحل میانی مانند پیشنهاد منطقه استفاده میکنند.) یا تحلیل احساس و خیلی تسک های دیگر مورد استفاده قرار می گیرد. همچنین مثالهایی را بررسی خواهیم کرد و در کد نیز خواهیم دید. به چالش های اصلی آن و راه هایی برای رفع این چالشها خواهیم پرداخت و در پایان انواع مدل های Transformer که وجود دارد و یا پیشنهاد داده شده است را خواهیم آموخت . با من همراه شوید تا ببینیم تغییر چهره دنیای حاضر چطور آغاز شده و چطور در حال انجام است. آماده اید !؟
معماری بسیار قدرتمند و تقزیبا پیچیده ای دارد. از دو بخش اصلی Encoder و Decoder تشکیل شده است. هر کدام از این بخش ها درون خود داری بلوک های دیگری هستند. زمانی که از Transformer برای انجام تسکی استفاده می کنیم این معماری بارها و بارها تکرار خواهد شد. همانطور که در تصویر مقاله اصلی هم می بینیم در هر جز Encoder و Decoder نوشته شده است “Nx” به معنای تکرار به هر تعداد لازم است. اجزا بسیار هنرمندانه و جادویی با هم ارتباط دارند. هر کدام از بلوک ها وظایف خاصی را انجام می دهند. مانند هر چیز دیگری وقتی معماری Transformer برای اولین بار معرفی شد، چند مشکل اصلی وجود داشت. یکی از آنها پیچیدگی محاسباتی است چرا که برای بررسی ارتباطات بین تمام ورودیها و خروجیها از ماتریس Attention استفاده میکند. این باعث میشود تا پیچیدگی محاسباتی بالا رود و منجر به نیاز به منابع محاسباتی بیشتر شود. برای کار کردن بهتر، Transformer نیاز به دادههای آموزش بسیار بزرگ دارد، مخصوصا در صورت استفاده از معماری ترجمه ماشینی. مقاله اصلی معماری Transformer تلاش کرد تا برخی از این مشکلات را حل کند. از جمله اضافه کردن تکنیکهایی مانند Dropout به معماری Transformer برای کاهش اورفیتینگ و بهبود عملکرد مدل در دادههای تست. مقالههای بعدی تلاش کردند تا معماریهای جدیدی ارائه دهند که به مشکلات اصلی Transformer پاسخ دهند، مانند افزودن لایههای Convolutional به معماری، استفاده از attention مبتنی بر ویژگیها، و یا استفاده از معماریهای Transformer با توجه به ویژگیهای خاص دادهها مانند WaveNet برای پردازش صوتی. استفاده از الگوریتمهای بهبود یافته آموزشی مانند AdamW برای بهبود سرعت و کارایی آموزش مدلهای Transformer. در قسمت های بعد به بررسی کامل جز به جز لایه های معماری Transformerخواهیم پرداخت.
در معماری Transformer نقش بسیار مهمی دارد. وظیفهی اصلی Encoder فهم و فشردهسازی اطلاعات ورودی است. یعنی ورودی را فهمیده و اطلاعات مهم و کلیدی را از آنها استخراج کند. Encoder از یک یا چند لایه عصبی تشکیل شده است هر لایه از Encoder معمولاً شامل دو بخش اصلی است. Multi-head Attention (MHA) این بخش به ورودیهای خود نگاه میکند و ارتباطات بین تمام کلمات یا توالیها را مدیریت میکند. برای هر ورودی، مدل Attention Score را محاسبه میکند تا برای هر کلمه توجهی به کلمات دیگر در جمله یا توالی داشته باشد. MHA به کمک ماتریسهای Query، Key و Value، ارتباطات بین کلمات را محاسبه میکند و سپس اطلاعات مهم را با توجه به این ارتباطات استخراج میکند. یک لایه Feedforward Neural Network اطلاعات استخراج شده از MHA را با استفاده از یک شبکه عصبی Feedforward پردازش میکند تا توالی دادههای ورودی مانند کلمات در یک جمله، فریمهای ویدیویا هر نوع توالی دیگری را به عنوان ورودی دریافت و اطلاعات مهم و کلیدی را با استفاده از توابع غیرخطی و تکنیکهایی مانند وزندهی و فعالسازی پردازش میکنند. در ادامه میخواهیم لایه به لایه در Encoder پیش برویم و ببینیم که چطور کار میکند.
هرچند که معمولاً معماری Transformer از این ساختار اصلی برای Encoderاستفاده میکند، اما مدلهایی همچون BERT، GPT و T5 از این معماری تغییراتی اعمال کردهاند و از ترکیبها و تغییراتی بر این مدل اصلی استفاده میکنند تا به مسائل خاصی که با آنها روبرو هستند پاسخ دهند. به عنوان مثال، BERT از تکنیک MLM (Masked Language Modeling) برای آموزش استفاده میکند. در MLM، بخشی از کلمات در یک جمله پنهان میشود و مدل باید کلمات پنهان را بر اساس کلمات اطراف پیشبینی کند. در GPT از MLM به همراه Autoregressive Language Modeling برای آموزش استفاده میکند. در Autoregressive Language Modeling، مدل باید کلمه بعدی در یک جمله را بر اساس کلمات قبلی پیشبینی کند. این امر به GPT کمک میکند تا تولید متن روان و طبیعی را یاد بگیرد. در T5 (Text-to-Text Transfer Transformer) از یک معماری چندوظیفهای استفاده میکند.تا وظایف مختلف پردازش زبان طبیعی مانند ترجمه، خلاصهسازی و پاسخ به سوال را یاد بگیرد.
در معماری Transformer ابتدا کلمات یا عناصر دنباله ورودی با استفاده از Embedding Layer به بردارهای Embedding تبدیل میشوند که اغلب بعد کمتری نسبت به بردارهای one-hot encoding دارند و اطلاعات معنایی و مضمونی را بهتر بازنمایی میکنند. این بردارهای Embedding به لایههای Encoder ارسال میشوند. لایه Embedding Layer معمولاً با استفاده از یک ماتریس Embedding حاوی بردارهایی برای هر واژه یا عنصر در واژگان ایجاد میشود. این بردارها به طور کلی از روشهایی مانند Word2Vec، GloVe یا FastText به دست میآیند. فرض کنید دنباله ورودی شما شامل کلمات "سلام"، "دنیا"، "خوبی" باشد. به طور مثال، "سلام" ممکن است به بردار Embedding [0.2, 0.5, -0.1]، "دنیا" به بردار Embedding [-0.3, 0.8, 0.6] و "خوبی" به بردار Embedding [0.1, -0.7, 0.4] تبدیل شوند. لایه Embedding در کتابخانههای محبوب مانند TensorFlow یا PyTorch، به صورت آماده در دسترس است و میتوانیم از آنها به راحتی استفاده کنیم.
import torch
import torch.nn as nn
# Define the Embedding Layer
embedding_layer = nn.Embedding(10000, 300)
# Sample input data
input_data = torch.tensor([1, 5, 7, 2])
# Transform the input data into embeddings
embedded_output = embedding_layer(input_data)
# Display the dimensions of the output
print("Embedding Layer output dimensions:", embedded_output.size())
در این کد، Embedding Layer با استفاده از کلاس` `nn.Embedding از کتابخانه PyTorch تعریف میشود. این لایه دو پارامتر دارد: تعداد کلمات در واژگان (10000) و اندازه بردار Embedding برای هر کلمه (300). سپس، یک داده ورودی نمونه به صورت یک تنسور PyTorch تعریف میشود که حاوی چند شماره کلمه است که به عنوان ورودی به Embedding Layer ارسال میشود وEmbedding Layer بردارEmbedding مربوط به هر کلمه را به عنوان خروجی تولید میکند. در نهایت، ابعاد خروجی Embedding Layer نمایش داده میشود و بردارهای Embedding متناظر با کلمات ورودی نمایش داده میشود.
در مدلهای Transformer، برخلاف مدلهای سنتی شبکههای عصبی بازگشتی که به توالی ورودیها وابسته هستند، هیچ نوع اطلاعات مکانی به صورت ضمنی به مدل ارائه نمیشود، بنابراین از طبقهبندی موقعیتی) (Positional Encoder برای دادن اطلاعات مکانی به توکنهای ورودی استفاده میشود تا مکان آن در دنباله را نمایان کند. تبدیل توکنها به بردارهای Embedding بدون در نظر گرفتن مکان و ترتیب آنها ممکن است اطلاعات مهمی را از دست بدهد. با اضافه کردن اطلاعات مکانی با استفاده از Positional Encoder، میتوان این اطلاعات را حفظ کرد و مدل را قادر به تمایز دادن بین توکنهای مختلف در یک دنباله کرد. این ویژگی یعنی درک و توجه به ترتیب و مکان توکنها در دنباله را فراهم میکند که این موضوع به بهبود عملکرد و کارایی مدل در وظایف مختلف پردازش زبانی کمک میکند.
این بردار مکانی معمولاً به صورت یک بردار یا ماتریس به ابعاد مشخصی تولید میشود. یکی از روشهای معمول استفاده از توابعی مانند سینوس و کسینوس است که به ازای هر مکان مختلف در دنباله یک مقدار منحصر به فرد ایجاد میکنند. به عبارت دیگر، Positional Encoder توکنهای ورودی را با اطلاعات مکانی مجهز میکند تا مدل بتواند ترتیب و مکان توکنها را در نظر بگیرد و از این اطلاعات برای تولید خروجی مناسب استفاده کند.
طبقهبندی موقعیتی Positional Encoder معمولاً بلافاصله پس از Embedding Layer در مدل Transformer قرار میگیرد. در زیر یک مثال ساده با استفاده از کتابخانه PyTorch میبینید که نحوه اضافه کردن اطلاعات مکانی به توکنهای ورودی با استفاده از Positional Encoder را نشان می دهد.
import torch
import torch.nn as nn
import math
class PositionalEncoder(nn.Module):
def __init__(self, d_model, max_len=1000):
super(PositionalEncoder, self).__init__()
self.d_model = d_model
# Initialize the positional encoding matrix
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
# Register as buffer so it's not updated during training
self.register_buffer('pe', pe)
def forward(self, x):
# Add the positional encoding to the input
x = x + self.pe[:, :x.size(1)]
return x
کلاس`PositionalEncoder` که از کلاس` nn.Module` ارثبری میکند، ابتدا متغیرهای اصلی مانند اندازه بردار` Embedding (d_model) `و حداکثر طول دنباله `(max_len)` تعیین میشوند. سپس، ماتریس مکانی با ابعاد` (max_len, d_model)` ایجاد میشود که همه مقادیر آن ابتدا با صفر پر میشوند. سپس، برای هر مکان در دنباله، مقادیر متغیرهای sinusoidal position encoding محاسبه میشوند و در ماتریس مکانی قرار داده میشوند. در نهایت، ماتریس مکانی به عنوان یک buffer ثبت میشود تا در فرآیند آموزش مدل آپدیت نشود.
یکی از بخش های بسیار مهم معماری Transformer و شاید بتونیم بگیم مهم ترین بخش اون MHA باشد. چرا که قلب تپنده Transformer ها همین Attention است. در پارت 1 راجع به انواع Attention و خود MHA هم صحبت کردیم و همچنین راجع به Scaled Dot-Product Attention حال می خواهیم ببینیم توضیحاتی که در پارت 1 گفته شد و مطالبی که در مورد نحوه محاسبه (Q, K, V) چه هستند و چه کارایی دارند. به تصویر زیر که از مقاله اصلی گرفته شده است دقت کنید.
بعد از مرحله Positional Encoder داده ها آماده وارد شدن به Multi-head Attention هستند که پردازش های لازم روی اونها صورت بگیرد و مراحل Attention انجام بشه که مثلا برای تسک ترجمه ماشینی که در مقاله اصلی هم انجام شده و مهم ترین کلمات و رابطه اونها رو با همدیگه بفهمیم. برای این کار بردارهای Embedding که تشکیل شده به وسیله سه (Q, K, V) وارد Multi-head Attention می شوند. انها با تابع Linear وارد Scaled Dot-Product Attention میشن و زمانیکه) (Q, K محاسبه میشوند (به نوعی ضرب داخلی انجام میشود = MatMul) با تابع Softmax مقادیر ماتریکس بین (1و0) قرار می گیرد. و بعد با مقدار V مجددا MatMul انجام می شود. سپس باز هم با تابع Linear وارد لایه add & Norm می شوند. اما چرا این کار انجام می شود؟ به این خاطر که از Vanishing Gradient Problem در مرحله backpropagation جلوگیری شود و اگر این کار انجام نشه در این مسیر که مشتق گیری انجام میشه مشتق ها به حدی کوچک و نزدیک صفر می شوند که عملا دیگر مقداری وجود ندارد. در معماری اصلی یک Residual connections را هم می بینیم که قبل از اینکه مقدار ها با (Q, K, V) محاسبه بشن به وسیله اون به Layer Normalization وارد میشن و این کار هم برای جلوگیری از نزول گرادیان هست. ، اگر از Residual Connections استفاده نشود، امکان دارد Attention برخی از لایهها به مراحل بعدی از شبکه به دلیل V G P ، کمتر بشه که منجر به از دست رفتن اطلاعات مهم یا کاهش کارایی شبکه شود. همانطور که در شکل بالا میبینید در مقاله اصلی در هر مرحله Multi-head Attention h = 8 لایه استفاده شده است. در مرحله بعد داده ها وارد add & Norm میشن که در قسمت بعد بررسی خواهیم کرد.
همه لایههای معماری Transformers از تکنیک های Normalization شامل محاسبه میانگین و واریانس برای هر ویژگی یا ورودی از دادهها است که از روش های Layer Normalization یا Batch Normalization استفاده می شود. خروجیهای مرحله MHA میتواند مقادیر گستردهای داشته باشند، و Normalization آنها میتواند به فرآیند آموزش کمک کند. Normalization اثر انحراف داخلی متغیر را که ممکن است هنگام آموزش تغییر کند کاهش می دهد، تا شبکه به موارد جدیدی که قبلاً دیده نشدهاند، پاسخ دهد. بعد از این مراحل، ورودیها به لایههای بعدی از شبکه منتقل میشوند. وقتی که از Normalization خارج میشوند و به لایه Feedforward میروند، آنها با استفاده از توابع فعالسازی مانند ReLU (Rectified Linear Activation) یا GELU (Gaussian Error Linear Unit) وارد فرآیند Feedforward میشوند. لایه Normalization از بزرگ یا کوچک شدن بیش از حد Gradient ها و در نتیجه از مشکلاتی مانند "gradient explosion" و "gradient vanishing" جلوگیری می کند. در آموزش مدلهای عمیق، ویژگیهای ورودی ممکن است در طول زمان تغییر کنند که به عنوان Covariate Shift شناخته میشود. Normalization لایهها میتواند این اثرات را کاهش داده و به سرعت آموزش کمک کند. حال میخواهیم در یک نمونه کد پایتونی با استفاده از کتابخانه PyTorch ببینیم که این لایه چطور پیاده سازی می شود :
import torch
import torch.nn as nn
class AddNormLayer(nn.Module):
def __init__(self, input_dim):
super(AddNormLayer, self).__init__()
self.norm = nn.LayerNorm(input_dim)
def forward(self, x):
# Add step: Adding input to the output of the layer
added = x + torch.randn_like(x)
# Norm step: Normalizing the output values
normalized = self.norm(added)
return normalized
# Using the Add & Norm layer
input_dim = 512
layer = AddNormLayer(input_dim)
# Example input
input_data = torch.randn(10, input_dim)
# Applying the layer on the input
output = layer(input_data)
print(output.shape) # Output size
در کد بالا، ما یک لایه سفارشی به نام `AddNormLayer` با استفاده از کتابخانه PyTorch پیادهسازی کردهایم که شامل دو بخش است. مرحله اول `Add` است که در این بخش، ورودی به یک نویز تصادفی اضافه میشود. برای این کار، ابتدا به هر بردار ورودی یک بردار نویز تصادفی با همان ابعاد اضافه میکنیم. این بردار نویز با استفاده از `torch.randn_like(x)` ایجاد میشود که مقدارهای تصادفی از توزیع نرمال با همان ابعاد ورودی را ایجاد میکند. سپس این بردار نویز به ورودی اضافه میشود و در مرحله Norm ، مقادیر خروجی حاصل از مرحله Add را نرمالسازی میکنیم. برای این کار، از یک لایه نرمالسازی به نام `nn.LayerNorm` استفاده میکنیم که ابعاد ورودی را نرمالسازی میکند. در نهایت، این لایه سفارشی را با یک مثال ورودی اعمال کرده و ابعاد خروجی را چاپ میکنیم تا اطمینان حاصل شود که پیادهسازی به درستی عمل میکند.
اندازه خروجی torch.Size([10, 512]) به این معنی است که ابعاد خروجی شبکه برای دادههای ورودی مثالی که به شکل torch.randn(10, 512) داده شده، 10 ویژگی دارد که هر یک از آنها یک بردار با ابعاد 512 است. به عبارت دیگر، برای هر نمونه ورودی، یک بردار خروجی با 512 ابعاد تولید شده است و در مجموعه دادههای ما، 10 نمونه وجود دارد.
نکته مهم : add & Normدر همه بلوک های معماری Transformer وجودد دارد و همیشه علاوه بر داده ه ای که مستقیم با تابع فعالسازی به آن وارد می شود. داده ها از طریق Residual connections هم به آن وارد می شوند. و خروجی آن هم معمولا Linear یا ReLU است.
بلوک Encoder معمولاً شامل چندین لایه تکرار شونده است، هر لایه شامل ماژولهایی مانند و Feed-Forward Neural Networks است. بعد از MHA، یک FFNN که شامل دو یا چندین لایه پرسپترون است و توابع خطی و توابع فعالسازی غیرخطی (ReLU، GELU، یا Swish) که به شبکه اجازه میدهد تا الگوهای پیچیدهتر و غیرخطی را یاد بگیرد. الگوهایی که ممکن است توسط Self-Attention به طور کامل شناسایی نشوند. وظیفه اصلی لایه FFN در Encoder این است که پس از اعمال عملیات Self-Attention، اطلاعات را به طور فشردهتر و بازنمایی شدهتری انتقال دهد. این امر می تواند به کاهش احتمال overfitting کمک میکند. سپس، خروجی این اتصال به یک Add & Norm میرسد که کمک میکند تا ویژگیهای خروجی هر لایه استاندارد شوند و فرآیند آموزش مدل سریعتر و پایدارتر شود. خروجی این فرآیند پس از گذر از تمام لایههای Encoder، بردارهای ویژگی نهایی که معمولاً به عنوان مجموعهای از بردارهای ویژگی برای هر عنصر از دنباله نمایش داده میشود. این بردارهای ویژگی حاوی اطلاعات معنایی و مضمونی از دنباله ورودی هستند و برای فرایند بعدی یعنی Decoder استفاده میشوند. در واقع شامل (Q, K) Quary است که به بلوک اخر MHA از Decoder وارد می شود. در قسمت بعد به طور کامل Decoder ها را بررسی خواهیم کرد . پازل ما در حال تکمیل هست آیا مایلید با من همراه باشید؟!
دیکودر Decoder یکی از اجزای بسیار مهم و حیاتی در معماری Transformer هاست. مسئول تولید خروجی نهایی است که معمولاً یک دنباله متنی یا یک سری عناصر است و برای اهداف مختلفی مانند ترجمه، خلاصهسازی، یا طبقهبندی کاربرد دارد. Decoder وظیفه تولید واژگان یا عناصر خروجی را بر اساس بردار زمینه یا حالتکه از Encoder دریافت کرده است، بر عهده دارد. و اطلاعات را از دو منبع مختلف، یعنی ورودی و خروجی قبلی، به دست آورد. بنابراین می تواند اطلاعات مرتبط از دو دنباله ورودی و خروجی را بررسی کند و ترجمه یا تولید خروجی دقیقتری ارائه دهد. در نهایت، Decoder برای تولید خروجی نهایی، از FFNsاستفاده میکند. این لایهها عملیاتی مانند تحلیل و ترکیب ویژگیهای ورودی را انجام داده و خروجی نهایی را تولید میکنند که معمولاً یک دنباله متنی یا یک بردار است که برای مرحله بعدی در فرآیند استفاده میشود.
دیکودر Decoder از چند لایه مختلف تشکیل شده است که هر کدام وظایف خاصی را بر عهده دارند. این لایهها شامل Multi-Head Attention Layers و لایههای FFNN میشوند. MHA به Decoder کمک میکنند تا Attention به اطلاعات مرتبط از ورودی و خروجی قبلی را داشته باشد، در حالی که لایههای FFNN به عملیات غیرخطی تبدیل اطلاعات کمک میکنند.
درست است که بخشهایی از عملکردی که در Decoder انجام میشود، به نظر میرسد که به نوعی مشابه عملکرد Encoder است، اما تفاوت های مهمی هم دارند. در هر یک از MHA در Decoder، Attention انجام میشود. با این تفاوت که این Attention به اطلاعات مرتبط از ورودی و خروجی قبلی مدل شده است، به عنوان ورودی به هر لایه Decoder داده شده است. این موضوع به Decoder کمک میکند تا بتواند متناسب با هر مرحله از تولید خروجی، تمرکز خود را تغییر دهد. در Decoder، FFNN بر روی نتایج MHA اعمال میشوند تا اطلاعات را با استفاده از عملیاتهای غیرخطی مدل کنند و به تولید خروجی نهایی کمک کنند. به عنوان مثال، در معماری GPT ، یک جمله به عنوان ورودی به مدل داده میشود. سپس Decoder با استفاده از MHA و لایههای FFNN ، اطلاعات مرتبط از ورودی را مدل کرده و توانایی تولید کلمات بعدی را دارد. این فرایند به طور بازگشتی ادامه مییابد تا جمله کامل تولید شود.
فرض کنید جمله ورودی "The cat sat on the mat" باشد. در اینجا، جمله ورودی به عنوان یک دنباله از کلمات (token) به مدل داده میشود. این دنباله از کلمات توسط لایههای Encoder پردازش میشود. در لایههای Encoder، هر کلمه (token) به یک بردار نهان (hidden vector) تبدیل میشود که نمایانگر معنای آن کلمه در جمله است. بنابراین، اطلاعات مرتبط از جمله ورودی در بردارهای نهان ایجاد شده توسط Encoder مدل میشوند و به عنوان ورودی به لایههای Decoder داده میشوند. در لایههای Decoder، با استفاده از MHAL، مدل توانایی تمرکز بر روی اطلاعات مرتبط از ورودی را دارد. این اطلاعات مرتبط از جمله ورودی، همراه با اطلاعات از خروجیهای قبلی (در صورت وجود)، برای تولید کلمات بعدی در جمله خروجی استفاده میشوند.
نکته مهم : در مدل GPT، Encoderمسئول تبدیل جمله ورودی به بردارهای نهان مرتبط است، در حالی که Decoderمسئول تولید کلمات بعدی در جمله خروجی بر اساس این بردارهای نهان و با توجه به متن قبلی است.
شاید برایتان سوال باشد چرا بعد از توضیح اولیه راجع به Decoder می خواهیم راجع به output صحبت کنیم. در Decoder، قسمت اول معمولاً شامل Embedding خروجی است. این به این معنی است که در ابتدا، بردارهای ورودی به بردارهای نهان (embedding vectors) تبدیل میشوند. Embedding ویژگیهای معنایی و موقعیتی کلمات را در نظر می گیرد و از آنها برای فرایند بعدی، یعنی Self-Attention، استفاده کند.
در واقع اینجا "خروجی" به معنای خروجی نهایی مدل در هر گام زمانی است، نه خروجی نهایی کلمه. در معماری Transformer، مدل به تدریج کلمات خروجی را تولید میکند. در هر مرحله، مدل یک بردار نهان را تولید میکند که معادل توزیع احتمالی کلمات در موقعیت جاری است. بعد از آن، این بردار به عنوان ورودی به مرحله بعدی مدل داده میشود و همین روند تا زمانی که مدل کلمه پایانی را تولید میکند، ادامه مییابد.
در مورد Positional Embedding، تفاوتهایی بین Encoder و Decoder وجود دارد. در هر دوی آنها، Positional Embeddingها مسئول نشان دادن موقعیت نسبی کلمات در جمله هستند، اما در Decoder، Embeddingها به یک مکانیزم متفاوت نیاز دارند. در Encoder، ترتیب کلمات ورودی اهمیت دارد زیرا موقعیت کلمات در جمله اطلاعات معنایی را تعیین میکند. اما در Decoder، علاوه بر موقعیت کلمات ورودی، ترتیب کلمات خروجی نیز اهمیت دارد. بنابراین، در Decoder، به جزییات زمانی نیز باید توجه شود تا مدل بتواند ترتیب صحیح کلمات خروجی را تولید کند. به عبارت دیگر، در Decoder، از یک مکانیزم Positional Embedding متفاوتی استفاده میشود که توجه به ترتیب زمانی و موقعیت کلمات خروجی را در نظر میگیرد. همانند Encoder بردارهای تئلید شده به همان روش وارد بلوک Attention می شود با این تفاوت که ممکن از داری یک Masked! باشد. میپرسی یعنی چی؟؟ خب بریم قسمت بعد تا بهت بگم!
در Decoder ها هم Self-Attention داریم که تفاوت های جزیی با همین لایه در Encoder دارد. اگرچه هر دو تقریبا از مکانیسم یکسانی استفاده می کنند. در Encoder، Self-Attention به مدل اجازه میدهد تا ویژگیهای ورودی خود را در هر مرحله از فرایند پردازش (ترجمه ماشینی یا دیگر وظایف پردازش زبان طبیعی) بررسی کند و وزنهای مناسب برای هر ویژگی را محاسبه کند. اما در Decoder، Self-Attention به عنوان Masked Multi-Head Attention شناخته میشود. در واقع در هر مرحله از تولید متن (یا ترجمه)، مدل فقط به کلماتی که تا آن لحظه تولید شدهاند (یا در ترتیب زمانی قرار گرفتهاند) Attention میکند و از کلماتی که هنوز تولید نشدهاند (کلمات آینده) صرفنظر میکند. به این منظور، یک Masked بر روی ورودی Self-Attention اعمال میشود که اجازه نمیدهد به اطلاعات آینده دسترسی پیدا کند.
به طور مثال، فرض کنید مدل در حال تولید یک جمله است و در مرحله فعلی، تنها کلمات "من" و "یک" را تولید کرده است. در این صورت، Self-Attention لایه با ماسک، تنها به این دو کلمه توجه میکند و از کلماتی که هنوز تولید نشدهاند (مانند کلمات بعدی جمله) صرفنظر میکند. این باعث میشود تا مدل در هر مرحله از تولید، تنها به اطلاعات موجود تا آن لحظه Attention کند و ترجمه یا تولید متن به شکل صحیحتری انجام شود. این لایه به تولید دقیقتر و معناگرتر ترجمهها کمک میکند.
لایه MMHA به ما کمک میکند تا محاسبات را در طول آموزش به صورت موازیانجام دهیم. این امر بهبود کارایی و سرعت آموزش مدل را افزایش میدهد.حالت Masked در Self-Attention به ما امکان میدهد تا در هر مرحله از آموزش، مدل فقط به اطلاعاتی که در زمانهای قبلی در دسترس بودهاند توجه کند و از اطلاعات آینده صرفنظر کند. این باعث میشود که مدل به طور کارآمدتری از پردازش موازی استفاده کند، زیرا هر نود میتواند به طور همزمان و مستقل از سایر نودها محاسبات خود را انجام دهد.
از این ویژگی برای تولید متن در مدلهای Generative AI مثل ChatGPT یا LlaMa و کلا LLM هایی که متن تولید می کنند استفاده می شود. بدون این ویژگی هم میتوانستیم مدلهای Generative AI برای تولید متن داشته باشیم، اما عملکرد و کیفیت تولید متن این مدلها بدون استفاده از مکانیزمهایی مانند Masked Attention ممکن است کاهش یابد. استفاده از Masked Attention، به مدلها کمک میکند تا در فرایند تولید متن، توجه بیشتری به ترتیب و ساختار جملات داشته باشند و از ایجاد متونی با ساختار ناهمگون جلوگیری کنند.
این مرحله به طور خاص در Decoder به کار میرود. نحوه انتقال اطلاعات از MMHA به لایه های بعدی کاملا مانند MHA است. تنها تفاوتی که دارند بخاطر کارایی که در بالا ذکر شد می باشد. در Decoder ها بعد از MMHA داده ها به لایه MHA وارد می شوند. این لایه علاوه بر داده هایی که از MMHA گرفته است همزمان بردار وضعیت (state vector) از Encoder هم به آن وارد می شوند. به آن مرحله Encoder - Decoder Attention می گویند. در تصویر زیر با جزییات می توان آن را مشاهده کرد.
یکی از اجزای کلیدی معماری Transformer است که به کمک آن مدل توانایی فهم و ترجمه دنبالهها را دارد. در هر مرحله از تولید خروجی توسط Decoder، مدل باید به ورودیهای Encoder توجه کند تا اطلاعات مرتبط را برای تولید خروجی صحیح استفاده کند. این کار در مرحله Encoder-Decoder Attention انجام می شود. در هر مرحله، ابتدا state vector دریافتی از مرحله قبلی در Decoderمحاسبه میشود. سپس، این بردار وضعیت با همه بردارهای وضعیت Encoder مقایسه میشود تا اهمیت (وزن) هر بردار وضعیت Encoder برای تولید خروجی فعلی در Decoderمحاسبه شود. به این ترتیب، مدل به صورت پویا و هوشمندانه میتواند به ورودیهای Encoder توجه کند و از آنها برای تولید خروجی مناسب استفاده کند. محاسبت ریاضی آن به این صورت است که ابتدا Key Vectors هایی که نشاندهنده اطلاعات مهم و کلیدی از ورودی هستند که باید توجه Decoder را جلب کنند. به همراه Value Vectors که همراه با بردارهای کلید از Encoder بهدست میآیند و اطلاعات جزئیتری از ورودی را دارند از Encoder و بردارهای Query که مربوط به Decoder هستند (که نقطه توجه Decoder را نشان میدهند) به معادله امتیاز توجه (Attention Score) وارد میشوند. سپس با استفاده از این امتیازهای توجه، مقادیر ارزیابی محاسبه میشوند و از طریق میانگینگیری وزندار، خروجی نهایی بهدست میآید.
لایه Feed-Forward Neural Network در مدلهای Transformer هم در Encoder و هم در Decoder وجود دارد. اما در هر کدام از این بخشها، ممکن است تفاوتهایی وجود داشته باشد. این لایه در Encoder برای تبدیل ویژگیهای ورودی (معمولاً بردارهای ویژگی کلمات) به فضای ویژگیهای جدیدی استفاده میشود که ممکن است برای مدل بهترین نتایج را ارائه دهند. هر ویژگی ورودی به همهٔ نورونهای لایه FFNN وارد میشود و سپس با استفاده از تابع فعالسازی (معمولاً ReLU یا GELU) پردازش میشود.
در Decoder این لایه برای تبدیل ویژگیهای خروجی Self-Attention به فضای ویژگیهای جدیدی که برای مدل در تولید متن نهایی مفید باشد استفاده میشود. در Decoder، نیازی نداریم که به اطلاعات آینده دسترسی داشته باشیم تا در زمان تولید متن، از اطلاعات قبلی استفاده کنیم. بنابراین، لایه FFNN در Decoder عموماً به صورت Masked Feed-Forward Neural Network پیادهسازی میشود که امکان دسترسی به اطلاعات آینده را محدود کند. این محدودیت به وسیلهٔ Masked مربوطه در محاسبات اعمال میشود تا مدل تنها به اطلاعات قبلی دسترسی داشته باشد.
در انتهای مدل، یک لایه خروجی خطی (Linear Layer) و یک لایه Softmax جهت تبدیل وزنهای خروجی به احتمالهای نرمال شده برای کلاسها (در حالت دستهبندی) یا کلمات (در حالت تولید متن) وجود دارد. این لایه از دو قسمت تشکیل شده است: یک لایه خطی آخر (Last Linear Layer ) و یک لایه Softmax. بیایید هر کدام را به صورت دقیق بررسی کنیم:
لایه Last Linear Layer در معماری Transformers ، به طور معمول در انتهای مدل قرار میگیرد و به طور مستقیم ویژگیهایی را که از لایههای قبلی Decoder به دست آمده اند را دریافت می کند، این لایه برای تبدیل ویژگیهای نهایی مدل به فضای ویژگیهای مورد نیاز برای وظیفه خاصی که مدل برای آن آموزش داده شده، استفاده میشود. این لایه معمولاً دارای یک ماتریس وزن و یک Bias است. ورودی این لایه معمولاً بردارهای ویژگی نهایی مدل هستند که در انتهای فاز Encoder یا Decoder به دست میآیند. بعد از اعمال عملیات خطی (ضرب ماتریسی بین وزنها و ویژگیهای ورودی)، معمولاً با استفاده از یک تابع فعالسازی (مانند ReLU یا GELU) ویژگیهای نهایی به دست می آید. بعد از این مراحل بستگی به تسک خاصی که داریم در صورتی که مدل برای مسئلهای مانند دستهبندی طراحی شده باشد، خروجی این لایه معمولاً به لایه Softmax ارسال میشود تا احتمالات کلاسها محاسبه شود و تصمیم گیری در مورد کلاس نهایی انجام شود. در صورتی که مدل برای تولید متن طراحی شده باشد، خروجی این لایه به لایه Softmax نرمال شده و به عنوان احتمالات کلمات در مرحله بعدی تولید متن ارسال میشود.
فرض کنید مدل ما در حال ترجمه جمله "I love cats" به زبان دیگری مانند فرانسوی است. جمله ورودی "I love cats" از طریق چندین لایه عبور میکند و ویژگیهای آن در هر لایه استخراج میشوند. Linear Layer این ویژگیهای استخراج شده را دریافت میکند. به عنوان مثال، ممکن است این ویژگیها شامل اطلاعاتی در مورد معنا، گرامر و ساختار جمله باشند که از لایههای قبلی به دست آمدهاند. سپس، با استفاده از وزنهای خود، این ویژگیها را به فضای ویژگیهای متناظر با خروجیهای مورد نظر تبدیل میکند، یعنی به فضای ویژگیهای متناظر با جمله فرانسوی "J'adore les chats". به عبارت دیگر، این لایه وزنهایی را که به هر ویژگی ورودی نسبت میدهد، به یک فضای ویژگی جدید (به عنوان ورودی لایه Softmax) تبدیل میکند.
بعد از لایه Linear اخر داده ها به لایه Softmax وارد می شوند که وزنهای خروجی لایه Linear را به احتمالها (احتمال نرمال شده) برای هر کلاس یا کلمه در خروجی مدل تبدیل می کند. در صورتی که مدل برای دستهبندی استفاده شود، این احتمالها نشان دهنده احتمال هر کلاس است. اگر مدل برای تولید متن استفاده شود، این احتمالها نشاندهنده احتمال ظهور هر کلمه در خروجی مدل است. به طور کلی میتوان گفت که با استفاده از لایه Softmax می توانیم مطمئن شویم که هیچ احتمالی به صفر نمیرسد. این کار به جلوگیری از برخی مشکلات مانند بیپایه بودن (zero-bias) و رانش توزیع احتمالاتی که باعث میشود توزیع احتمالاتی خروجی مدل در طول زمان تغییر کند کمک کند. در LLM ها اگر توزیع احتمالاتی کلمات در جملات متفاوت باشد، باعث ایجاد جملات ناهمخوان و نامعقول می شود. پس لایه Softmax باعث میشود که مدل به طور متناسب و منظم احتمالات را تخصیص دهد و از تغییرات ناخواسته در توزیع احتمالاتی جلوگیری کند یا در مسائل دستهبندی، اگر توزیع احتمالاتی دستهها با تغییر زمانی تغییر کند، ممکن است دقت و قابلیت پیشبینی مدل کاهش یابد.
بعد از لایه Softmax در Decoder معمولاً با یکی از دو روش زیر تولید خروجی در معماری Transformers انجام می شود. یا با روش Beam Search (جستجوی پرتو) که در این روش، پس از محاسبه احتمالات با استفاده از لایه Softmax، مدل از جستجوی پرتو برای انتخاب بهترین پیشبینی برای هر گام استفاده میکند. به این صورت است که برای هر گام، مدل چندین پیشبینی ممکن را محاسبه کرده و سپس از بین آنها پیشبینی با بالاترین احتمال را انتخاب میکند. این فرایند تا رسیدن به شرایط خاتمه مانند انتهای جمله یا تعداد تعیین شده از گامها ادامه مییابد. بیایید با یک مثال بهتر آن را یاد بگیریم. فرض کنید که مدل ما یک مدل ترجمه ماشینی است و فرض کنید از مدل می خواهیم جمله انگلیسی "I love you" را به فارسی ترجمه کند. مدل میتواند چندین پیشبینی مختلف برای کلمات فارسی ممکن را محاسبه کند، مانند "من عاشق تو هستم"، "من تو را دوست دارم"، "عشق تو را میپذیرم" و غیره. سپس با استفاده از روش Beam Search، مدل از بین این پیشبینیها، پیشبینی با بالاترین احتمال را انتخاب میکند. به عنوان مثال، اگر مدل از یک پرتو با اندازه ۳ استفاده کند، پیشبینی با بالاترین احتمال در هر مرحله انتخاب میشود و در مراحل بعدی، این پیشبینیها با استفاده از احتمالات محاسبه شده برای کلمات بعدی بهروزرسانی میشوند. کاربردهای آن بیشتر برای مدلهایی مانند مدلهای ترجمه ماشینی، مدلهای تولید شرح بر تصاویر، و مدلهای تولید متن مبتنی بر توجه از این روش برای تولید خروجی نهایی استفاده میکنند.
روش بعدی Sampling(نمونهبرداری) که به جای انتخاب بهترین پیشبینی، مدل از یک فرآیند نمونهبرداریاستفاده و با توجه به احتمالات محاسبه شده، پیشبینیهای مختلفی را تولید کند. این فرآیند میتواند به صورت تصادفی انجام شود، به این معنی که پیشبینیها براساس توزیع احتمالاتی محاسبه شده نمونهبرداری میشوند. به عنوان مثال، فرض کنید مدل میخواهد پیشبینی کند که کدام کلمه بعدی در یک جمله خواهد آمد. این مدل میتواند بر اساس احتمالات محاسبه شده برای کلمات مختلف در واژگان، یک کلمه را با استفاده از نمونهبرداری مستقیم انتخاب کند. برای مثال، اگر واژگان مدل شامل کلمات "آسمان"، "زرد" و "آبی" باشد و احتمالات محاسبه شده به ترتیب 0.4، 0.3 و 0.3 باشند، مدل میتواند با استفاده از نمونهبرداری، به تصادف کلمه "آسمان" را انتخاب کند. این روش برای مسائل مختلفی مانند مدلهای زبانی، ترجمه ماشینی، تولید متن خودکار و تولید تصویر مورد استفاده قرار میگیرد.
البته استفاده از هر کدام از این روش ها برای تولید خروجی مناسب بستگی تسک هایی دارد که می خواهیم انجام دهیم و مثلا در مواردی که فضای جستجو بسیار بزرگ است و استفاده از روش نمونهبرداری مستقیم ممکن است بسیار زمانبر باشد، از روش Beam Search برای تولید پیشبینیهای محتمل استفاده میشود. در هر دو روش، خروجیهای تولید شده به عنوان ورودی به مدل برای محاسبه گام بعدی یا به عنوان خروجی نهایی برای استفاده در برنامهها و کاربردهای دیگر به دست میآید.
ترنسفورمرها به دلیل توانایی فوقالعادهشان در درک روابط بین کلمات در یک جمله، کاربردهای بسیار متنوعی در حوزههای مختلف پردازش زبان طبیعی (NLP) پیدا کردهاند. از مهمترین کاربردهای Transrormer ها مثل ترجمه ماشینی که به طور قابل توجهی دقت ترجمه ماشینی را در زبانهای مختلف افزایش داده است. در خلاصهسازی متن متنهای طولانی را به طور دقیق خلاصه می کنند. میتوانند به سوالات مربوط به متن به طور دقیق و جامع پاسخ دهند. متنهای مختلفی مانند شعر، داستان، کد و ایمیل تولید کنند. تشخیص و تصحیح خطا در واقع میتوانند خطاهای نگارشی و دستوری را در متن شناسایی و تصحیح کنند. کاربرد های زیادی برای استخراج اطلاعات مهم از متن دارند. Transrormer ها میتوانند احساسات بیان شده در متن را تجزیه و تحلیل کنند. در LLM ها برای ایجاد مکالمات طبیعی و جذاب با کاربران استفاده شوند.
علاوه بر همه مواردی که در بالا ذکر شد امروزه شاهد آن هستیم که از Transrormers ها در تسک های دیگر مثلا در بینایی کامپیوتر برای پردازش تصاویر و ویدیوها استفاده می شود و از جمله شرکت هایی که از آن استفاده می کنند مثل Google در طیف گسترده ای از جمله طبقه بندی تصویر (تصاویر اشیاء، حیوانات یا مناظر)، تشخیص شیء (شناسایی افراد، ماشین ها یا ساختمان ها) و بخش بندی تصویر (بخش بندی افراد، ماشین ها یا ساختمان ها) استفاده می کند. به عنوان مثال، از مدل Transformer به نام ViT برای بالا بردن دقت پیشرفته در مجموعه داده های ImageNet استفاده شده است. این مدل در سال 2021 توسط گروهی از محققان Google AI در مقاله ای منتشر شد.
این مقاله نشان می دهد که مدل های Transformer می توانند مستقیماً روی تصاویر اعمال شوند مدل ViT با تفاوت خیلی جزئی از معماری Transformer استاندارد برای پردازش تصاویر استفاده می کند. روی مجموعه داده های ImageNet به روش pre-training with massive parameters آموزش داده می شود. با مدل ViT می توان نتایج خیلی خوبی را در مجموعه داده های مختلف تشخیص تصویر به دست می آورد و از مدل های پیشرفته قبلی مانند مدل های مبتنی بر CNN بهتر عمل می کند. OpenAI از Transformers در برنامه های مختلف بینایی کامپیوتر، از جمله تولید تصویر، ترجمه تصویر و... استفاده می کند. به عنوان مثال، از مدل Transformer به نام DALL-E برای ایجاد تصاویر واقعی از متن استفاده شده است. Microsoft از Transformers برای تشخیص چهره، تشخیص اشیا و ردیابی اشیا استفاده می کند. به عنوان مثال، از مدل Transformer به نام Azure Cognitive Services برای ارائه API های بینایی کامپیوتر به توسعه دهندگان استفاده شده است. Facebook در تسک هایی از جمله تشخیص چهره، تشخیص اشیا و بخش بندی تصویر استفاده می کند. به عنوان مثال، از مدل Transformer به نام Detectron2 که در واقع یک جعبه ابزار منبع باز برای تشخیص اشیاء در تصاویر است که بر پایه شبکههای عصبی عمیق مبتنی بر Transformer طراحی شده است. این جعبه ابزار از مدل Transformer و سایر روشهای پیشرفته در حوزه دید کامپیوتری استفاده میکند. ازجمله مزایای استفاده از مدل Detectron2 میتوان به دقت بالا، قابلیت یادگیری و انطباق با ورودیهای مختلف، و توانایی انجام وظایف پیچیدهتر در تشخیص و تفسیر تصاویر اشاره کرد.
از Transformers می تواند برای ایجاد تصاویر جدید از متن یا تصاویر موجود استفاده شود. به عنوان مثال، می توان از آنها برای ایجاد تصاویر واقع گرایانه از متن یا برای ترجمه تصاویر از یک سبک به سبک دیگر استفاده کرد. همچنین برای دستکاری تصاویر، مانند تغییر رنگ، اضافه کردن یا حذف اشیاء یا تغییر بافت تصاویر استفاده شود. اینها تنها چند نمونه از کاربردهای Transformers در بینایی کامپیوتر هستند. با توجه به توانایی Transformers در یادگیری وابستگی های پیچیده در داده ها، احتمالاً در آینده شاهد استفاده گسترده تری از آنها در این زمینه خواهیم بود.
ترنسفورمرها از نظر توانمندی و انعطاف پذیری در پردازش زبان طبیعی و بینایی کامپیوتر بسیار پیشرفته هستند، اما بدون شک هیچ مدلی کامل نیست و معایب خاص خودش را می تواند داشته باشد. اولین نکته ای که وجود دارد پیچیدگی زیاد Transformer ها و نیاز به منابع محاسباتی بالا برای آموزش و استفاده از آن است که مشکلاتی مانند زمان طولانی آموزش و پردازش، مصرف انرژی بالا و نیاز به سخت افزار قوی را در پی دارد. برای آموزش مدلهای Transformer به مجموعه دادههای بزرگ و حجیم نیاز است که ممکن است به مشکلاتی مانند نیاز به ذخیره و پردازش حجم زیادی از دادهها و مدیریت دادههای بزرگ منجر شود. چون برای استفاده از Transformer ها داده ها به صورت توکن ها یا بردارهای عددی باشند برای بعضی از حوزهها مانند تشخیص تصویر، ممکن است دقت و اطلاعات موجود در تصویر را کاهش دهد.
در بخش دوم مطالعه ما، به جزئیات بسیاری در مورد معماری ترنسفورمرها پرداختیم. ما هر مؤلفه و لایه را بررسی کردیم و یادگرفتیم که چگونه انکودرها، دیکودرها و ترنسفورمرها با هم کار میکنند تا ترجمه زبان بین زبانهای مختلف را بهبود بخشند. همچنین، ما بررسی کردیم که چگونه ترنسفورمرها میتوانند برای وظایف مختلف دیگر استفاده شوند. ما در مورد برخی از محدودیتهای ترنسفورمرها صحبت کردیم. از زمان معرفی آنها در سال 2017، شهرت مدلهای زبانی بر پایه ترنسفورمرها ادامه داشته است. به نظر میرسد که ترنسفورمرها نه تنها شهرت خود را حفظ میکنند بلکه روز به روز محبوبیت بیشتری کسب میکنند. با این حال، در سالهای اخیر، معماریهای دیگری مانند Infini-Transformers ظاهر شدهاند. Infini-Transformers یک خانواده از مدلهای ترنسفورمر با عمق نامحدود هستند، و مهمترین مقاله که در این زمینه پیدا کردم، توسط تیم تحقیقاتی گوگل نوشته شده است.
این مدلها از معماری استاندارد ترنسفورمر با اصلاحاتی برای افزایش عمق آن استفاده میکنند. به عنوان مثال، آنها از توابع فعالسازی ReLU به جای توابع فعالسازی softmax در معماری استفاده میکنند، لایههای نرمالسازی دستهای را بین هر بلوک ترنسفورمر درج میکنند، و از توابع توجه موقعیتی جدید استفاده میکنند. این مدلها با استفاده از پیشآموزش با پارامترهای عظیم بر روی مجموعه دادههای متن بزرگ آموزش داده میشوند. پس از آن، این مدلها برای وظایف مختلف پردازش زبان طبیعی مانند ترجمه ماشینی، خلاصهسازی متن و پاسخ به سوالات بهصورت مرحلهای تنظیم میشوند. در آینده، بیشتر درباره این مدلها خواهم نوشت. با این حال، سرعت تغییرات به شدت افزایش یافته است و ممکن است به زودی یک مدل موثرتر از ترنسفورمرها معرفی شود. از همراهی شما در این مقاله سپاسگزارم. من خودم درحال نوشتن این مقاله بسیاری چیزها یاد گرفتم و امیدوارم برای شما هم مفید بوده باشد. نظرات شما در مورد این مقاله را قدردانی میکنم. لطفاً نظر خود را با من به اشتراک بگذارید. با تشکر.
ممنون از شما که در این سفر به دنیای Deeps با من همراه بودید.
لینک پارت 1 به انگلیسی در Medium
# پارت 2 : معماری ترنسفورمرها را به صورت جز به جز و قسمت به قسمت کامل باز می کنیم با مثال و کد
لطفا اگر مایل بودید مقاله دیگر من"مرحله به مرحله برای ساختن یک شبکه عصبی مصنوعی و دیدن چگونگی رخ دادن overfitting با MNIST و معماری CNN " رو در ویرگول ببینید .
مهندسی پرامپت چیست و چرا برای پیشرفت هوش مصنوعی اهمیت دارد؟
امیدوارم از مطالب لذت برده باشید .