ترجمه شده توسط سایت ZeroToHero
در بخش اول دیدیم هنگامی که میخواهیم مسئلهای را حل کنیم، بدون این که لازم باشد کدی مخصوص به آن مسئله بنویسیم، یادگیری ماشین با استفاده از الگوریتمهای عمومی اطلاعات جالبی در مورد دادههای ما کشف میکند. (اگر هنوز بخش اول را نخواندهاید، همین الان این کار را بکنید!)
مجموعه ی یادگیری ماشین جذاب است!
این بار قصد داریم به کمک یکی از این الگوریتمها، یک کار خیلی جالب انجام بدهیم. میخواهیم مراحل یک بازی کامپیوتری را طوری بسازیم که انگار توسط انسان طراحی شده است. برای این کار از یک شبکه عصبی استفاده میکنیم، مراحل موجود در بازی سوپر ماریو را به عنوان ورودی به آن میدهیم و مرحله جدیدی که خودبهخود ساختهشده است را به عنوان خروجی مشاهده خواهیم کرد!
دقیقاً مانند قسمت اول، این راهنما برای همه آنهایی است که در مورد یادگیری ماشین کنجکاوند اما نمیدانند از کجا شروع کنند. بنابراین هدف این است که این نوشته برای همه افراد قابل درک باشد و این یعنی از جزئیات دقیق خبری نیست و بسیاری از مفاهیم به صورت کلی بیان خواهد شد. اما مشکلی نیست، چون اگر این راهنما بتواند کسی را بیشتر به یادگیری ماشین علاقهمند کند ما مأموریتمان را انجام دادهایم.
چطور هوشمندانه تر حدس بزنیم؟
در بخش اول، ما الگوریتم ساده ای نوشتیم که ارزش یک خانه را بر اساس مشخصاتش تخمین میزد. هر خانه مشخصاتی مانند جدول زیر داشت:

و در پایان به تابع تخمین ساده زیر رسیدیم:
def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): price = 0 # a little pinch of this price += num_of_bedrooms * 0.123 # and a big pinch of that price += sqft * 0.41 # maybe a handful of this price += neighborhood * 0.57 return price
به عبارت دیگر، ما ارزش خانه را از ضرب هر کدام از مشخصهها در یک وزن و در نهایت جمع آنها بدست آوردیم.
به جای کد، اجازه دهید این تابع ساده را در قالب یک نمودار ساده ببینیم :

اما این الگوریتم تنها برای مسائل سادهای که نتایج آنها رابطهای خطی با ورودی دارد قابل استفاده است. اما اگر حقیقت پشت قیمت گذاری خانه ها در این حد ساده نباشد چه باید کرد؟ برای مثال، شاید این که خانه در کدام محله قرار دارد برای خانههای بزرگ و خانههای کوچک اهمیت زیادی داشته باشد، اما اصلاً برای خانههایی با اندازه متوسط اهمیت نداشته باشد. چنین جزئیات پیچیدهای (غیرخطی) را چطور میتوان در مدل ساخته شده قرار داد؟
برای این که در تخمین زدن باهوش تر عمل کنیم، میتوانیم این الگوریتم را چندین بار با وزن های متفاوت اجرا کنیم و در نتیجه هر بار خروجی متفاوتی خواهیم داشت :

اکنون چهار تخمین قیمت متفاوت داریم. بیایید این چهار تا را با هم ترکیب کنیم تا به یک تخمین نهایی برسیم. مجدداً همان الگوریتم را این بار با مجموعه جدیدی از وزنها اجرا میکنیم.

ابَرپاسخ ما به این مسئله، خروجی تخمین های چهار تلاش قبلی را با هم ترکیب میکند. بنابراین، میتواند مدلهای پیچیده تری را نسبت به مدل ساده اولیه پوشش دهد.
شبکه عصبی چیست؟
اگر نمودار کامل مراحلی که انجام دادیم را رسم کنیم به شکل زیر خواهد بود :

این نمودار یک شبکه عصبی است! هر نود ( گره ) میداند که چطور مجموعه ای از ورودیها را بگیرد، به هر کدام وزن مشخصی اعمال کند، و یک مقدار خروجی محاسبه کند. اگر تعداد زیادی از این نود ها را زنجیروار به هم متصل کنیم، میتوانیم به مدلی برسیم که توابع پیچیده را پوشش میدهد.
در این جا برای حفظ سادگی مطلب از جزئیات زیادی صرف نظر کردیم (مانند گسترش ویژگی و تابع فعالسازی)، اما مهم ترین نکته این است که همین ایده ساده جرقه هایی در ذهن ایجاد کرد:
- ما یک تابع تخمین ساده ساختیم که مجموعهای از ورودیها را می گیرد، آنها در مجموعه ای از وزن ها ضرب میکند و یک خروجی بر می گرداند. این تابع ساده را نورون می نامیم.
- با اتصال زنجیروار تعداد زیادی از این نورون های ساده به هم دیگر، میتوانیم به مدل هایی برسیم که نسبت به یک تک نورون توانایی پوشش توابع پیچیده تری دارند.
درست مانند لگو! ما نمیتوانیم با یک قطعه ساده لگو چیز خاصی بسازیم، اما اگر به تعداد کافی از این لگوها داشته باشیم، با اتصال آنها به همدیگر میتوانیم هر چیزی بسازیم.

آیا یک شبکه عصبی میتواند حافظه داشته باشد؟
نوعی از شبکه عصبی که در مثال قبل دیدیم هر بار با ورودی های یکسان، جواب یکسانی به عنوان خروجی ایجاد می کند. بنابراین حافظه ندارد یا به بیان برنامه نویسی، الگوریتمی بدون حالت ( stateless ) است.
در اکثر موارد (مانند تخمین ارزش خانه)، این دقیقاً همان چیزی است که میخواهیم. اما کاری که این الگوریتم قادر به انجام آن نیست، پاسخگویی به الگوهای داده در گذر زمان است.
تصور کنید من یک کیبرد به شما می دهم و از شما می خواهم یک داستان بنویسید. اما قبل از این که شروع کنید، وظیفه من این است که حدس بزنم اولین حرفی که با آن شروع می کنید کدام است. کدام یک از حروف الفبا را باید انتخاب کنم؟
من میتوانم از دانش زبانی استفاده کنم تا احتمال درست بودن حدس خودم را بالا ببرم. برای مثال، من میتوانم با بررسی لغات زبان فارسی ببینم اکثر کلمات با کدام حرف شروع میشوند. اگر من به داستانهایی که شما در گذشته نوشته اید رجوع کنم، احتمالاً کلماتی وجود دارند که شما در آغاز داستان بیشتر از آن ها استفاده کرده اید. به این ترتیب گزینه های احتمالی که من میتوانم به عنوان اولین حدس انتخاب کنم، کمتر میشود. وقتی که این داده ها را جمع آوری کردم، میتوانم از یک شبکه عصبی استفاده کنم تا احتمال شروع داستان شما با هر کدام از حروف الفبا مدل سازی کنم.
مدل ما به شکل زیر خواهد بود:

اجازه بدهید مسئله را کمی سخت تر کنیم. فرض کنید به جای شروع داستان، هدف این باشد که تا هر کجای داستان را که نوشته اید، بتوانیم حرف بعدی را حدس بزنیم. این مسئله به مراتب جالب تری است.
برای مثال، از چند کلمه اول یکی از کتابهای ارنست همینگوی به نام خورشید همچنان میدرخشد استفاده میکنیم:
Robert Cohn was once middleweight boxi
حرف بعدی چه خواهد بود؟
احتمالاً حدس شما حرف ‘n’ خواهد بود و احتمالاً کلمه مورد نظر boxing است. این را ما از جملاتی که تا به حال دیده ایم و دانش زبانیمان از کلمات متداول انگلیسی نتیجه گرفتیم. همچنین، کلمه قبلی یعنی middleweight به معنی میان وزن سر نخ خوبی است تا بدانیم احتمالاً موضوع به ورزش بوکس ربط دارد.
به عبارت دیگر، اگر دنباله حروفی که تا به این جا داریم را ارزیابی کنیم و از دانش قواعد زبان استفاده کنیم، حدس زدن حرف بعدی کار سختی نیست.
برای حل این مسئله توسط یک شبکه عصبی، لازم است برای مدل فعلی مان حالت ( state ) در نظر بگیریم. هر بار که از شبکه عصبی برای حدس زدن حرف بعدی سؤال میپرسیم، مجموعه ای از محاسبات میانی داریم که میتوانیم در مرحله بعدی آن ها را هم به عنوان بخشی از ورودی در نظر بگیریم. به این ترتیب، مدل ما پیش بینی هایش را بر اساس ورودی اخیراً مشاهده شده انجام خواهد داد.

در نظرگرفتن حالت برای مدل به ما اجازه میدهد بتوانیم نه تنها اولین حرف داستان، بلکه در هر زمان اولین حرف از ادامه داستان را بر اساس حروف قبلی پیش بینی کنیم.
همین ایده ساده، درونمایه شبکههای عصبی بازگشتی ( Recurrent Nerual Network ) است. در واقع با این کار با هر بار استفاده از شبکه آن را آپدیت میکنیم. بنابراین پیش بینی ها براساس آن چه اخیراً مشاهده شده به روز میشود. اگر به اندازه کافی برای آن حافظه در نظر بگیریم، حتی قادر است الگوها را در گذر زمان مدل کند.
حدس زدن یک حرف به چه دردی میخورد؟
حدس زدن حرف بعدی در یک داستان ممکن است کار بیهودهای به نظر برسد. اما یک استفاده جالب آن قابلیت auto-predict در کیبرد گوشی موبایل است:

اما به همین جا ختم نمیشود. می توانیم از همین ایده استفاده کنیم و از کامپیوتر بخواهیم با حدس زدن حرف به حرف ادامه داستان، در نهایت یک داستان کامل را از ابتدا تا انتها بنویسد!
تولید یک داستان
دیدیم که چطور میتوان حرف بعدی جمله همینگوی را حدس زد. حالا بیایید یک داستان کامل را به سبک همینگوی بنویسیم.
برای این کار، از پیادهسازی شبکه عصبی بازگشتی که آندری کارپاتی نوشته، استفاده خواهیم کرد. آندری یک محقق یادگیری عمیق در دانشگاه استنفورد است و همچنین یک متن عالی برای آشنایی با تولید متن به وسیله RNN نوشته است. تمامی کد ها را در گیتهاب میتوانید ببینید.
مدل مورد نظر را براساس متن کامل خورشید همچنان میدرخشد خواهیم ساخت. این متن ۳۶۲۲۳۹ کاراکتر دارد که از ۸۴ حرف منحصر به فرد ( شامل علائم نگارشی، حروف کوچک و بزرگ و غیره ) تشکیل شده است. این مجموعه داده در مقایسه با مسائل دنیای واقعی بسیار کوچک است. برای تولید یک داستان خیلی خوب به سبک همینگوی در واقع لازم است چندین برابر این مقدار داده آموزشی داشته باشیم. اما برای این که کمی سرگرم شویم و با یک مثال عملکرد الگوریتم را ببینیم کافی است.
در اوایل آموزش RNN چندان در پیشبینی حروف خوب عمل نمی کند. این چیزی است که بعد از تنها ۱۰۰ بار تکرار آموزش به دست آمده است :
hjCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr er deffijha
می بینید که متوجه شده گاهی بین کلمه ها فاصله قرار می گیرد، اما غیر از این موفقیت خاصی نداشته است.
بعد از ۱۰۰۰ بار تکرار، حاصل کمی امیدوار کننده تر است:
hing soor ither. And the caraos, and the crowebel for figttier and ale the room of me? Streat was not to him Bill-stook of the momansbed mig out ust on the bull, out here. I been soms
inick stalling that aid.
“Hon’t me and acrained on .Hw’s don’t you for the roed,” In’s pair.”
“Alough marith him.”
مدل شروع به شناسایی الگو ها در ساختار جملات ساده کرده است. در پایان جملات نقطه می گذارد یا حتی از علامت نقل قول استفاده می کند. تعداد کمی از کلمات معنی دار هستند اما تعداد بیشتری همچنان نا مفهومند.
اما بعد از چندین هزار بار تکرار آموزش، به نظر خوب می رسد :
He went over to the gate of the café. It was like a country bed.
“Do you know it’s been me.”
“Damned us,” Bill said.
“I was dangerous,” I said. “You were she did it and think I would a fine cape you,” I said.
“I can’t look strange in the cab.”
“You know I was this is though,” Brett said.
“It’s a fights no matter?”
“It makes to do it.”
“You make it?”
“Sit down,” I said. “I wish I wasn’t do a little with the man.”
“You found it.”
“I don’t know.”
“You see, I’m sorry of chatches,” Bill said. “You think it’s a friend off back and make you really drunk.”
در این جا، الگوریتم الگوی ساده دیالوگ های کوتاه و مستقیم همینگوی را متوجه شده است. بعضی از جملات حتی منطقی به نظر می رسند.
برای مقایسه نگاهی به بخشی از متن واقعی کتاب داشته باشیم :
There were a few people inside at the bar, and outside, alone, sat Harvey Stone. He had a pile of saucers in front of him, and he needed a shave.
“Sit down,” said Harvey, “I’ve been looking for you.”
“What’s the matter?”
“Nothing. Just looking for you.”
“Been out to the races?”
“No. Not since Sunday.”
“What do you hear from the States?”
“Nothing. Absolutely nothing.”
“What’s the matter?”
حتی با وجود این که تمام تلاش ما حدس زدن یک کاراکتر در هر مرحله بود، الگوریتم ما توانست متن قابل قبولی با فرمت استاندارد تولید کند. به نظر من که خیلی جالب بود!
ما مجبور نیستیم متن را کاملاً از هیچ بسازیم. میتوانیم چند حرف اول را مشخص کنیم و از الگوریتم بخواهیم آن را کامل کند.
برای سرگرمی، میخواهیم برای کتاب جعلی مان جلد تهیه کنیم. برای تعیین اسم نویسنده و اسم جدید کتاب، حروف اولیه Er، He و The S را به عنوان ورودی به الگوریتم میدهیم :

بد نشد!
اما هیجانانگیزترین قسمت ماجرا این است که این الگوریتم میتواند هر الگویی را در دنبالهای از داده ها کشف کند. به سادگی میتوان دستور پختهای مشابه واقعی یا یک سخنرانی جعلی از اوباما تولید کرد. اما چرا خودمان را به زبان انسان محدود کنیم؟ این ایده را میتوان بر روی هر دنباله از انواع داده ها که از الگوی خاصی پیروی میکند امتحان کرد.
ساخت مراحل بازی سوپر ماریو به کمک کامپیوتر
در سال ۲۰۱۵، شرکت نینتندو ابزاری برای سیستم بازی Wii U منتشر کرد که توسط آن میتوان مراحل بازی سوپر ماریو را به صورت دستی طراحی کرد.

این برنامه به شما اجازه میدهد مراحل بازی سوپر ماریو را خودتان طراحی کنید و در اینترنت آپلود کنید تا دیگران از آنها برای بازی استفاده کنند. تمامی عناصر کلاسیک بازی، از جمله دشمن ها، عناصر محیطی و غیره قابل استفاده هستند. مشابه یک مجموعه لگو که در اختیار افراد قرار گرفته تا به هر شکلی که کاربران میخواهند آنها را کنار هم بچینند.
آیا میتوانیم از همان مدلی که برای تولید متن جعلی به سبک همینگوی استفاده کردیم، برای ساختن مراحل بازی سوپر ماریو هم استفاده کنیم؟
ابتدا، لازم است مجموعهای از داده های آموزشی تهیه کنیم. برای این کار از تمامی مراحل بازی اریجینال سوپر ماریو که در سال ۱۹۸۵ منتشر شد استفاده میکنیم :

این بازی ۳۲ مرحله داشت که ۷۰ درصد آن ها محیط تقریباً مشابهی داشتند. پس از همین ها استفاده می کنیم.
برای استخراج طراحی مرحله ها یک نسخه از بازی تهیه کردم و برنامه ای نوشتم که ساختار طراحی مرحله های بازی را از حافظه آن استخراج می کند. این بازی بیشتر از ۳۲ سال قدمت دارد و به اندازه کافی منابع در اینترنت موجود هست که شما را در این کار یاری کند. استخراج داده های مربوط به مراحل بازی از حافظه آن خود یک تمرین برنامه نویسی جالب بود که توصیه می کنم امتحان کنید.
این اولین مرحله از بازی است ( اگر بازی کرده باشید حتماً در خاطرتان هست ) :
اگر دقیقتر نگاه کنیم، می بینیم طراحی هر مرحله از مجموعه ای از قطعات کوچک تر تشکیل شده است.

برای سادگی، هر کدام از این قطعات کوچک را با یک کاراکتر مشخص نمایش میدهیم :
-------------------------- -------------------------- -------------------------- #??#---------------------- -------------------------- -------------------------- -------------------------- -##------=--=----------==- --------==--==--------===- -------===--===------====- ------====--====----=====- =========================-
کاراکتر مربوط به هر قطعه به شرح زیر است:
- ‘-’ یک فضای خالی
- ‘=’ یک بلوک سنگی
- ‘#’ یک آجر شکستنی
- ‘?’ یک آجر حاوی سکه
و به همین ترتیب، به ازای هر قطعه از عناصر بازی یک کاراکتر به آن اختصاص میدهیم.
نمایش متنی مرحله بازی به شکل زیر خواهد بود :

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

اما اگر به صورت ستونی به این فایل نگاه کنیم، الگوها خودشان را نشان میدهند.

پس برای این که الگوریتم ما این الگوها را شناسایی کند، دادههای ورودی را به صورت مجموعهای از ستونها انتخاب میکنیم. درک این که مؤثرترین روش نمایش دادههای ورودی چیست خود یکی از عناصر کلیدی در استفاده از الگوریتمهای یادگیری ماشین میباشد. این کار انتخاب ویژگی ( Feature Selection ) نام دارد.
برای آموزش این مدل، فایل متنی را ۹۰ درجه چرخاندیم.
-----------= -------#---= -------#---= -------?---= -------#---= -----------= -----------= ----------@= ----------@= -----------= -----------= -----------= ---------PP= ---------PP= ----------== ---------=== --------==== -------===== ------====== -----======= ---========= ---=========
آموزش مدل
دقیقاً همان طور که در مدل تولید کننده متن همینگوی دیدیم، یک مدل با آموزش و تکرار ارتقاء می یابد.
بعد از کمی آموزش، مدل ما خروجی بی ربطی تولید کرده است :
-------------------------- LL+<&=------P------------- -------- ---------------------T--#-- ----- -=--=-=------------=-&--T-------------- -------------------- --=------$-=#-=-_ --------------=----=<---- -------b -
البته تا حدی درست فهمیده که ‘-’ها و ‘=’ها زیاد تکرار میشوند. اما الگو را هنوز کشف نکرده است.
بعد از چندین هزار بار تکرار، بالاخره شکل معقولی به خودش میگیرد:
-- -----------= ----------= --------PP= --------PP= -----------= -----------= -----------= -------?---= -----------= -----------=
مدل تقریباً فهمیده است که هر خط باید طول یکسانی داشته باشد. همچنین بعضی از منطقهای موجود در طراحی بازی سوپر ماریو را نیز متوجه شده است، مانند این که لوله ها همیشه دو بلوک عرض و حداقل دو بلوک ارتفاع دارند.
با بارها تکرار بیشتر آموزش، مدل میتواند داده های کاملاً معتبری تولید کند:
--------PP=
--------PP=
----------=
----------=
----------=
---PPP=---=
---PPP=---=
----------=
--------PP= --------PP= ----------= ----------= ----------= ---PPP=---= ---PPP=---= ----------=
اگر خروجی یک مرحله کامل را از الگوریتم بگیریم و آن را به صورت افقی بچرخانیم حاصل به شکل زیر خواهد بود :
این داده ها کاملاً مناسب به نظر میرسند. به چند نکته باید توجه کنیم:
- یک Lakitu ( غولی که روی ابر شناور است ) در ابتدای مرحله در آسمان مشاهده میشود، دقیقاً مانند مراحل واقعی بازی.
- می داند که لوله های شناور روی هوا باید روی تکیه گاهی از بلوک های سنگی قرار بگیرند.
- دشمنان در جایگاه درستی قرار دارند.
- هیچ مانعی سر راه بازیکن وجود ندارد که از پیشروی او جلوگیری کند.
- تقریباً حس یک مرحله واقعی از بازی را میتوان از تصویر زیر دریافت کرد. زیرا براساس مراحل واقعی بازی ساخته شده است.

خودتان این مرحله را بازی کنید!
اگر بازی Super Mario Maker را در اختیار دارید، می توانید این مرحله را دنبال کرده و با کد ۴AC9–۰۰۰۰–۰۱۵۷-F3C3 آن را بیابید.
اسباب بازی در مقابل کاربرد های دنیای واقعی
شبکه عصبی بازگشتی که برای آموزش مدل استفاده کردیم همان نوع الگوریتمی است که توسط شرکت های دنیای واقعی برای حل مسائل دشوار مانند تشخیص کلام و ترجمه زبان استفاده می شود. چیزی که باعث میشود مدل ما به جای یک تکنولوژی پیشرفته بیشتر شبیه یک اسباب بازی به نظر برسد این است که مدل ما از داده های خیلی کمی به دست آمده است. برای مثال مراحل کافی در بازی سوپر ماریو وجود ندارد که مدل ما از آنها برای ایجاد یک مرحله خیلی خوب از آنها استفاده کند.
اگر ما به صدها هزار مدل ساختهشده توسط کاربران نینتندو دسترسی داشتیم، میتوانستیم مدل خارق العاده ای بسازیم. اما نمیتوانیم، چون نینتدو به ما اجازه نمیدهد این داده ها را داشته باشیم. شرکت های بزرگ داده های خود را رایگان به کسی نمیدهند.
هر چه یادگیری ماشین در صنایع بیشتری اهمیت پیدا میکند، تفاوت میان برنامه خوب و برنامه بد در تعداد دادههایی است که برای آموزش مدل استفاده می شود. به همین خاطر است که شرکت هایی مثل گوگل و فیسبوک به طرز حریصانه ای به داده های شما نیاز دارند!
برای مثال، گوگل مدتی پیش TensorFlow را معرفی کرد. نرمافزاری متن باز که ابزارهایی برای کاربردهای یادگیری ماشین در مقیاس بزرگ فراهم میکند. این که گوگل چنین تکنولوژی مهمی را به رایگان در اختیار عموم قرار داد، اتفاق بسیار مهمی بود. این ابزار همان چیزی است که سرویس ترجمه گوگل از آن استفاده میکند.
اما بدون داشتن گنجینه عظیم داده های گوگل در هر زبان، کسی نمیتواند رقیبی برای Google Translate بسازد. داده همان چیزی است که برتری گوگل را رقم زده است. دفعه بعدی که به تاریخچه مکانی Google Maps نگاه میکنید به این قضیه فکر کنید و خواهید دید که هر جایی که رفتهاید در دیتابیس گوگل ذخیره شده است.
در نهایت به یاد داشته باشید که در یادگیری ماشین، هیچ گاه تنها یک راه برای حل یک مسئله وجود ندارد. همچنین هیچ گاه نمیتوان یک الگوریتم را به عنوان بهترین راه حل انتخاب کرد. بسته به نوع مسئله، الگوریتم ها میتوانند عملکرد متفاوتی داشته باشند. بی نهایت راه پیش روی شما است که چگونه داده ها را پیش پردازش و از چه الگوریتم هایی برای یادگیری استفاده کنید. حتی گاهاً ترکیب چند روش مختلف ممکن است نتایج بهتری به همراه داشته باشد.
بیشتر بخوانید :
- قوی ترین هوش مصنوعی دنیا
- برنامه ای که سن دقیق را نشان می دهد
- شباهت چهره گوگل
- تست مدل مو آنلاین
- نرم افزار تشخیص زیبایی چهره