پست وبلاگ

آموزش Caffe بخش پنجم :مثال عملی

بسم الله الرحمن الرحیم

در این بخش ما سعی میکنیم تا یک شبکه (شبکه MNIST) را از ابتدا تا انتها ایجاد کرده و ببینیم چگونه میتوان با استفاده از Caffe این کار را انجام داد.
مواردی مثل آماده سازی داده ها توسط خود ما برای داده های جدید(یعنی چطوری یه دیتابیس از تصاویر خودمون بسازیم و…) انشاالله در یک پست دیگه توضیح میدم.

آماده سازی داده ها :

قبل از اینکه به سراغ تعریف لایه ها برویم , برای تسریع فرآیند آموزش, ما داده های خود را به فرمت lmdb تبدیل میکنیم . برای اینکار کافیست دستورات زیر را اجرا کنید :

دانلود و دریافت دیتاست MNIST در لینوکس (در ورژن ویندوز اون هم فقط پسوند عوض میشه. البته ورژن رسمی Caffe مثالها به ویندوز رو نداره اما من قبلا تبدیل کردم و میتونید از برنچ من اینجا معادلها رو بگیرید)

فایل های فوق را میتوان از سورس کد Caffe با آدرس های داده شده یافته و اجرا نمود.

 

تعریف Data Layer

در اینجا ما سعی میکنیم تا داده ها را از دیتابیس imdb که در مرحله قبل آن را ایجاد کردیم بخوانیم. عمل خواندن را در لایه داده انجام به اینصورت انجام میشود:

در لایه بالا, اسم این لایه mnist بوده و از نوع Data میباشد. ما در بخش data_param , اطلاعات مورد نیاز این لایه را وارد میکنیم .

پارامتر :Source : این پارامتر مسیر پوشه (دایرکتوری ) حاوی داده هایی که باید خوانده شوند را مشخص میکند.

پارامتر backend : مشخص کننده نوع دیتابیسی است که ما از آن اطلاعات خود را میخوانیم

پارامتر batch_size : عددی که در این بخش مشخص میکنیم نشانگر ظرفیت دسته هاست. به این معنا که تصاویر در دسته های ۶۴ تایی پردازش میشوند.

پارامتر scale : این پارامتر هم مقادیر ورودی را به اعدادی در رنج [۰,۱) تبدیل میکند. چرا از ۰٫۰۰۳۹۰۶۲۵ استفاده کردیم ؟ این عدد از تقسیم عدد ۱ بر ۲۵۵ بدست می آید. (چون تصاویر mnist تصاویر سیاه و سفید هستند مقادیر پیکسلی آنها مقداری بین ۰ تا ۲۵۵ دارد. بنابر این با تقسیم ۱ بر ۲۵۵ عددی بدست می آید که در صورت ضرب هر مقدار در آن مقدار متناظر آن در گستره [۰,۱) بدست می آید. )

و در انتها نیز پارامتر top مشخص میکند که خروجی این لایه دو blob با نامهای data و  label هستند.

تعریف لایه Convolution

حالا به تعریف لایه کانولوشن میپردازیم که بعد از لایه دیتا قرار میگیرد.

در اینجا ما از ذکر پارامترهایی که در بخش قبل توضیح داده شدند صرفنظر میکنیم و فقط به توضیح پارامترهای جدید میپردازیم .

این لایه blob داده را از لایه داده دریافت میکند و blob conv1 را تولید میکند. این لایه ۲۰ کانال (فیلتر) تولید کرده و اندازه کرنل آن برابر با ۵ است که با stride =1 بر روی ورودی اعمال میشود.

filler ها بماکمک میکنند تا بتوانیم مقادیر وزنها و بایاس ها را بصورت تصادفی مقداردهی اولیه کنیم. برای weight filler ما از الگوریتم Xavier استفاده میکنیم که بصورت خودکار مقیاس مقداردهی اولیه را مبتنی بر تعداد نورون های ورودی و خروجی مشخص میکند. برای bias filler هم  ما خیلی ساده آنرا بعنوان یک ثابت (constant) با مقدار filling پیشفرض ۰ مقداردهی اولیه میکنیم.

lr_mult ها هم تنظیمات مربوط به نرخ یادگیری (learning rate) هستند که برای پارامترهای قابل یادگیری لایه مورد استفاده قرار میگیرند. در اینجا, ما نرخ یادگیری وزن را برابر نرخ یادگیری ارائه شده توسط solver در زمان اجرا قرار میدهیم و نرخ یادگیری بایاس را هم دوبرابر آن تنظیم میکنیم . این کار معمولا باعث نرخ همگرایی بهتر میشود.

تعریف لایه Pooling

تعریف این لایه هم بصورت زیر است

در اینجا میبینیم که ما عملیات max pooling را با تنظیم پارامتر pool:Max انجام خواهیم داد و اندازه کرنل هم برابر با ۲*۲ بوده که با stride =2 بر روی ورودی اعمال میشود. (با این stride هیچ اشتراکی (overlapping بین پیکسل های همسایه ناحیه های pooling وجود نخواهد داشت)/

به همین شکل , ما لایه های کانولوشن و pooling بعدی را میتوانیم طراحی کنیم .

تعریف لایه تماما متصل

این لایه هم همانند لایه های قبلی بصورت زیر تعریف میشود :

تعریف بالا یک لایه تماما متصل را مشخص میکند که در Caffe به لایه InnerProduct معروف است. این لایه ۵۰۰ خروجی داشته و مابقی پارامترها نیز مشابه لایه های قبلی است که توضیح انها داده شد.

تعریف لایه ReLU

یک لایه ReLU بصورت زیر تعریف میشود

از آنجایی که ReLU یک عملیات مولفه محور است (element-wise) , بنابر این ما میتوانیم عملیات را بصورت درجا انجام داده تا در مصرف حافظه صرفه جویی کنیم . این کار با تعریف یک نام برای blob های بالایی و پایینی (همانطور که در تعریف بالا انجام شده است ) قابل انجام است. لطفا دقت کنید که شما نمیتوانید از نامهای یکسان برای blob ها در سایر لایه ها استفاده کنید و این کار مختص این لایه است.

بعد از لایه ReLU ما یک لایه تماما متصل دیگر تعریف میکنیم:

و نهایتا لایه Loss را بصورت زیر تعریف میکنیم

لایه softmax_loss هم softmax و هم multinomial logistic loss را (که نسبت به مورد اول از لحاظ زمانی و پایداری عددی (numerical stability) بهتر است) را پشتیبانی میکند. این لایه دو blob دریافت کرده که اولی پیشبینی و دومی برچسب ای است که توسط لایه داده تولید میشود است. این لایه هیچ خروجی ای تولید نمیکند . تمام کاری که انجام میدهد محاسبه مقدار تابع خطا , و گزارش آن در زمان شروع عملیات backpropagation و شروع بدست اوردن گرادیانت با توجه به ip2 میباشد.

در انتها هم معماری فوق الذکر بشکل زیر خواهد بود

Mnist-model-deeplearning.ir

نکات اضافی

در زمان تعریف مدل یک شبکه, هیچ الزامی برای خطی بودن معماری همانند شکل زیر نیست. بعبارت دیگر میتوان معماری غیرخطی (البته بدون دور) هم داشت :

image005

در تعاریف لایه ها میتوان با استفاده از قوانینی مشخص کرد که آیا لایه ای در زمان خاصی فعال باشد یا خیر.

بعنوان مثال, نمونه زیر را در نظر بگیرید :

در نمونه بالا, چیزی که مشاهده میکنید یک قانون است که حضور یک لایه در یک شبکه را بر اساس وضعیت فعلی شبکه کنترل میکند. شما میتوانید به مراجعه به CAFFE_ROOT/src/caffe/proto/caffe.proto$  اطلاعات بیشتری در باره قوانین لایه ها و طرح های مربوط به مدلها بدست بیاورید.

در مثال بالا , این لایه تنها در فاز training (آموزش) به شبکه اضافه خواهد شد. اگر ما TRAIN را با TEST عوض کنیم, این لایه تنها در فاز test مورد استفاده قرار خواهد گرفت. بصورت پیشفرض , یعنی بدون استفاده از قوانین لایه ها, یک لایه همیشه در شبکه حضور خواهد داشت و مورد استفاده قرار خواهد گرفت. بخاطر همین مسئله است که  lenet_train_test.prototxt دارای ۲ لایه DATA است (که دارای batch_size های متفاوتی هستند) .یکی از آنها برای فاز training و دیگری برای فاز testing مورد استفاده قرار میگیرد. همچنین اگه به lenet_solver.prototxt نگاه کنید میبینید که یک لایه Accuracy هم وجود دارد که تنها در فاز TEST به منظور گزارش دقت مدل در هر ۱۰۰ تکرار فعال میشود .

نهایتا در زیر مدل کامل MNIST را مشاهده میکنید :

نکته :

الان بجای layers از layer استفاده میشه.(هرچند کد بالا هم براحتی اجرا میشه اما دیگه layers نوشته نمیشه . نوع لایه ها هم دیگه با حروف بزرگ نوشته نمیشه بصورت camel case نوشته میشه یعنی POOLING شده Pooling و CONVOLUTION شده Convolution.)

تعریف MNIST Solver

test_iter مشخص میکند که چه تعداد عملیات forward pass در مرحله تست باید انجام شود. در اینجا, ما اندازه batch size فاز تست را ۱۰۰ و تعداد تکرار عملیات forward pass در فاز تست را هم ۱۰۰ قرار دادیم. تا اینطور تمام ۱۰ هزار تصویر موجود برای تست ما پوشش داده شوند. (۱۰۰*۱۰۰ =۱۰,۰۰۰ در هر تکرار یک دسته ۱۰۰ تایی از تصاویر خوانده میشود.)

test_interval هم مشخص میکند که عمل Test را در هر ۵۰۰ تکرار فاز آموزش انجام شود.

نکته خیلی مهم :
تو محاسبه test_iter بر اساس اندازه batch-size یی که در مدلتون مشخص میکنید در بخش تست خیلی دقت کنید. چون اگه ضرب این دو برابر test set شما نشه دقت غلط میگیرید یا دقت بیشتری از چیزی که هست یا کمتر از چیزی که هست.

به همین شکل حواستون به MaxIter و اندازه بچ تو فاز اموزش باشید و محاسبه شما و تست شما بر اساس هر epoch (ارائه کامل تمام نمونه های دیتاست ) باشه. مثلا اگه ۵۰ هزار عکس برای اموزش دارید و اندازه بچ شما در فاز اموزش ۱۰۰ هست. هر epoch شما برابر با ۵۰۰ تکرار هست. یعنی هر ۵۰۰ تکرار یعنی دیتاست شما کامل به شبکه ارائه شده پس میتونید testiter رو هم روی ۵۰۰ تنظیم کنید حداقل.

مثال Regression  در Caffe : 

برای دیدن مثال رگرشن که مثل همین مثال هست فقط یکسری فرق کوچیک داره اینجا کلیک کنید(مثلا برای deploy کردن ما تو دسته بندی از softmax استفاده میکنیم اما تو رگرشن کلا اخرین لایه ما باید لایه تماما متصل ما باشه و لایه Eucledian loss  رو حذف کنیم که برای رگرشن استفاده میشه)

فایل deploy هم فایلی هست که برای تست ازش استفاده میکنیم . مثل همون فایلی هست که در اموزش ازش استفاده میکنیم با این فرق که لایه های مربوط به اموزش رو حذف میکنیم . لایه هایی مثل ورودی و لاس و … که در زمان اموزش فقط معنا دارن.

مثال Multivariate Regression

برای Multivariate Regression هم میتونید این لینک رو ببینید.(بخش Multimodal Convolutional neural networks (CNN) رو ببینید )

 برای دیدن نمونه prototxt کلیک کنید 

بخش قبلی : fine-tuning

سید حسین حسن پور متی کلایی

درباره ی سید حسین حسن پور متی کلایی

موسس و مدیر سایت. اطلاعات در مورد فعالیت های کاری و تحصیلی : linkedIn . برای ارتباط از بخش تماس با ما یا در باره من استفاده کنید.

مقالات مرتبط

7 دیدگاه در “آموزش Caffe بخش پنجم :مثال عملی

  1. سلام و وقت بخیر
    امکانش هست در مورد شبکه MNIST بیشتر توضیح بفرمایید؟ یا بفرمایید که کجا می تونم در رابطه با این شبکه مطالعه کنم؟ 🙂
    راستش متاسفانه تا الان فکر می کردم MNIST یک دیتاست دستخط هست

    ممنونم

    1. Mnist یک دیتاست هست. شبکه MNIST هم اشاره به LeNet5 داره که یان لیکون برای اولین بار اونو معرفی کرد (شبکه های کانولوشن رو با این شبکه معرفی کرد)
      تو caffe یه ورژن از Lenet5 رو با یکسری تغییرات بعنوان مثال Mnist گذاشتن که میتونید ببینید و اجرا کنید تا بیاد دستتون طراحی شبکه و اموزش اون تو caffe مثلا چطوری انجام میشه.
      تو پوشه examples یکسری فولدر هست که هرکدوم یک مثال خاص رو داره و میتونید اجرا کنید. یکی از اون مثالها مثال Mnist هست که اینجا توضیح داده.

  2. سلام
    خدا قوت
    عالی بود
    ببخشید تو بخشهای قبل گفته بودیدبعد از لایه های کانولوشن لایه فعالساز(relu) قرار میگیره ولی چرا تو این شبکه اینجوری نیست؟
    ممنون

    1. سلام. این شبکه LeNet5 اصلی هست که یان لیکون تو مقاله اش ارائه کرده . تو مثال کفی هم بعنوان یه مثال کلاسیک اومده همین. اون زمان ReLU هنوز کشف نشده بود و خود لایه کانولوشن بعنوان یه nonlinearity بحساب میومد برای همینه که تو این مثال چیزی نمیبینید.
      شما همین معماری رو تست کنید بعد طبق آموزشهای قبلی ما بعد هر لایه کانولوشن یه ReLU اضافه کنید . میبینید سرعت همگرایی و دقت چقدر بهتر میشه . ReLU باعث افزایش nonlinearity شبکه میشه و همینم باعث همگرایی سریعتر و دقت بهتر میشه.

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *