فهرست مطالب
شبکههای عصبی روشهایی هستند که تلاش میکنند با تقلید از مغز انسان، بتوانند یاد بگیرند و مسائل مختلف را حل کنند. برای رسیدن به این هدف، انواع مختلفی از این شبکهها به وجود آمده است که در این مقاله خیلی ساده یاد میگیریم انواع شبکههای عصبی چه هستند و چطور کار میکنند.
برای آشنایی بیشتر با شبکه عصبی، مقاله شبکه عصبی مصنوعی به زبان ساده را از مجموعه مقالات یادگیری ماشین بخوانید.
پرسپترون (Perceptron) چیست؟
پرسپترون واحد سازنده شبکههای عصبی است. در پرسپترون تعدادی ورودی داریم که در ضریب دلخواهی ضرب شده و مجموع حاصلضرب ورودی در ضرایب به دست میآید. سپس نتیجه با یک بایاس جمع شده و یک activation function، خروجی نهایی را تولید میکند.
شبکه عصبی عمیق شبکهای است که چندلایه دارد (MLP: multi-layer perceptron). این لایهها پشت سر یکدیگر قرار میگیرند.
اگر در یک شبکه عصبی عمیق، از لایه ورودی به لایه بعدی تمام اتصالات برقرار باشد، لایه بعدی یک لایه fully connected نامیده میشود.
به دلیل برقرار بودن همه اتصالات بین نورونها در لایههای fully connected، حجم محاسبات در این لایهها بالا است. بنابراین محاسبات در شبکههای عصبی که از این لایهها استفاده میکنند، زمانبر است. برای حل این مشکل، شبکههای عصبی پیچشی یا کانولوشنی (Convolutional Neural Networks: CNN) مطرح شدند. با وجود اینکه این شبکهها برای تصاویر به کار میروند، اما برای متن هم میتوانند مورد استفاده قرار گیرند. استخراج ویژگی داخل این شبکه به خوبی انجام میشود. استخراج ویژگی با CNN معمولاً زمانی انجام میشود که میخواهیم مهمترین ویژگیها را استخراج کنیم. در این شبکهها برخلاف fully connected، تمام اتصالات به یکدیگر وصل نیستند.
در مقاله یادگیری عمیق چیست بیشتر درباره این موضوع بخوانید.
شبکه عصبی بازگشتی (Recurrent Neural Network)
فرض کنید میخواهیم با یک دنباله یا sequence کار کنیم. منظور از دنباله، هر چیزی است که شامل چند زیر بخش است و ترتیب قرارگیری این موارد در کنار یکدیگر مهم است. بهعنوان مثال، جملاتی که شامل تعدادی کلمه پشت سر هم هستند یا ویدئوهایی که شامل فریمهایی پشت سر هم هستند همگی دنباله محسوب میشوند. در شبکههای عصبی RNN به جای اینکه بین همه لایهها ارتباط fully connected باشد، از روشی به نام اشتراک پارامترها استفاده میشود. یعنی به جای اینکه ارتباطی بین همه لایهها برقرار باشد، بین همه لایهها پارامترهایی مشترک وجود دارد که منتقل میشوند.
در شکل زیر، RNN سمت چپ تصویر است که یک ورودی گرفته و یک خروجی میدهد:
تصویر سمت راست باز شده این شبکه است. شبکههایی که مانند RNN به صورت بازگشتی عمل میکنند، یک لایه ساده هستند که به صورت مداوم تکرار میشوند. در این شبکه، ورودی یعنی x با v، در هم ضرب شده و یک خروجی تولید میکند.
v درواقع hidden state است و همزمان با تولید یک خروجی، یک hidden state جدید هم تولید میکند. v در ابتدای کار که هیچ اطلاعات قبلی وجود ندارد با مقدار تصادفی پر میشود و در هر مرحله اطلاعات چکیده و ارزشمند را نگهداری میکند. شکل زیر را در نظر بگیرید:
اگر از سلول اول سمت چپ شروع کنیم، در ابتدا ورودی در یک hidden state تصادفی ضرب شده و یک خروجی و یک hidden state جدید تولید میکند. این hidden state جدید خلاصهای از اطلاعات خوانده شده است. در ابتدای کار چون hidden state نداریم، از یک hidden state تصادفی استفاده میشود.
شکل زیر باز شده شکل بالاست که نحوه ضرب ورودی در hidden state در هر مرحله و تولید hidden state جدید در آن مشخص شده است.
در دوره آموزش متن کاوی فارسی با شبکههای عصبی، شبکه های عصبی را با کدنویسی فراوان را یاد بگیرید.
مشکلات شبکه عصبی بازگشتی RNN
به طور کلی، مشکلات RNN عبارتاند از:
- Vanishing/exploding gradient
- Forget first word
در ادامه به شرح این مشکلات پرداخته میشود:
مشکل Vanishing/exploding gradient در RNN
مفهوم Vanishing در شبکه RNN
زمانی که میخواهیم شبکه عصبی را آموزش دهیم، در ابتدا ورودیها به مدل داده میشوند، در ادامه خروجی تولید میگردد و این خروجی با مقدار واقعی مقایسه شده و خطا به دست میآید. سپس وزنها آپدیت میشوند. اگر میزان تغییر وزنها کم باشد، وزنهای آخر در برگشت عوض شده؛ ولی وزنهای لایههای ابتدایی شبکه تغییر نمیکنند. این موضوع سبب میشود تا در خطاهای بسیار کوچک، وزنهای ابتدایی شبکه آپدیت نشده و تغییر نکنند و در اصطلاح Vanishing اتفاق میافتد.
مفهوم Exploding در شبکه RNN
زمانی اتفاق میافتد که وزن لایههای آخر خیلی بزرگ باشند و موقع آپدیت شدن، در وزنهای لایههای دیگر ضرب شده و درنتیجه وزنهای ابتدایی بسیار بزرگی تولید میشود.
مشکل Forget first word در RNN
شکل زیر، مثالی از چگونگی عملکرد hidden state را نشان میدهد که در هر مرحله چکیدهای از مراحل قبلی را در خود دارد:
با درنظر گرفتن شکل بالا، میبینیم که عیب بزرگ RNN این است که اطلاعات مراحل خیلی قبل را دور میریزد و حافظه نزدیک دارد. مثلاً در شکل بالا، در مرحله آخر هیچ اطلاعاتی از مرحله اول باقی نمانده است.
شبکه عصبی LSTM
به دلیل مشکلاتی که در RNN گفته شد، به سراغ LSTM میرویم.
در این شبکه علاوه بر hidden stateهایی که در RNN داشتیم، stateهای دیگری نیز وجود دارد.
سمت چپ بلاک A دو ورودی وجود دارد که یکی hidden state است و دیگری cell state .
با توجه به شکل بعدی، میبینیم که LSTM شامل دو حالت forget gate و update gate است.
LSTM دو حافظه دارد: یکی hidden state که RNN هم داشت و دیگری cell state.
در cell state چکیده اطلاعات بسیار مهم نگهداری میشود، این فرایند توسط forget gate و update gate انجام میشود.
در ابتدا، ورودی و hidden state وارد یک لایه fully connected میشوند. سپس forget gate تصمیم میگیرد که آیا این کلمه جدیدی که دیده است اطلاعات با ارزشی دارد یا نه. اگر باارزش نبود forget gate آن را به cell state اضافه نمیکند و تنها در hidden state تأثیر میگذارد. اما اگر کلمه مهمی باشد، در قسمت آپدیت به cell state اضافه میشود.
مشکلات LSTM عبارتاند از:
- در LSTM توانایی پردازش موازی را نداریم و این موجب میشود تا سرعت محاسبات پایین باشد.
- با وجود اینکه cell state حافظه بلند مدتی است که در این مدل استفاده شده، اما این حافظه همچنان محدود است و توانایی یادگیری دنبالههای بسیار طولانی را ندارد.
این عیوب سبب شد تا از ترنسفورمرها استفاده شود.
شبکه عصبی بازگشتی دو طرفه (Bidirectional RNN)
مدل Bidirectional مدلی است که در آن جمله از هر دو طرف خوانده میشود. مثال دیگری از مدل Bidirectional مدل Bert است که در ادامه با این مدل آشنا خواهیم شد.
مدل Seq2Seq در یادگیری عمیق
این مدل از نظر ساختاری، از دو قسمت Encoder و Decoder تشکیل شده است. مدل Seq2Seq، ساختاری دومرحلهای داریم و میخواهیم دادهای که از جنس دنباله است، به داده دیگری از جنس دنباله، تبدیل شود.
مثالی از این مدل، سرویسهای ترجمه است. مثلاً مترجم گوگل، یک جمله انگلیسی را میگیرد و به جملهای چینی تبدیل میکند.
از دیگر کاربردهای این مدل در زمان تبدیل صوت به متن یا بلعکس است. مثلاً دستیار صوتی گوگل.
همچنین یک سیستم پرسشوپاسخ، با استفاده از ساختار مورد استفاده در مدل Seq2Seq ساخته میشود و دو مرحلهای است. به عبارتی یک سیستم پرسشوپاسخ، دنبالهای از جنس کلمات را گرفته و آن را به دنباله دیگری از جنس کلمات تبدیل میکند.
مدل Seq2Seq از دو قسمت Encoder و Decoder تشکیل شده که در Encoder رمزگذاری و در Decoder رمزگشایی انجام میگیرد.
در شکل بالا در قسمت Encoder، بعد از اینکه ورودیها و hidden state های هر مرحله به مدل RNN داده شد، hidden state نهایی که چکیدهای از همه hidden stateهای قبلی است، تولید میشود و آن را به Decoder میدهیم و Decoder باید این hidden state را رمزگشایی کند.
مشکلات مدل Seq2Seq
- long-range dependencies
عیب بزرگ Seq2seq، این است که در متون طولانی با ازدسترفتن اطلاعات یا information loss مواجه میشویم. در واقع اگر طول جمله ورودی خیلی زیاد باشد، برای تولید جمله خروجی اطلاعات مفیدی که در ابتدای جمله ورودی هستند، از دست میرود. مثلاً در شکل بالا فاصله x1 و y1 خیلی زیاد است و فاصله زیادی بین کلمات ورودی و خروجی وجود دارد. این موضوع، سبب ازدسترفتن اطلاعات مفید میشود.
- parallelization
مشکل دیگر مدل Seq2seq، این است که باید ورودیها به ترتیب وارد شوند و امکان ورود هم زمان اطلاعات به صورت موازی وجود ندارد. زیرا ورودی هر بخش، به خروجی بخش قبل وابسته است.
به دلیل این مشکلات، ترنسفورمرها پدید آمدند. ترنسفورمرها به نحوی ساخته شدهاند که دارای همه مزایای RNN و CNN و fully connected هستند و تلاش میکنند عیبهای گفته شده در مدلهای فوق را از بین ببرند.
وقتی بخواهیم متنی را ترجمه کنیم در برخی مواقع نیاز داریم که به قسمتها و کلمات قبلی متن برگردیم مثلاً در متن زیر برای تشخیص اینکه ضمایر به چه کسی بر میگردد، باید مدل نام شخص را از ابتدای متن به یاد داشته باشد. پس، گاهی نیاز است برای ترجمه یک کلمه، به کلمات دیگر هم توجه کنیم.
بنابراین بعضی از ورودیها در تولید خروجی نقش مهمتری دارند و تأثیرگذارتر هستند. مثلاً در ترجمة یک کلمه، بعضی از ورودیها نقش بیشتری دارند یا هنگامی که میخواهیم یک فعل را ترجمه کنیم باید به مفرد یا جمع بودن فاعل “توجه“ کنیم. “توجه” (Attention) بیان میکند که هنگام تولید خروجی آینده، تا چه اندازه باید به قبل (گذشته) توجه کنیم.
Attention مشکل long-range dependencies را از بین میبرد.
مدل ترنسفورمر (Transformer Model) یا مدل انتقالی
مشکل LSTM این بود که در آن امکان پردازش موازی وجود نداشت. این مشکل در ترنسفورمر برطرف شده و میتوانیم تمام کلمات را به صورت یکجا به ترنسفورمر بدهیم تا به صورت موازی مدل آموزش ببیند.
ترنسفورمر از دو قسمت تشکیل شده است: قسمت Encoder (سمت چپ) و قسمت Decoder (سمت راست)
مطابق شکل بالا، در کنار Encoder و Decoder نوشته شده : *N . این موضوع به معنای این است که Encoder و Decoder هرکدام N بار تکرار میشوند.
قسمت Encoder در ترنسفورمر
در Encoder، ابتدا embeddingهایی که تصادفی هستند به همراه جایگاه کلمات، به یک multi head attention داده میشود. در مراحل بعدی به ترتیب normalization ، feed forward و مجدداً normalization انجام شده و بعد از اینکه این مراحل N بار تکرار شد، خروجی به Decoder وارد میشود.
وظیفه multi head attention تولید بردار توجه است. به عبارتی مشخص میکند که برای تولید کلمات خروجی، به چه کلماتی از گذشته باید توجه شود. (این توجه مربوط به یک جمله است)
منظور از توجه یا همان attention، این است که وزنهای مربوط به درجه اهمیت هر کلمه را پیدا کنیم.
قسمت Decoder در ترنسفورمر
لایههایی که در قسمت Decoder وجود دارند، شامل لایه masked multi head attention ، لایه multi head attention و لایه feed forward است.
در دوره آموزش کاهش نویز تصاویر، با Encoder و Decoder بیشتر آشنا شوید.
مکانیزم توجه و Self-attention چگونه کار میکند؟
در self-attention یک کلمه را در نظر میگیریم و میخواهیم بدانیم کلمات دیگر آن جمله چه تأثیری در این کلمه دارند. مثلاً یک عبارت هزار کلمهای داریم و حال یک کلمه جدید اضافه میشود، باید بررسی کنیم که چه وابستگیهایی بین این کلمه جدید و هزار کلمهای که داشتیم وجود دارد. برای محاسبه این وابستگیها از attention استفاده میکنیم. attention درجه اهمیت هزار کلمه در تککلمه جدید را به صورت یک امتیاز (وزن) ارائه میدهد. این وزنها همان درجه اهمیت کلمه هستند.
روش Masked self-attention چیست؟
در Masked self-attention ، به جای توجه به وابستگیهای بین کلمه جدید و همه کلمات مربوط به آن عبارت، تنها وابستگیهای کلماتی که قبل از کلمه جدید وجود داشتند، با کلمه جدید بررسی میشود.
در Decoder ترانسفور و در بخش output، به کلماتی که در جمله هستند یک شیفت داده شده و یک کلمه جابهجا میشود و مدل باید این کلمه را پیشبینی کند. به عبارتی، Decoder در ترانسفور مانند مدل زبانی، چند کلمه را گرفته و کلمه بعدی را پیشبینی میکند. پس هنگام پیشبینی کلمه بعدی، باید به چند کلمه قبلی توجه کنیم و نه هزار کلمه.
مثلاً اگر بخواهیم 701 امین کلمه را پیشبینی کنیم، باید به 700 کلمه قبل توجه کنیم، نه کلمههای بعدی (چون اصلاً کلمات بعدی را نداریم). زیرا 700 کلمه قبل روی کلمه 701 ام تأثیرگذار هستند و باید بررسی کنیم که برای تولید کلمه 701 ام هرکدام از 700 کلمه قبل چقدر در تولید کلمه 701 ام نقش دارند. در این مثال attention کلمه 0 – 700 محاسبه میشود. پس اگر بخواهیم 701 امین کلمه را پیشبینی کنیم، اگر به 700 کلمه قبل توجه کنیم از روش Masked self-attention ولی اگر به کل 1000 کلمه توجه کنیم، از روش self-attention استفاده کردهایم.
در Encoder، attention برای کل کلمات یک عبارت محاسبه میشود، اما در Decoder از روش Masked استفاده میکنیم و attention فقط برای کلمات قبل حساب میشود.
فایده مکانیزم attention این است که در دنبالههای طولانی کلمات مهمتر را مشخص میکند و کلماتی را که اول بودند، فراموش نکند.
بهازای تکتک کلمات، attention محاسبه میشود. یعنی اگر یک عبارت یا ورودی 1000 کلمهای داشته باشیم attention همه این 1000 کلمه محاسبه میشود.
نحوه محاسبه attentionها در شبکه عصبی
برای محاسبه attentionها، باید چند بردار زیر را محاسبه کنیم:
- Query vector
- Key vector
- Value vector
در طول زمان این بردارها آپدیت و بهینه میشوند.
در مثال زیر نحوه محاسبه attention برای دو کلمه thinking و machines نشان داده میشود.
هر کدام از این دو کلمه، یک بردار embedding دارد. فرض کنید این بردارها x1 , x2 هستند که در ابتدای کار با مقادیر تصادفی مقدار گرفتهاند.
همچنین سه ماتریس وزندار به نامهای wq, wk , wv داریم که به ترتیب وزن مربوط به Valueها ، Keyها و Query هاست . این وزنها نیز در ابتدا به صورت تصادفی مقداردهی شدهاند.
اگر بخواهیم attention دو کلمه thinking و machines را محاسبه کنیم، در ابتدا باید بردارهای Value ، Key و Query مربوط به هر کلمه را حساب کنیم. این بردارها به صورت زیر حساب میشوند:
X1 * Wq = q1 & x2 * wq = q2
X1 * Wk = k1 & x2 * wk = k2
X1 * Wv = v1 & x2 * wv = v2
وزنهای wq, wk , wv باید به مرور آپدیت و بهینه شوند.
محاسبه بردارهای Value ، Key و Query برای محاسبه attention استفاده میشود و به کمک این سه بردار scoreهایی که مربوط به attention است، به صورت زیر به دست میآید.
مثلاً برای کلمه اول همانطور که مشخص شده q1* k1 شده و score =112 که این درجه اهمیت کلمه thinking است.
در مرحله بعدی باید score هارا به 8 تقسیم کنیم. (چون فرض شده که dimension 6۴تایی است. پس ازش رادیکال گرفته شده 8.) بعد از تقسیم نیز از تابع softmax استفاده میکنیم تا احتمالات به دست آید.
طبق این نتیجه مقدار score بهدستآمده برای thinking بیشتر است پس باید بیشتر به آن توجه شود.
در مرحله بعدی باید softmax در value یعنی v1 و v2 ضرب شوند و به این ترتیب z1 و z2 به دست میآید.
z1 بردارself-attention اولین کلمه جمله است. zها خروجی هستند که به لایههای بالایی فرستاده میشوند.
چرا در ترانسفور multi head attention داشتیم؟
چون اگر چند پردازنده داشته باشیم، این پردازندهها هم زمان و به طور موازی attentionها را حساب میکنند و به نوعی این نام گویای عملیات موازیسازی در ترنسفورمرها است.
هرکدام از Headها نیز وزنهای مخصوص به خود را دارند.
در نهایت همه attentionهای مربوط به Headهای مختلف با هم aggregate (جمع) میشوند.
هر Head برای خودش ماتریسهای وزنی دارد که باید train شوند.
همانطور که در شکل زیر مشخص است، هر Head ماتریس z خود را تولید کرده. (z0 , z1 , … , z7)
هر z وزن مربوط به خود را دارد و به ترتیب z0 در وزن مربوط به Head0 ، z1 در وزن مربوط به Head1 و … و zn در وزن مربوط به Headn ضرب میشود. سپس با هم جمع میشوند و z نهایی تولید میشود.
اگر فرض کنیم که multi head attention ما ۸تایی باشد، نمیتوانیم 8 خروجی به لایه بعدی (feed forward) بدهیم و باید هر 8 تا را با هم یکی کنیم و ماتریس z نهایی را به مرحله بعدی بفرستیم.
کل محاسبات به صورت زیر بود:
مدل Bert و تاثیر آن پردازش زبان طبیعی (NLP)
Bert مخفف عبارت Bidirectional Encoder Representations from Transformers است.
Bidirectional یعنی از دو طرف به یک دنباله نگاه میکند.
Bert با دادههای زیادی آموزش دیده و همانطور که گفته شد، Bert از Encoder ترنسفورمر استفاده میکند. خروجی لایه Encoder، وزن یا word embedding است. بنابراین بعد از پایان آموزش، Bert وزن تمام کلمات را میدهد. پس میتوان از این مدل که قبلاً آموزش داده شده، استفاده کرد و فقط کمی آن را بهبود بخشید (fine tune). زیرا ترنسفورمر پارامترهای زیادی دارد و اگر بخواهیم از ابتدا Bert را برای مدل خودآموزش دهیم زمان بسیار زیادی لازم دارد و با سیستمهای معمولی چنین کاری امکانپذیر نیست.
در روشهایی مانند word2vec و حتی روشهای بهتر مثل fast text یا Glove، دو محدودیت جدی داشتیم:
- word2vec از شبکههایی استفاده میکرد که تعداد لایههایشان خیلی کم بود (shallow)، ولی Bert معماری بزرگتری دارد. طبیعی است که هرچقدر معماری بهتر باشد شانس موفقیت بیشتر است.
- همچنین مدلهای قدیمی به context و معنا و مفهوم توجه نمیکنند اما Bert به محتوا و مفهوم کلمات هم توجه میکند. مثلاً در دو مثال زیر، معنی کلمه بانک در جمله متفاوت است.
در جمله اول به معنای ساحل و در جمله دوم به معنای بانک است. Bert به محتوا و معنای کلمهها نیز توجه میکند و برای کلمه بانک در این مثال، دو word embedding تولید میکند.
Bert دو ورژن دارد: یک ورژن base و یک ورژن large
ورژن base، 12 لایه دارد. یعنی 12 Encoder پشت هم قرار گرفتهاند. ورژن large، 24 لایهای است. در ورژن base 12 تا multi head attention داریم یعنی 12 هد داریم که در آن محاسبات به صورت موازی انجام میشوند و در مدل لارج 16 تا multi head attention داریم. در زیر مشخصات این دو ورژن به همراه تعداد پارامترها مشخص شده است.
BERT-Base: 12-layer, 768-hidden-nodes, 12-attention-heads, 110M parameters
BERT-Large: 24-layer, 1024-hidden-nodes, 16-attention-heads, 340M parameters
Bert از روی 2,500 میلیون کلمه ویکیپدیا و 800 میلیون کلمه از کتب مختلف آموزش داده شده است. آموزش چنین مدلی با چنین دیتای آموزشی با سیستمهای عادی امکانپذیر نیست. به همین دلیل از مدل از پیش آموزش داده شده (pre-trained) استفاده میکنیم و میتوانیم آن را بهبود بخشیم.
اگر بخواهیم از مدل Bert استفاده کنیم، دو کار میتوانیم انجام دهیم:
1- خودمان Bert را از ابتدا آموزش دهیم. یعنی به مدل Bert دادههای زیادی بدهیم و وزن هر کلمه را تولید کنیم و word embedding خاص خود را داشته باشیم. با hugging face میتوانیم این کار را انجام دهیم؛ ولی سیستم عادی میسوزد.
زمانی که بخواهیم Bert اولیه را آموزش دهیم، دو مرحله باید انجام شود:
- Masked Language Modeling
- Next Sentence Prediction
در مرحله Masked Language Modeling، 15 درصد کلمات ماسک میشوند و مدل باید این کلمات را پیشبینی کند.
در مرحله Next Sentence Prediction نیز مدل باید پیشبینی کند که جمله دوم در ادامه جمله اول هست یا نه.
2- به جای اینکه Bert را آموزش دهیم، از Bert آموزشدیده استفاده کنیم. مدل Bert یک خروجی دارد و میتوان روی خروجی این مدل، لایههای دلخواه را استفاده کرد. مثلاً در لایه خروجی میتوان از تابع softmax استفاده کرد یا یک لایه fully connected و بعد از آن یک تابع softmax قرار داد.
برای بهبوددادن نتایج Bert به صورت زیر عمل میکنیم:
در ابتدا Bert یک توکن خاص به نام CLS میگیرد. CLS مخفف classification است و به این صورت مشخص میشود که Bert باید classification انجام دهد.
دو جمله A وB داریم و میخواهیم این دو جمله را به مدل Bert بدهیم که پیشبینی کند جمله B میتواند بعد ازA بیاید یا نه.
جمله اول را به مدل میدهیم و وقتی به آخر جمله رسید، یک علامت جداکننده، مانند نقطه یا ویرگول و غیره در انتهای جمله قرار میگیرد. سپس جمله دوم به مدل داده میشود و با تمامشدن جمله دوم علامت جداکننده دیگری در انتهای جمله قرار میگیرد. علامتی که جملات را از هم جدا میکند، به نام SEP شناخته میشود(مخفف SEParator).
همچنین در هر جمله یک کلمه پنهان شده است (Mask شده).
کل این دو جمله را به Bert میدهیم.
Bert بسته به اینکه مدل base است یا large، یک خروجی میدهد. در این مثال خروجی ۵۱۲تایی بوده است و در پایان روی خروجی اول یک softmax و یک fully connected قرار گرفته است.
Is next و not next نشاندهنده احتمال این است که جمله دوم، ادامه جمله اول هست یا نه. در واقع احتمال اینکه جمله دوم ادامه جمله اول هست یا نه مشخص میشود.
در مثال بعدی کلمهای از جمله Mask شده و هدف، پیشبینی این کلمه است. پس در لایه خروجی یک fully connected به همراه یک softmax قرار گرفته و احتمال اینکه کلمه Mask شده کدام کلمه است، محاسبه میشود.
شکل زیر نیز مثالی از نحوه طبقهبندی توسط Bert را برای تشخیص اسپم بودن یا نبودن یک پیام نشان میدهد:
در اینجا طبقهبندی بسیار ساده انجام شده است و در لایه خروجی، یک لایه feed- forward و fully connected با تابع softmax قرار گرفته و در خروجی احتمال اسپم بودن یا نبودن حساب میشود. به این کار در اصطلاح fine tune کردن گفته میشود. درواقع لازم نیست Bert از ابتدا آموزش داده شود و تنها لایههایی که در خروجی قرار میدهیم نتیجه و وزنهای Bert را برای کار مخصوصی که داشتیم، کمی بهبود میدهند. (که در مثال ما spam detection بود)
نکته: ورودی که Bert میگیرد به صورت زیر است:
به عبارتی، علاوه بر token embeddings و segment embeddings، باید جایگاه کلمات یا Position Embeddings را هم بگیرد. ترنسفورمرها جایگاه را ذخیره نمیکردند به همین دلیل جایگاه کلمات نیز بهعنوان ورودی باید به مدل Bert داده شود.
token embeddings ، embedding کلمات است. یا همان وزن کلمات.
segment embeddings، مشخص میکند هر کلمه مربوط به جمله اول است یا دوم.
Position Embeddings مشخصکننده جایگاه کلمهها است.
بنابراین اگر بخواهیم با Bert مدلی بسازیم، ابتدا باید دادهها را پیشپردازش کنیم و ورودی ما باید به صورت token embeddings + segment embeddings + Position Embeddings باشد.
پیادهسازی برت (Bert)
در پیادهسازی به جای اینکه از ابتدا Bert را شروع کنیم، از فریمورکهای آماده شروع میکنیم. مثل فریمورکهای زیر:
- huggingface/ transformers
- fastbert
- Deeppavlov
- BERT as service
به صورت خلاصه، اگر بخواهیم با مدل Bert طبقهبندی انجام دهیم، ابتدا دیتای خام را پیشپردازش کرده و سپس آن را به Bert میدهیم و وقتی Bert پیشبینی کرد، در خروجی Fully Conntected یا softmax قرار میدهیم (اولین خروجی).
مشکل اصلی Bert حجیم بودن آن است که سختافزارهای خیلی قوی برای پردازش نیاز دارد. به همین دلیل مدلهای دیگری وجود دارد که سعی کردهاند بدون کمشدن دقت از حجیم بودن Bert بکاهند و آن را سبک کند. این مدلها در جدول زیر آورده شدهاند:
اینکه روی کدام یک از خروجیهای Bert لایه Fully Conntected یا softmax و ... را قرار دهیم فرقی دارد یا نه؟
همیشه باید روی لایه خروجی اول لایههای لایه Fully Conntected یا softmax را قرار دهیم.
- ترنسفورمر از دو لایه Encoder و Decoder تشکیل شده است که هر لایه N بار تکرار میشود. Encoder جمله را به یک جا میگیرد و ترتیب کلمات را ندارد به همین دلیل از positional encoding استفاده شد. در گام بعدی عملیات multi head attention انجام شده و attention ها به دست میآید. یعنی اگر 1000 کلمه داشته باشیم در این مرحله امتیاز تکتک این کلمهها محاسبه میشود. پس از محاسبه attentionها از یک لایه normalizer استفاده و نتیجه به یک feed forward وارد میشود. وظیفه feed forward خلاصهسازی و نرمالسازی بردارهایی است که multi head attention تولید میکند. این مراحل N بار تکرار شده و در مرحله N ام خروجی Encoder به Decoder داده میشود.
- Decoder به ورودیها یک شیفت به راست میدهد و وظیفهاش این است که کلمه بعدی را پیشبینی کند. همچنین، در لایه آخر Decoder یک تابع soft max وجود دارد، زیرا باید احتمال کلمه بعدی را محاسبه کند.
- در Bert فقط از Encoder ترنسفورمر استفاده میشود.
- در GPT فقط Decoder ترنسفورمر استفاده میشود.
- در ترنسفورمر جملات به یک Encoder داده شده و جملات Encode میشوند. آخرین Encoder یک خروجی میدهد که این خروجی، چکیده اطلاعاتی است که بهعنوان word embedding استفاده میشود.