رفتن به نوشته‌ها

شبکه‌های عصبی بازگشتی – قسمت سوم LSTM

در قسمت قبل به توضیح شبکه‌های عصبی بازگشتی ساده و سپس به پیا‌ده‌سازی شبکه‌ بازگشتی ساده با تنسورفلو و کراس پرداختیم. در این قسمت میخواهیم به توضیح شبکه‌های عصبی بازگشتی با سلول LSTM (به طور خلاصه شبکه‌های LSTM) بپردازیم.

درحالی‌که شبکه‌های عصبی بازگشتی ساده (Simple RNN) ابزاری بسیار قوی محسوب می‌شوند اما از برخی مشکلات اساسی مانند محو گرادیان (vanishing gradient) و عدم یادگیری توالی‌های بلند رنج می‌برند.
به عنوان مثال، تسک مدل زبانی (Language modeling) را در نظر بگیرید. در این تسک هدف ما، حدس کلمة هدف (target) با توجه به کلمات قبلی (گاهی اوقات بعدی) است. در عبارت «آب شدن یخ‌های قطبی و گرمایش زمین» برای حدس کلمه «زمین» اطلاعات بیشتری لازم نداریم و شبکة بازگشتی ساده (Simple RNN) به‌راحتی می‌تواند کلمة هدف را حدس بزند. اما فرض کنید طول عبارت ورودی بلند باشد و برای حدس کلمه آخر به اطلاعات بیشتری نیاز داشته باشیم. برای مثال:

آن پسر در ایران به دنیا آمد. او ازدواج کرد و سه فرزند دارد. او مدرک کارشناسی ارشد خود را در دانشگاه استنفورد در سال ۲۰۱۶ دریافت کرد و سپس برای کار به سویس مهاجرت کرد و در دانشگاه پلی‌تکنیک سویس مشغول به تدریس شد. او در زمینه الگوریتم و هوش مصنوعی دکترای خود را دریافت کرد. زبان مادری وی فارسی …

همانطور که مشاهده میکنید پاراگراف بالا عبارت نسبتا طولانی‌تری است و برای حدس کلمة «فارسی» شبکه باید اطلاعات بسیار قبل‌تری را به خاطر بسپارد. شبکة بازگشتی ساده (Simple RNN) در به خاطر سپردن توالی‌های بلند با مشکل مواجه‌‌ است و قادر به نگهداری اطلاعات به مدت طولانی نیست.

مشکلات بالا سبب شده است تا در اکثر پژوهش‌های اخیر از نسخه‌های توسعه‌یافته این شبکه استفاده شود. یکی از معماری‌های ارائه شده حافظه کوتاه-مدت ماندگار (LSTM) نام دارد. این معماری دقیقاً به این علت طراحی شده است تا توالی‌های طولانی را به خاطر بسپارد. همانند شبکه بازگشتی ساده، این شبکه حالتِ تکرار شدنی خود را دارد اما واحد تکرارشونده (سلول) آن اندکی پیچیده‌تر است.

اگر خاطرتان باشد گفتیم که شبکه بازگشتی ساده به صورت زیر است:

ساختار داخلی شبکه بازگشتی

اگر به دو شکل بالا دقت کنید به شباهت شبکه LSTM و شکبه Simple RNN پی خواهید برد. هر دو شبکه یک ورودی \(x_{t}\) میگیرند و یک خروجی \(h\) یا \(y\) (با رنگ بنفش در شکل مشخص شده است) برمیگردانند و برای مرحله بعدی (سلول بعدی) یک بردار وضعیت (state vector) تولید می‌کنند (در شبکه LSTM بردار وضعیت به دو قسمت شکسته شده است).

به عبارت دیگر، هر دو شبکه یک توالی از کلمات (به صورت برداهای نهفته – مثل ورد۲وک) دریافت میکنند و یک بردار خروجی y (چگال) برمیگردانند که از آن میتوان در تسک‌های مختلف استفاده کرد (مثل شکل زیر):

همچنین گفتیم که هر تابع بازگشتی را میتوان به دو تابع اصلی شکست:

  • قسمت بازگشتی یا Recurrent که آن را با R نمایش میدهیم.
  • قسمت خروجی یا Output که آن را با O نمایش میدهیم.

فرمول شبکه بازگشتی ساده

همین ساختار برای شبکه‌های تمام شبکه‌های بازگشتی از جمله LSTM یا GRU وجود دارد اما با اندکی تفاوت!

همانطور که در شکل اول مشاهده می‌شود برخلاف شبکه‌های بازگشتی ساده که یک خروجی به واحد (سلول) بعدی داشتیم در اینجا بردار وضعیت ما \(s_{i}\) به دو قسمت تبدیل شده است (خروجی که به مرحله بعدی میرود دو قسمت است). پس در نتیجه تابع بازگشتی (یا همان R) که بردار وضعیت را برای ما تولید میکرد باید دو مقدار برگرداند. پس همون چیزایی که برای شبکه بازگشتی ساده داشتیم رو میتونیم برای شبکه بازگشتی با سلول LSTM به صورت زیر بنویسیم:

تنها فرق عبارت بالا با شبکه بازگشتی ساده این است که خروجی تابع بازگشتی (R) را به دو قسمت به نام‌های c و h تبدیل کردیم. یا به عبارت دیگر اگر c و h رو بهم بچسبانیم، بردار وضعیت (s) را برای شبکه LSTM به دست میاوریم.

خب حالا سوالی که مطرح میشود این است که تابع بازگشتی داخلش چی هست؟ چطوری بردار وضعیت \(s_{i}\) را تولید میکند یا به عبارت دیگه چطوری این بردار c و h را می‌سازد؟ اگر خاطرتان باشد در شبکه بازگشتی ساده تابع R یک tanh بود. اما در اینجا اندکی پیچیده‌تر خواهد شد. در این شبکه بردارهای h و c خودشان از عبارت‌های زیر به دست آورده‌ میشوند:
همانطور که ملاحضه می‌کنید چندتا متغیر دیگر هم اضافه شد. خب بیایید ببینیم متغیرهای بالا چی هستند. این متغیر‌ها رو به ترتیب تعریف میکنیم:

  • متغیر i که اصلاحا به آن input gate گفته میشود.
  • متغیر f که اصلاحا به آن forget gate گفته میشود.
  • متغیر o که اصلاحا به آن output gate گفته میشود.
  • متغیر z که اسمش رو میزاریم candid update.

متغیرهای بالا هریک وظایف جالبی دارند و میتوانیم آنها را به صورت زیر به دست آوریم:

از  ۴تا عبارت‌ بالا نترسید 🙂 در هر عبارت مقدار \(x_{j}\) و \(h_{j-1}\) (بردار مخفی سلول قبل) از شبکه feed forward عبور دادیم و با سپس با یکدیگر جمع کردیم و در نهایت هم از یک تابع غیرخطی سیگمویید σ یا tanh عبور دادیم. همچنین دقت داشته باشید که اندیسهای \(W\) با یکدیگر متفاوت است پس در نتیجه به ازای هرکدام از مقادیر i  , f و o شبکه‌های feedforward مجزا خواهیم داشت (جمعا ۸ تا شبکه feedforward یک لایه داریم).

خب حالا فرض کنید میخواهیم عبارت اول یعنی بردار i را بدست آوریم (با فرض اینکه بردار ورودی \(x_{j}\) طولش ۳۰۰ باشه و سایز لایه مخفی \(h_{j-1}\) هم ۱۰۰ باشه):

همانطور که در عکس بالا مشاهده می‌کنید برای به دست آوردن بردار نهایی که یک بردار 1*100 است ۳ قسمت داریم:

۱) قسمت بالایی: اطلاعات مراحل قبلی در \(h_{j-1}\) ذخیره شده است که اگر آن را در یک شبکه feedforward با پارامتر \(W^{hi}\) اندازه 100*100 ضرب کنیم نتیجه یک بردار 1*100 خواهد شد.

۲) قسمت پایینی: اطلاعات جدید یا همان بردار ورودی که با \(x_{j}\) نمایش دادیم در یک شبکه feedforward یک لایه که پارامتر آن \(W^{xi}\) و اندازه 300*100 است ضرب میکنیم و نتیجه حاصل آن یک بردار 1*100 خواهد شد.

۳) قسمت non linear و جمع دو بردار: در دو مرحله قبلی دو بردار 1*100 به دست آوردیم اگر این دو بردار را جمع کنیم و از یک تابع غیرخطی سیگمویید عبور دهیم ما توانسته‌ایم بردار نهایی \(i\) را بدست بیاوریم.

این کار رو به ازای سایر متغییرها (f، o و z) به همین صورت انجام می‌دهیم و به ازای هر کدام یک بردار به دست می‌آوریم.

بردارهایی که از طریق تابع غیر خطی سیگمویید به دست آمده‌اند (i، o و f) نقش گیت (gate) را خواهد داشت. یعنی چی؟ بیایید یکم به تابع خاصیت تابع غیرخطی‌ سیگمویید () بپردازیم. اگر دقت کنید هر سه متغیر (i, f, o) از یک تابع غیر خطی سیگموید عبور داده شده است. خاصیتی که این تابع دارد این است که مقادیر بردار ورودی رو بین صفر و یک تبدیل میکنه (مثل عبارت زیر).


sigmoid ([2, -3, 1, 0, 5, -1]) => [0.88079708 0.04742587 0.73105858 0.5 0.99330715 0.26894142]

پس در نتیجه هرکدام از بردارهای f, i و o یک بردار نرمال شده هستند که مقادیرشون بین ۰ و ۱ است. که مقدار صفر یعنی هیچی عبور نده و مقدار یک یعنی تمام مقدار رو عبور بده. یعنی چی؟  یه بار دیگه به فرمول زیر نگاه کنید:

اگر دقت کنید این بردارها رو در متغیرهای \(z\) و \(c\) و \(tanh(c)\) ضرب نقطه‌ای (نظیر به نظیر) می‌کنیم. هنگامی که مقدار یکی از درایه‌های بردار صفر یا نزدیک به صفر باشه درایه‌های بردار متناظر را صفر می‌کند و هنگامی هم که یک باشد آن را اصلا تغییر نمیدهد. پس در نتیجه اگر مثلا یکی از درایه‌های \(i\) صفر باشه به این معنی است که داریه نظیر به نظیر آون در \(z\) را عبور ندهد. حالا فهمیدید منظور از دریچه چیه؟

این دریچه‌ها هرکدوم برای برآورده کردن هدفی طراحی شدند. دریچه \(f\) به این دلیل طراحی شده است تا تصمیم بگیریم که چه مقدار اطلاعات قبلی را نگه داریم و چه مقداری را فراموش کنیم. دریچه \(i\) به این علت طراحی شده است که تصمیم بگیریم چه بخشی از اطلاعات ورودی (\(x\)) را نگه داریم و چه بخشی از آن فراموش کنیم. دریچه \(o\) هم مشابه قبل میخواهد تصمیم بگیریم چه اطلاعاتی را برای سلول بعدی بفرستیم و چه مقداری را فراموش کنیم. و در نهایت متغیر \(z\) که اگر به آن نگاه کنید مشابه آن چیزی است که در تابع بازگشتی ساده داشتیم.

خب حالا که تمام متغیرها را تعریف کردیم و فهمیدیم چطوری به دست آورده میشوند در فرمول زیر قرار میدهیم:

خب همانطور که میبینید قسمت اول و مهم توابع بازگشتی یعنی بردار وضعیت \(s_{j}\) را بدست آوردیم (دقت کنید بردار وضعیت در شبکه LSTM از چسباندن \(c_{j}\) و \(h_{j}\) به دست می‌آید).

تنها یک چیز موند و آن هم بردار خروجی یا \(y\) است. تابع \(O\) عملا هیچ کاری برای ما انجام نمیدهد و صرفا مقدار h را برمیگرداند یعنی:

پس تمام اون چیزی که برای شبکه‌های بازگشتی با سلول LSTM داشتیم رو به دست آوردیم.

شبکه‌های بازگشتی با سلول GRU مانند مکانیزم بالا عمل می‌کنند و تنها فرقش این است که به جای ۳ گیت از ۲ گیت استفاده میکند که در نتیجه از نظر سرعت بهبود نسبتا خوبی خواهیم داشت و در حین نتایجی که می‌دهد تقریبا با مدل LSTM یکسان است.

در قسمت بعدی به سراغ مدل Transformer خواهیم رفت و معایب شبکه‌های عصبی بازگشتی را بررسی میکنیم.

منتشر شده در آموزشپردازش زبان طبیعییادگیری عمیق

نظر

  1. سعید کامرو سعید کامرو

    خیلی خوب بود دستتون درد نکنه اگر مرحله به مرحله محاسبات رو داخل شبکه طی یک مثال عددی نشون بدید خیلی بهتر هم میشه.

    • هادیفر هادیفر

      مرسی از پیشنهادتون سعی میکنم این مورد رو اضافه کنم

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *