سلام. وقت شما بخیر. امیر پورمندم و این قسمت ۱۶ ایستگاه هوش مصنوعیه و صدای من رو از یزد میشنوید.
تو این قسمت از پادکست میخوام به یک سؤال بپردازم. سؤالی که از دوره ارشد برام وجود داشت و بهش فکر میکردم.
بخشهای مهم یک سیستم یادگیری عمیق چه چیزهایی هستند؟ یعنی اگر من یک مقاله یا روش جدید هوشمصنوعی رو خوندم، چه بخشهایی وجود دارند که معمولاً مهمترن؟ کدوم بخشها هستند که میشه ازشون ایده گرفت؟
به یک معنای دیگه اگر بخوام بگم، چطوری میشه به یادگیری عمیق به عنوان یک سیستم نگاه کرد؟ این سیستم چه اجزایی داره و هر جزء چگونه با بقیه بخشها ارتباط برقرار میکنه؟ هدف این سیستم چیه و چطوری خودش رو به این هدف نزدیک میکنه؟ چطوری میفهمیم که به هدف نزدیک شده یا نه؟
چطوری میتونیم با نگاهی متفاوت توضیح بدیم که یادگیری عمیق چیه؟ و فلان روش جدید یادگیری عمیق چه دستاوردی در چه حوزهای داشته؟ یا این که فلان روش جدید کجای این سیستم قرار میگیره و کجا به درد خورده؟
اینها سؤالاتی هست که امیدوارم بتونم بهشون پاسخ بدم.
شنیدن اپیزود
همه اپیزودهای این پادکست تو کانال کست باکس منتشر میشه و البته میتونید از جاهای دیگه هم بشنوید.اینجا هم میتونید فایل صوتی این قسمت رو گوش بدید:
مقدمه
تو دوره ارشد مثل همه بچههای دیگه، زیاد مقاله میخوندم. خیلی وقتها نمیفهمیدم چی میگن. انگار یه ادبیات خاصی دارند و لقمه رو ۱۰ بار، دور سر میچرخونند. بعد که میرفتم با دوستان صحبت میکردم، میدیدم که اکثر مقالات حول یک ایده کلیدی نوشته میشن؛ یعنی اگر بخوایم خلاصه کنیم، کل کار طرف رو میشه تو یک پاراگراف یا شکل خلاصه کرد.
بقیه مقاله جزئیات پیادهسازی و چیزهای غیرمهم دیگه بود. بعد برام سؤال پیش اومده بود که اصلاً اجزاء یک سیستم یادگیری عمیق چیه؟ یعنی من یک مقاله رو میخونم چه سؤالاتی رو از خودم بپرسم که متوجه بشم فهمیدم یا نه؟ یا اصلاً بصورت کلیتر، اگر یادگیری عمیق رو بصورت یک سیستم در نظر بگیریم، این سیستم چه بخشها و بازیگرانی داره؟ هر جزء تو این سیستم چه نقشی داره؟ چطوری میتونیم با دیدن اجزاء جدید این سیستم، دید کلی رو از دست ندیم؟
به نظرم اهمیت سؤال درست خیلی وقتها از دونستن جواب مهمتره. تو هر کاری آدم اگر بلد باشه سؤال درست بپرسه، بهتر میتونه متوجه بشه. تعاملی هم میشه دیگه. شما الان یک مقاله دیپ لرنینگ رو بردارید بخواید بخونید، اگر سؤال برای پرسیدن داشته باشید خیلی راحتتر میتونید ارتباط بگیرید.
به نظرم میرسه خیلی از سیستمهای یادگیری عمیق رو میشه در پنج بخش بهشون نگاه کرد.
تعریف مسئله و ورودی و خروجی (Problem Definition)
اولین سؤال اینه که چه مسئلهای رو دارند حل میکنند؟ ورودی و خروجی این سیستم چیه؟
یکی از دوستان من تز ارشدش، تشخیص توپ فوتبال بود; یعنی توپ رو تو فیلم بتونه تشخیص بده. خب اینجا ورودی مشخصه. تکتک فریمهای ورودی (تصویرها) رو به یک مدل میدیم و انتظار داریم که بتونیم توپ رو تشخیص بدیم. پس خروجی رو هم میشه به شکل یه کادر مستطیلی دور توپ تعریف کرد. کادر مستطیلی رو هم میشه با دو تا نقطه دو بعدی نشون داد. نقطه بالا سمت چپ و نقطه پایین سمت راست.
یا میشه مرکز توپ و طول و عرض مستطیل رو خروجی داد. هر کسی ممکنه یه جوری برای خودش تعریف کنه.
حالا اینجا فرض کردیم، توپ یه دونه بیشتر نداریم. اگر تو هر لحظه ۲ تا توپ داشتیم، خروجی عوض میشد.
یا مثلاً در نظر بگیرید مسئله «ردیابی اشیاء» یا Object Tracking باشه؛ یعنی بخوایم علاوه بر تشخیص محل توپ، تشخیص بدیم که این «توپ» که در ثانیه ۱۰ ام میبینم همون توپی هست که در ثانیه اول دیدم و یه توپ دیگه نیست.
حالا تو مدت زمان زیادی که این فیلد بوجود اومده، آدمها به مسائل مختلف بسته به محدودیتها و ورودی خروجیهای مورد انتظارشون، اسمهای مختلف دادند. ما فقط اسمش رو بفهمیم، میتونیم دقیقاً تشخیص بدیم که مسئله چیه و همین اسمگذاری هم با این که کار سادهای به نظر میاد اما یکی از چالشها تو صنعت هست. طرف کلی جلسه میره تا بتونند تشخیص بدن که مسئله چی هست اصلاً.
بعد از این که مسئله رو تشخیص دادیم، حالا میتونیم سراغ راهحل بریم. بعد هم راهحل طرف رو ارزیابی کنیم. اینجاست که تازه میشه گفت حدوداً فهمیدیم چی خوندیم!
معماری مدل (Model Architecture)
تو اینجا تازه میرسیم سراغ راهحل طرف برای مسئله.
من نگاهم به یادگیری عمیق، یه ترکیب تو در تو از توابع مختلفه. همین. یعنی در کلیترین حالت، به ازای هر ورودی یک خروجی میخوایم. یک تابع از ورودی به خروجی. حالا این تابعه میتونه خیلی پیچیده باشه یا میتونه خیلی ساده باشه.
مثلاً تابع در سادهترین حالت ممکن میشه یک تابع خطی. حتی میتونه ۱۰۰ تا تابع تو در تو باشه. به مجموعه توابعی که از ورودی به خروجی میرسند، میگن «معماری مدل».
اصلاً بخش بزرگی از دورههای یادگیری عمیق و یادگیری ماشین به مطالعه خواص این توابع برمیگرده. آدمها نشستن کلی بررسی کردند و دیدند که فلان تابع ریاضی، برای فلان نوع داده بهتر جواب میده. مثلاً میگن تابع کانولوشن برای تصویر خیلی خوب جواب میده. تابع RNN برای دادههایی که تابع زمان باشند، خوب جواب میدن.
کل بازیای که ۱۰ ۱۵ ساله داریم همینه دیگه. یک سری دانشمند میرن منابع صرف میکنند و یک تابع جدید ابداع میکنند و میگن که تابع من از تابع بقیه بهتر روی فلان مسئله جواب میده.
بخشی از پیچیدگی این بخش هم از ابعاد بالای ورودی و خروجی میاد. اگر یه تصویر سیاه سفید 720p در نظر بگیرید، میشه یه بردار ۹۰۰ هزار بعدی (۱۲۸۰ ضربدر ۷۲۰). اینجا دیگه ریاضیات دبیرستان به کار نمیاد! ریاضیات تو ابعاد بالا به کار میاد که اسمش رو گذاشتند جبر خطی. اینجا دیگه حتی اگر تابع خطی هم داشته باشیم، با ماتریس باید سر و کله بزنیم.
ولی کلیت همینه که گفتم. سؤالشون اینه که چه ترکیبی از توابع رو پشت سر هم ردیف کنیم تا از ورودی به خروجی برسیم. مثلاً دانشمندان میرن کلی آزمایش انجام میدن، میگن که اگر بعد از فلان تابع، فلان تابع دیگه بگذاریم، نتایج بهتر میشه.
اینجا هم داروین با ایده تکامل به کمک میاد. و عملاً تو طول زمان یک سری مدلها برای یک سری مسائل بهتر عمل میکنند و معروف میشن. بقیه هم به فراموشی سپرده میشن.
یکی از دوستانم این بازی رو به ساخت پازل تشبیه میکنه. پازلی که توش توابع رو پشت سر هم ردیف میکنی. مثلاً یکی از تکههای پازل که چندسالی هست همه فیلد درگیرش شدن، تابعی به نام Attention هست.
یه مقالهای (+) سال ۲۰۱۷ اومد که این تکه جدید بازی رو معرفی کرد و مدلهای زبانی بزرگ هم، نطفهشون از همون جا اومد. از اون به بعد اگر دقیق نگاه کنید، واقعاً تکه جدیدی برای این پازل نیومده. یعنی از نظر معماری کار خاصی انجام نشده. فقط تا قبلش مثلاً ۱۰۰ تا تابع رو میگذاشتند پشت سر هم. بعد از این تونستند ۱۰۰۰ تا تابع رو بگذارند پشت سر هم و خروجی بدست بیارند.
حالا تو ادبیات یادگیری عمیق اسمش رو شیک کردند. میگن مدل یادگیری عمیق ۱۰۰ لایه. ولی چیز خاصی نیست. ۱۰۰ تا تابعه که پشت سر هم گذاشتیم. از نظر فلسفی هم اگر نگاه کنیم، خیلی کسی ایدهای نداره که داریم چیکار میکنیم. یک سری تابع داریم پشت سر هم میگذاریم و به طرز عجیبی خروجیهای خیلی جالب میگیریم.
هدف یا تابع خطا (Loss Function)
عملاً تو این بخش برای مدل، هدفگذاری میکنیم.
فرض کنید یک تابعی کاملاً تصادفی دارید. به ازای هر ورودی یک خروجی تصادفی میده. ما باید برای این سیستم، هدف تعریف کنیم که بتونه بر اساسش عمل کنه. تو ادبیات یادگیری ماشین به مدل میگن که هدفت اینه که خطات صفر بشه. بعد هر بار که از مدل خروجی میگیرند، میگن خروجیات با خروجی مدنظر ما فلان اندازه فاصله داره.
مثلاً اگر هدف سیستم فروش این باشه که ۲ میلیارد بفروشه و ۱ میلیارد بیشتر نتونه بفروشه، ۱ میلیارد با هدف اختلاف داره. حالا به طرز مشابه یک سیستم هوشمند که قراره قیمت خونه رو تخمین بزنه، اگر بیشتر یا کمتر تخمین بزنه، اختلاف داره. هدف اینه که این اختلاف به صفر برسه.
پس نیاز به تابعی داریم که بتونیم «اندازه انحراف از هدف» رو تشخیص بدیم. شاید به نظر ساده بیاد. مثلاً همین قیمت خونه رو در نظر بگیرید. یکی ممکنه بگه که تابع نمیخواد که. قیمت واقعی رو از قسمت تشخیص داده شده، کم کنید و خلاص. اما به این سادگی هم نیست!
این فقط یکی از توابع ممکنه. دقت کنید که با این تابع داریم به سیستم هدف میدیم. پس اگر با دقت تعریف نشه، تهش با خروجی مطلوب ما فاصله میگیره. مثلاً ما ممکنه تو ذهنمون باشه که اگر کمی بیشتر تخمین بزنی بهتر از اینه که کمی کمتر تخمین بزنی!
اینجا میتونیم تابع متفاوتی تعریف کنیم. مدل x تومن بیشتر تخمین بزنه، بهش میگم اختلافت با هدف x هست. اگر x کمتر تخمین بزنه، بهش میگم اختلافت 5x هست. تابع دست خودمونه. هر جوری هدفگذاری کنیم عین همون انجام میده. اینطوری میتونم به کلاسهای مختلف وزنهای مختلف بدم.
مثلاً تو پزشکی ممکنه بگن که اگر بیمار سرطانی باشه و تشخیص داده نشه، خیلی بدتر از این هست که بیمار سرطانی نباشه و شما به اشتباه بگی هست! بالاخره یکی از این دو سمت میچربه. و مهم نیست که کدوم. مهم اینه که ما باید این رو هم داخل هدفگذاری مدل تعریف کنیم.
پس باید به ازای هر مسئله بشینیم فکر کنیم که چه خروجیای از مدل انتظار داریم و این خروجی رو چگونه میتونیم بصورت کاملاً ریاضی برای مدل تعریف کنیم. مثلاً همون مثال تشخیص توپ رو هم در نظر بگیرید. بالاخره مدل خروجیاش دو تا نقطه است دیگه. نقطه بالا سمت چپ و نقطه پایین سمت راست که یک مستطیل رو تشکیل بده.
این که خروجیای که مدل داده چقدر با خروجی مدنظر ما تفاوت داره، میشه همون تابع لاس.
روش بهینه سازی (Optimization Algorithm)
اوکی! تا اینجا گفتیم که یک سری تابع میگذاریم پشت سر هم و برای سیستم هدف تعریف میکنیم و این اباطیل.
حالا سؤال اینه که چطوری به هدف برسیم؟
یعنی فرض کنید سادهترین تابع ممکن رو دارید. یک تابع خطی. یک تابع خطی به فرم Ax+b دو تا مجهول داره. به این مجهولات میگن پارامترهای مدل. حالا سؤال اینه که پارامترهای مدل رو چطوری تعیین کنیم که به هدف برسیم؟
جوابش میشه همون فرآیند آموزش مدل! چیزی که بهش میگن Training.
میگن که تکتک ورودیها رو به اون تابع بده و خروجی رو ازش بگیر. حالا اختلاف خروجی رو با تابع هدف بسنج. بعد یه الگوریتمی هست که میاد پارامترها رو جوری تغییر میده که به اون هدف نزدیکتر بشی. خلاص.
حالا برای تکتک ورودیها این کار رو انجام بده تا روی همشون به هدف نزدیک بشی! به کل این فرآیند میگن آموزش مدل. یعنی تک تک ورودیها رو به مدل میدیم و پارامترهای مدل رو جوری تغییر میدیم که به هدف نزدیک و نزدیکتر بشیم.
وقتی به اندازه کافی نزدیک شدیم آموزش مدل رو تموم میکنیم و حالا مدل ما میتونه با کمترین خطا، به هر ورودی یک خروجی مرتبط نسبت بده.
اما اینجا چیزی راجع به اون روش نگفتم. به نظرم میشه تو یه اپیزود جداگانه راجع بهش صحبت کرد که چگونه میشه پارامترهای مدل رو در جهت مدل تغییر داد. خیلی خلاصه بخوام اشاره کنم، برای این کار از مشتق و مشتق زنجیرهای و این چیزها استفاده میکنند.
حالا یک سری روش استاندارد برای این کار وجود داره. SGD و ADAM و اینا.
ولی وارد بحثش نمیخوام بشم. دوست دارم خیلی کلیتر به قضیه نگاه کنیم. خیلی کلی بخوایم نگاه کنیم، تا حالا چند تا کار انجام دادیم:
- اول مسئله و ورودی خروجیمون رو تعریف کردیم.
- بعد گفتیم یک مجموعهای از توابع برای رسیدن از ورودی به خروجی میسازیم.
- بعد هم یک هدف برای سیستم تعریف میکنیم و سعی میکنیم اختلاف از هدف صفر بشه.
- و بعد هم یک روش برای رسیدن به اون هدف، به سیستم میدیم.
الان سیستم ما به هدفش رسیده. تنها گام اینه که ارزیابی کنیم در عمل چقدر این سیستم به درد میخوره؟
نحوه ارزیابی (Model Evaluation)
این مورد یه کم عجیب به نظر میرسه. ما برای سیستم هدف تعریف کردیم و سیستم با دادههای ورودی آموزش دیده و به هدف بسیار نزدیک شده. اما اینها برای ما مهم نیست.
چیزی که در نهایت برامون مهمه اینه که مدل چقدر تو ارزیابیها میتونه خوب عمل کنه.
تو زندگی خودمون هم همینه. ما یک سری هدف میگذاریم و یک سری معیار متفاوت میگذاریم که متوجه بشیم که چقدر به اون حرف تونستیم برسیم. مثلاً هدف سلامتی ممکنه باشه. ولی ارزیابی سلامتی رو از جنبههای مختلف انجام میدیم؛ آزمایش خون میدیم. فشار خون میگیریم. BMI حساب میکنیم و کلی چیز دیگه.
مثلاً مدل تشخیص سرطان داریم. چیزی که در نهایت برامون مهمه این مدل چند درصد از سرطانیها رو تونسته تشخیص بده؟ چند درصد از کسانی که سرطان نداشتند رو سرطان تشخیص داده؟ چند درصد از کسانی که سرطان داشتند رو نتونسته تشخیص بده؟
پس اینطوری چند تا معیار ارزیابی تعریف میکنیم و مدل رو با معیارهای ارزیابی میسنجیم و راجع بهش قضاوت میکنیم. دقت کنید ما داخل مدل رو چندان نمیتونیم بفهمیم که چیه. درسته که خودمون درستش کردیم؛ اما شما در نظر بگیرید ۱۰۰ تا تابع تو در توی سینوس و خط و فلان و بهمان وسطش وجود داره و خیلی نمیشه فهمید مدل داره چیکار میکنه و چطوری تصمیم میگیره.
اما میشه خروجیاش رو دید و ارزیابیاش کرد و این کار تو این بخش انجام میشه.
حالا طبق چیزهایی که من دیدم اکثر مقالات و آموزشهای یادگیری ماشین و یادگیری عمیق روی یک یا چند تا از اینها تمرکز میکنند. یکی میاد میگه که روش ارزیابی من بهتر از روشهای ارزیابی قبلی هست. یکی میاد میگه که معماری من بهتر از معماریهای قبلی هست.
و همینطور الیآخر.
جمعبندی
اگر بخوام خلاصه کنم تو این قسمت راجع به اهمیت پنج تا سؤال حرف زدیم. این که چطوری مسئلهمون رو تعریف کنیم. معماری مدل چیه؟ و هدف مدل چیه و چطوری به اون هدف نزدیک بشیم؟ بعدش هم چطوری مدل رو ارزیابی کنیم که داره خوب عمل میکنه یا نه.
این دستهبندیای هست که من خودم موقع دیدن هر روش «جدید» یا ناآشنا تو یادگیری عمیق بهش توجه میکنم و امیدوارم که دستهبندی مفیدی باشه.
تا قسمت بعد خدانگهدار.
پینوشت: یک موضوع دیگه هم بود که نتونستم تو قصهای که تعریف کردم جاش بدم و اون نحوه بدست آوردن خروجی هست. این که برای تبدیل ورودی به خروجی چه پیشپردازشها و پسپردازشهایی رخ داده (Pre-processing, post-processing and inference techniques).