تو این پست میخوایم یه شبکه ی عصبی train کنیم. هدف اصلی اینه که با مقدمات کد زدن شبکه های عصبی آشنا بشیم و یه دید کلی نسبت بهش داشته باشیم. در ادامه خیلی بیشتر وارد جزئیات میشیم.
دیتاستی که قراره باهاش کار کنیم یه دیتاست خیلی معروفه به نام MNIST. این دیتاست در کل 70.000 تا عکس 28 پیکسل در 28 پیکسل داره که تو هر کدوم از عکسا یکی از رقم های 0 تا 9 نوشته شده. تسکی که برای این دیتاست تعریف شده اینه که با ورودی گرفتن عکس، عددی که توی اون عکس نوشته شده رو بگیم.
این دیتاست خیلی دستاست معروفیه و خیلی جا ها به عنوان benchmark ازش استفاده شده. البته به خاطر اینکه روش های deep خیلی پیشرفت کردن، دیتاست ساده ای حساب میشه و دیگه از این دیتاست خیلی استفاده نمیشه.
برای کار با شبکه های عصبی، کتابخونه های زیادی وجود داره. دو تا از معروف ترین ها tensorflow و pytorch هستند. هر دوی این کتابخونه های کاربرد های زیادی تو research و صنعت دارن اما pytorch جدیدا خیلی بیشتر پیشرفت داشته و بیشتر داره استفاده میشه. به همین دلیل ما هم برای این پست و پست های بعدی از همین کتابخونه استفاده میکنیم.
برای این آموزش نیازی نیست چیزی روی سیستمتون نصب کنید. ولی اگر بخواید pytorch رو نصب کنید هم خیلی کار سختی نیست: تنها کاری که باید انجام بدید اینه که سایتش رو باز کنید و تو بخش installation، دستوری که مینویسه رو copy و توی ترمینالتون paste کنید. (تنها چیزی که باید بهش دقت کنید اینه که اگر میخواید با pip نصب کنید، گزینه ی pip و اگر میخواید با anaconda نصب کنید، گزینه ی conda رو بزنید).
اگر قبلا با پایتون کار کرده باشید میدونید که کلا نصب کتابخونه تو پایتون سادس. این قضیه درسته ولی برای کتابخونه های deep learning یکم داستان تفاوته چون اونا میتونن از GPU استفاده کنن و ممکنه نیاز باشه dependency های دیگه ای رو هم نصب کنید که نصب اون ها (به خصوص برای tensorflow) ممکنه کار راحتی نباشه.
تو مرحله ی اول سایت گوگل colab رو باز کنید. این محیط به شما این امکان رو میده که از GPU ها و TPU هایی که گوگل در اختیارتون میذاره به صورت رایگان استفاده کنید. گرچه همیشه و برای همه کار نمیشه ازش استفاده کرد اما تا حد خوبی میتونه کار ها رو برای ما ساده تر کنه. (این محیط، Jupyter notebook ای هست که روی سرور های گوگل run میشه.)
تو مرحله ی اول سایت رو باز کنید و روز new notebook کلیک کنید.
هر notebook از یک سری cell ساخته شده که یک سری از اونها برای code و بقیه برای text هستند. میتونید تو cell های text، از HTML و Markdown هم استفاده کنید.
تو اولین سلول کد های مربوط به import کردن کتابخونه هایی که نیاز داریم رو مینویسیم:
بعد از اینکه این دستورات ر نوشتیم باید روی [ ] کلید کنیم که این cell اجرا بشه. (وقتی روی اون علامت برید، باید آیکنش عوض بشه و جاش فلش بیاد.) به جز کلید کردن روی آیکن، میتونید با کلید های Shift+Enter هم cell رو اجرا کنید.
خط اول این کد، کتخونه ی pytoch رو import میکنه. این کتابخونه، همون کتابخونه ایه که قراره شبکه عصبی رو بسازه و train کنه. همین طور داده ها رو هم با همین کتابخونه load میکنیم.
دو تا خط بعدی هم یک سری از ماژول هایی که به اونها نیاز داریم رو به صورت nn و F مخفف میکنه که دیگه نیاز نباشه هر دفعه بنویسیم torch.nn یا torch.nn.functional و به جاش از nn و F استفاده کنیم. خط چهارم هم به همین تریب، torch.optim رو به optim مخفف میکنه.
خط بعدی، کتابخونه ی torchvision رو import میکنه، این کتابخونه برای load کردن دیتاست به ما کمک میکنه.
خط بعدی هم یکی از ماژول های torchvision رو مخفف میکنه.
خط بعدی کتابخونه ی matplotlib رو import میکنه که برای رسم نمودار استفاده میشه و خط آخر هم accuracy_score رو از sklearn به کد اضافه میکنه. (برای محاسبه ی دقت مدل به درد میخوره).
تو این مرحله باید دیتاستی که میخوایم باهاش کار کنیم رو load کنیم. برای این کار اول باید خود داده ها رو لود کنیم و بعد با استفاده از یک کلاس دیگه، داده ها رو برای شبکه عصبی آماده کنیم.
برای مرحله ی اول باید از torchvision.dataset، دیتاست MNIST رو load کنیم. برای این کار باید این دستور رو بنویسیم:
این دستور داده های MNIST رو برای ما load میکنه. البته نه دقیقا این دستور! در واقع باید یک سری پاراکتر دیگه هم بهش پاس بدیم.
اول از همه، این دیتاست خودش به دو بخش train و test تقسیم شده. بخش train شامل 60.000 تا عکسه که برای train کردن مدل استفاده میشه و بخش test شامل 10.000 تا عکس که برای تست کردن، دقت مدل train شده استفاده میشه.
دوم، یه object از نوع Transform (در واقع از نوع torchvision.transforms.Transform) بهش پاس بدیم، کار این object اینه که وقتی داده ها میخوان load بشن، روی اونها یک سری محاسبه انجام بده که بتونن تو مراحل بعدی قابل استفاده باشه. مثلا اونا رو به tensor های pytorch تبدیل کنه (این tensor ها میتونن روی GPU هم allocate بشن، پس مهمه که به جای مثلا numpy ndarray، داده ها از اون tensor های pytorch باشن). یا مثلا داده ها رو normalize کنه. (هنوز درباره ی اینکه normalization چی هست صحبت نکردیم، برای این ادامه ی این پست صرفا بدونید عدد رو تقسیم بر یک مقداری میکنه که بیان تو رنج 0 تا 1، توضیحات دقیق ترش رو تو یه پست دیگه مینویسم)
اول از همه بیایم و transform رو تعریف کنیم.
چون میخوایم داده ها اول به tensor تبدیل بشن و بعد normalize بشن باید از transform ای استفاده کنیم که خودش شامل چند تا transform باشه. برای ساختن همچین چیزی میتونیم از transforms.Conpose استفاده کنیم. این کلاس خودش یه list میگیره که از آیتمش یه Transformهست و اونا رو به ترتیب روی داده ها اجرا میکنه.
برای تبدیل داده های به Tensor میتونیم از transforms.ToTensor و برای Normalize کردن اونها از transforms.Normalize استفاده کنیم.
دستور نهایی برای ساختن transform به این صورت میشه:
حالا باید این object رو به torchvision.datasets.MNIST پاس بدیم.
کار بعدی هم که باید انجام بدیم اینه که داده های train و test جداگانه load کنیم. در نهایت کدش اینجوری میشه:
در نهایت باید این داده ها رو آماده کنیم تا شبکه ی عصبی اونها رو پردازش کنه. برای این کار باید از torch.utils.data.Dataloader استفاده کنیم. Dataloader، یه کلاسه که داده ها رو آماده میکنه برای پردازش، مهم ترین کاری ک انجام میده اینه که داده ها رو به صورت batch در میاره.
شبکه های عصبی وقتی میخوان داده ها رو پردازش کنن، یک دونه ورودی نمیگیرن. مثلا تو این مثالی که داریم، به جای اینکه هر دفعه 1 عکس بگیره، میاد 8 تا عکس میگیره و همزمان هر 8 تا پردازش میکنه. به این تعداد (8) میگن batch size. این عدد میتونه هر مقداری باشه ولی معولا اون رو توان 2 انتخاب میکنن (2 4 8 16 32 ...).
برای ساختن dataloader باید از این دستور استفاده کنیم:
خب تا اینجا ی کار داده ها رو لود کردیم.
تو پست بعدی شبکه ی عصبی رو میسازیم و loss function و optimizer اون رو مشخص میکنیم و تو پست آخر هم خود train رو پیاده سازی میکنیم.