LSTM و GRU: حافظه با دریچه
جواب کوتاه
LSTM، کوتاهشدهی Long Short-Term Memory، که سال ۱۹۹۷ معرفی شد، یه جور شبکهی بازگشتیه که برای حل فراموشی ساخته شد. یه «سلول» حافظه داره که مثل یه نوار از همهی قدمها رد میشه، و سه دریچه که هر کدوم یه عدد بین ۰ و ۱ میدن: دریچهی فراموشی میگه چی از حافظه پاک بشه، دریچهی ورودی میگه چی تازه نوشته بشه، و دریچهی خروجی میگه چی از حافظه بیرون بیاد. چون حافظه با جمع بهروز میشه و دریچهی فراموشی میتونه نزدیک ۱ بمونه، یه یادداشت مهم میتونه قدمهای خیلی زیادی سالم بمونه. GRU، از ۲۰۱۴، نسخهی سبکترشه با دو دریچه و پارامتر کمتر، و توی بعضی کارها همونقدر خوب. ولی هر دو هنوز یکییکی میخونن.
یعنی چی
یه دفترچه با سه تصمیم: چی رو پاک کنم، چی رو بنویسم، چی رو بخونم.
توی درس مشکلهای RNN دیدیم یادداشت شبکهی بازگشتی هر قدم در یه عدد ضرب میشه و کمکم محو میشه. حالا فرض کنید بهجای یادداشتی که خودبهخود هر قدم عوض میشه، یه دفترچه داشته باشید که خودتون تصمیم بگیرید چی رو پاک کنید، چی رو اضافه کنید، و چی رو بلند بخونید. اگه چیزی مهمه، پاکش نمیکنید و تا آخر سالم میمونه. LSTM، کوتاهشدهی Long Short-Term Memory، یعنی «حافظهی کوتاهمدت بلند»، همین ایدهست؛ سال ۱۹۹۷ معرفی شد و هدفش حافظهایه که بتونه خیلی بیشتر از یه شبکهی بازگشتی ساده دوام بیاره.
سه دریچه
قلب LSTM یه «سلول» حافظهست، مثل یه نوار که از هر قدم رد میشه. سه دریچه کنارشن و هر کدوم، از روی کلمهی الان و حالت قبلی، یه عدد بین ۰ و ۱ میسازن. دریچهی فراموشی حافظهی قبلی رو در این عدد ضرب میکنه: ۱ یعنی همه رو نگه دار، ۰ یعنی همه رو پاک کن. دریچهی ورودی میگه چقدر از اطلاعات تازه به حافظه اضافه بشه. و دریچهی خروجی میگه چه بخشی از حافظه بهعنوان خروجی همین قدم بیرون بیاد. دریچهی فراموشی، جالبه، توی نسخهی اول نبود و چند سال بعد اضافه شد.
یه قدم با دست
بیاید یه قدم LSTM رو با عددهای ساختگی، کامل با دست حساب کنیم.
فرض کنید حافظهی قبلی ۱ بوده. دریچهی فراموشی این قدم ۰٫۹ میده، یعنی ۹۰ درصدش رو نگه دار. دریچهی ورودی ۰٫۵ میده، و چیز تازهای که میخواد نوشته بشه ۰٫۸ هست. پس حافظهی تازه میشه ۰٫۹ ضرب در ۱، که ۰٫۹ میشه، بهعلاوهی ۰٫۵ ضرب در ۰٫۸، که ۰٫۴ میشه؛ روی هم ۱٫۳. برای خروجی، حافظه رو از همون تابع فشردهکننده رد میکنن، که ۱٫۳ رو حدود ۰٫۸۶ میکنه، و در دریچهی خروجی، ۰٫۷، ضرب میکنن: حدود ۰٫۶۰.
ببینید حافظه چطور بزرگتر شد، نه کوچیکتر: چون با جمع بهروز شد. و خروجی، ۰٫۶۰، با خود حافظه، ۱٫۳، فرق داره؛ یعنی LSTM میتونه یه چیزی رو توی حافظه نگه داره بی اینکه همین الان بیرونش بده.
چرا جواب میده
فرقش با شبکهی بازگشتی ساده یه جملهست: حافظهی تازه با جمع ساخته میشه، نه با رد شدن از یه ضرب ثابت. حافظهی تازه میشه حافظهی قبلی ضرب در دریچهی فراموشی، بهعلاوهی چیز تازه. و این دریچه رو خود شبکه یاد میگیره.
یه حساب ساختگی: اگه دریچهی فراموشی برای یه یادداشت مهم یاد بگیره ۰٫۹۹ باشه، بعد از ۵۰ قدم هنوز حدود ۰٫۶۱ از اون یادداشت مونده. توی شبکهی سادهی درس قبل، با ضرب در ۰٫۸، فقط حدود ۰٫۰۰۰۰۱ میموند. همین مسیر برای سیگنال آموزش هم هست: ویکیپدیا میگه LSTM اجازه میده گرادیان تقریبا بیکاهش جریان پیدا کنه، پس محو شدن رو تا حد زیادی حل میکنه.
یه مثال
همون جملهی درس دنباله، کوتاهشده: «بچهها دیروز با دوستاشون به پارک رفتن».
وقتی LSTM «بچهها» رو میخونه، دریچهی ورودی میتونه یه یادداشت بنویسه: فاعل جمعه. بعد توی کلمههای وسط، دریچهی فراموشی این یادداشت رو نزدیک ۱ نگه میداره، یعنی پاکش نمیکنه. وقتی به فعل میرسه، دریچهی خروجی اون رو میخونه و شبکه «رفتن» رو انتخاب میکنه، نه «رفت». این مثال ساختگیه، ولی ویکیپدیا هم میگه ایدهی LSTM همینه که یاد بگیره کی چیزی رو نگه داره و کی فراموش کنه، و مثلا توی زبان ربطهای دستوری رو یاد بگیره.
GRU
سال ۲۰۱۴ یه نسخهی سبکتر اومد به اسم GRU، یعنی «واحد بازگشتی دریچهدار». همون ایدهی دریچه رو داره، ولی سلول جدا و دریچهی خروجی نداره؛ فقط دو دریچه: بهروزرسانی و بازنشانی. برای همین پارامتر کمتری داره. توی بعضی کارها، مثل مدل کردن موسیقی و گفتار و زبان، نتیجهش شبیه LSTM بود، و پژوهشگرهایی که مقایسهشون کردن به نتیجهی قطعی نرسیدن کدوم بهتره. پیام اصلی: خود دریچه کمک میکنه، نه تعداد دقیقش.
چند تا وزن
این همه دریچه بیهزینه نیست.
هر دریچه وزنهای خودش رو داره، و «چیز تازه» هم یه دستهی دیگه. پس LSTM چهار دسته وزن داره جایی که شبکهی بازگشتی ساده یه دسته داره، و GRU سه دسته. با یه حساب ساده، اگه حافظه ۱۰۰ عدد و ورودی ۵۰ عدد باشه، شبکهی ساده حدود ۱۵ هزار وزن داره، GRU حدود ۴۵ هزار و LSTM حدود ۶۰ هزار. برای همین GRU رو «سبکتر» میگن: یه چهارم کمتر، با همون ایدهی دریچه.
هشت نسخه
از ۱۹۹۷ تا ۲۰۱۵ کلی نسخهی مختلف از LSTM ساخته شد. یه پژوهش ۲۰۱۵ پرسید: کدومش واقعا بهتره؟
هشت نسخه رو روی سه کار، تشخیص گفتار، تشخیص دستخط و ساختن موسیقی چندصدایی، با ۵۴۰۰ آزمایش مقایسه کردن؛ حدود ۱۵ سال کار یه پردازنده. نتیجهی اصلیشون این بود که هیچکدوم از نسخهها LSTM معمولی رو خیلی بهتر نکرد. و دو تا بخش از همه مهمتر بودن: دریچهی فراموشی، و تابعی که خروجی رو فشرده میکنه؛ برداشتن هر کدوم کار رو خرابتر میکرد. یعنی همون فکر سادهی «یه دریچه که بگه چی رو نگه دار»، قلب ماجراست.
چی هنوز مونده
LSTM فراموشی رو خیلی کم کرد و سالها توی ترجمه، تشخیص گفتار و سریهای زمانی به کار رفت. ولی سه مشکل باقی موند. اول، هنوز یکییکی میخونه؛ پس همون کندی درس قبل سر جاشه. دوم، حافظه هنوز اندازهی ثابت داره؛ هر چقدر هم خوب نگهش داره، یه دفترچهست، نه کل کتاب. سوم، طبق ویکیپدیا هنوز ممکنه سیگنال منفجر بشه. ترنسفورمر برای اولی و دومی اومد. ولی پیش از اون، باید ببینیم LSTM چطور برای ترجمه به کار رفت.
چند نکته
- سلول، نوار حافظهست. از همهی قدمها رد میشه.
- فراموشی، ورودی، خروجی. هر کدوم یه عدد بین ۰ و ۱.
- جمع بهجای ضرب ثابت. برای همین یادداشت سالم میمونه.
- GRU: دو دریچه، همون ایده، سبکتر.
درس بعد دو تا LSTM رو کنار هم میذاره تا جمله ترجمه کنن: رمزگذار و رمزگشا (seq2seq).
جمعبندی. آنچه از این درس با خودتان میبرید.
- یه نوار حافظه، از همهی قدمها رد میشه.
- سه دریچه: پاک کن، بنویس، بخون.
- دریچهی نزدیک ۱، یادداشت رو نگه میداره.
- GRU: دو دریچه، سبکتر.
- هنوز یکییکی؛ هنوز کند.
خودتون رو بسنجید
۱۵ پرسش، هر بار تازه از میان ۳۰ پرسش این درس. آخرش فقط کارنامه رو میبینید: چند تا درست، چند تا نادرست.