آموزشترنسفورمرها

درس ۱۷ از ۶۲، هوش مصنوعی، حدود ۱۲ دقیقه خواندن

توجه با دست: سه کلمه، عددهای واقعی

جواب کوتاه

توی این درس فرمول توجه رو یه بار کامل با دست حساب می‌کنیم، برای جمله‌ی ساختگی «گربه شیر خورد». هر کلمه یه پرسش و یه کلید ۴ عددی و یه مقدار ۲ عددی داره. پرسش «خورد» با کلید هر سه کلمه ضرب می‌شه و امتیازهای ۲ و ۲ و ۰ درمیاد. چون d برابر ۴ هست، امتیازها بر ریشه‌ش، یعنی ۲، تقسیم می‌شن و می‌شن ۱ و ۱ و ۰. سافت‌مکس این‌ها رو می‌کنه حدود ۰٫۴۲ و ۰٫۴۲ و ۰٫۱۶. آخر، این وزن‌ها در مقدارها ضرب و جمع می‌شن و خروجی «خورد» می‌شه ۲ و ۲؛ یعنی «خورد» حالا هم از گربه خبر داره، هم از شیر.

یعنی چی

یه کاغذ، سه کلمه، چند تا عدد کوچیک؛ کل فرمول توجه، با دست.

توی درس فرمول کامل پنج قدم توجه رو دیدیم. ولی تا آدم یه بار خودش با عدد حسابش نکنه، ته ذهنش یه کم مبهم می‌مونه. پس اینجا یه جمله‌ی کوتاه و ساختگی برمی‌داریم، «گربه شیر خورد»، و همه‌ی قدم‌ها رو با عدد می‌ریم. ماسک رو هم کنار می‌ذاریم، چون این جمله لازمش نداره.

پرسش، کلید، مقدار

توی مدل واقعی، پرسش و کلید و مقدار از ضرب بردار هر کلمه در سه ماتریس درمیان؛ این رو توی درس پرسش، کلید و مقدار دیدیم. اینجا برای اینکه حساب کوتاه بمونه، خود نتیجه‌ها رو آماده گذاشتیم. پرسش و کلید هر کلمه ۴ عدد دارن، پس d می‌شه ۴. مقدارها رو دو عددی گرفتیم: مقدار «گربه» ۴ و ۰، «شیر» ۰ و ۴، «خورد» ۲ و ۲. همه‌ی این عددها ساختگی‌ان.

امتیازها

قدم اول، ضرب هر پرسش در هر کلید، همون امتیاز توجه. مثلا پرسش «خورد» این چهار تا عدده: ۲ و ۲ و ۰ و ۰. کلید «گربه» ۱ و ۰ و ۱ و ۰. عددهای هم‌جا رو ضرب می‌کنیم: ۲ ضرب در ۱ می‌شه ۲، بقیه صفر؛ جمعشون ۲. با کلید «شیر» هم ۲ درمیاد، و با کلید خودش صفر. بقیه‌ی جدول هم همین‌طور ساخته می‌شه. از اینجا به بعد فقط ردیف «خورد» رو دنبال می‌کنیم؛ بقیه‌ی ردیف‌ها دقیقا همین راه رو می‌رن.

ردیف «خورد»

امتیازهای «خورد» شدن ۲ و ۲ و ۰. قدم دوم، تقسیم بر ریشه‌ی d. چون d می‌شه ۴ و ریشه‌ش ۲، امتیازها می‌شن ۱ و ۱ و ۰. قدم سوم، سافت‌مکس، که وزن‌ها رو می‌سازه: حدود ۰٫۴۲ و ۰٫۴۲ و ۰٫۱۶. یعنی «خورد» به «گربه» و «شیر» به یه اندازه نگاه می‌کنه، و به خودش کمتر. منطقی هم هست؛ کسی که خورد گربه بود، چیزی که خورده شد شیر.

سافت‌مکس با دست

اون ۰٫۴۲ از کجا اومد؟ توی درس سافت‌مکس دیدیم که سافت‌مکس اول هر عدد رو می‌کنه e به توان اون عدد؛ e یه عدد ثابته، حدود ۲٫۷۲. پس ۱ می‌شه حدود ۲٫۷۲، و ۰ می‌شه ۱، چون هر عددی به توان صفر یکه. حالا جمعشون رو می‌گیریم: ۲٫۷۲ به‌علاوه‌ی ۲٫۷۲ به‌علاوه‌ی ۱ می‌شه حدود ۶٫۴۴. هر کدوم رو بر این جمع تقسیم می‌کنیم: ۲٫۷۲ تقسیم بر ۶٫۴۴ می‌شه حدود ۰٫۴۲، و ۱ تقسیم بر ۶٫۴۴ حدود ۰٫۱۶. جمع وزن‌ها هم می‌شه یک، همون‌طور که باید.

ضرب در مقدار

قدم آخر، هر مقدار رو در وزنش ضرب می‌کنیم و همه رو جمع می‌زنیم. ۰٫۴۲ ضرب در مقدار «گربه» می‌شه ۱٫۶۸ و ۰؛ ۰٫۴۲ ضرب در مقدار «شیر» می‌شه ۰ و ۱٫۶۸؛ ۰٫۱۶ ضرب در مقدار «خورد» می‌شه ۰٫۳۲ و ۰٫۳۲. جمع عددهای اول می‌شه ۲، جمع عددهای دوم هم ۲. پس خروجی «خورد» می‌شه ۲ و ۲. عدد اولش بیشترش از «گربه» اومده و عدد دومش بیشترش از «شیر». یعنی بعد از این لایه، «خورد» دیگه فقط خودش نیست؛ یه کم از فاعلش و یه کم از مفعولش رو هم با خودش داره.

یه ردیف دیگه: «گربه»

حالا که یه ردیف رو با هم رفتیم، ردیف «گربه» رو هم حساب کنیم؛ این بار عددها یه کم کمتر گرده.

پرسش «گربه» ۱ و ۰ و ۱ و ۰ هست. ضربش با کلید «گربه» می‌شه ۲، با کلید «شیر» صفر، و با کلید «خورد»، که ۰ و ۰ و ۱ و ۱ هست، می‌شه ۱. تقسیم بر ۲: ۱ و ۰ و ۰٫۵. حالا سافت‌مکس: e به توان ۱ حدود ۲٫۷۲، به توان صفر ۱، و به توان ۰٫۵ حدود ۱٫۶۵. جمعشون حدود ۵٫۳۷. پس وزن‌ها می‌شن حدود ۰٫۵۱ و ۰٫۱۹ و ۰٫۳۱.

آخر هم ضرب در مقدارها: ۰٫۵۱ ضرب در ۴ و ۰، به‌علاوه‌ی ۰٫۱۹ ضرب در ۰ و ۴، به‌علاوه‌ی ۰٫۳۱ ضرب در ۲ و ۲، که می‌شه حدود ۲٫۶۴ و ۱٫۳۶. یعنی «گربه» بیشتر از همه خودش موند، یه کم از «خورد» گرفت و کمتر از «شیر». اگه ردیف «شیر» رو هم حساب کنید، چون عددهاش قرینه‌ی «گربه»ست، جوابش برعکس درمیاد: ۱٫۳۶ و ۲٫۶۴.

همین با چند خط برنامه

اگه برنامه‌نویسی بلدید، کل این حساب توی چند خط پایتون جا می‌شه. اگه بلد نیستید، این بخش رو رد کنید؛ چیزی از دست نمی‌دید.

این همون ردیف «گربه»ست، با همون عددها:

import math
q = [1, 0, 1, 0]
keys = [[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 1]]
vals = [[4, 0], [0, 4], [2, 2]]
s = [sum(a * b for a, b in zip(q, k)) / 2 for k in keys]
e = [math.exp(x) for x in s]
w = [x / sum(e) for x in e]
out = [sum(w[j] * vals[j][c] for j in range(3)) for c in range(2)]
print(w, out)
# [0.506, 0.186, 0.307] [2.64, 1.36]

خط پنجم امتیاز و تقسیم بر ۲ هست، خط ششم و هفتم سافت‌مکس، و خط هشتم ضرب در مقدارها. توی مدل‌های واقعی همین کار با کتابخونه‌هایی انجام می‌شه که کل جدول رو یه‌جا ضرب می‌کنن، نه ردیف‌به‌ردیف؛ ولی جواب همونه.

چند نکته

  • هر ردیف جدا حساب می‌شه، ولی همه با هم اجرا می‌شن.
  • خروجی هم‌اندازه‌ی مقدارهاست. اینجا دو عدد.
  • عددهای واقعی رو مدل یاد می‌گیره. اینجا ساختگی بودن.
  • مدل واقعی این کار رو چند بار کنار هم می‌کنه؛ درس توجه چندسر.

کاری که اینجا کردیم، یعنی هر کلمه‌ی یه جمله به کلمه‌های همون جمله نگاه کنه، یه اسم داره. درس بعد: خودتوجهی (Self-attention).

جمع‌بندی. آنچه از این درس با خودتان می‌برید.

  • پرسش «خورد» × سه کلید: ۲، ۲، ۰.
  • تقسیم بر ریشه‌ی ۴: ۱، ۱، ۰.
  • سافت‌مکس: ۰٫۴۲، ۰٫۴۲، ۰٫۱۶.
  • وزن‌ها × مقدارها، بعد جمع.
  • خروجی «خورد»: نیمی گربه، نیمی شیر.

خودتون رو بسنجید

۱۵ پرسش، هر بار تازه از میان ۳۰ پرسش این درس. آخرش فقط کارنامه رو می‌بینید: چند تا درست، چند تا نادرست.

خودتون رو بسنجید

۱۵ پرسش

  • هر بار پرسش‌ها و ترتیب گزینه‌ها عوض می‌شه.
  • تا آخر نمی‌گیم کدوم جواب درست بوده؛ می‌تونید برگردید و جوابتون رو عوض کنید.
  • آخرش کارنامه می‌گیرید: چند تا درست، چند تا نادرست.
  • اگه وسطش بستید، دوباره که باز کنید از همون‌جا ادامه می‌دید.

فصل‌های این درس

درس بعد