Transfer learning

ما برای کانولوشن ها (CNN) نیاز به میلیون ها دیتا داریم. البته براساس Transfer learning
ما می توانیم از مدل آموزش دیده ی شخص دیگری که مدلش را بر روی دیتاهای بسیار آموزش داده است استفاده کنیم به طوری که نیازی نباشد تا برای آموزش شبکه کانولوشن خودمان ملیون ها دیتا را بررسی و تحلیل کنیم. به عنوان مثال در تصویر زیر برای تشخیص گربه ایرانی از گربه ی خیابانی و یا هرچیز دیگری:

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

در این حالت به جای اینکه به این فکر کنم که چه مشخصه هایی از تصویری که به مدل داده ام را استخراج کنم، عکس را به مدل آموزش دیده ی یک شخص دیگری می دهیم بعد مشخصه های لایه های ماقبل آخر را از مدل میگیرم به عنوان مثال لایه ماقبل آخر Alexnet ، 4096 تا است که به عنوان مشخصه های تصویر از مدل Alexnet میگیریم.
حال در مدل freeze شده لایه های سمت چپ لبه ها را تشخیص می دهند و هرچه از سمت چپ به سمت راست حرکت میکنیم لایه های مشهودتری مثل گوش گربه را به خوبی تشخیص می دهد.
اگر با مسئله جدیدی برخوردیم مثلا دو آبجکت را در نظر بگیریم که در دیتاست ما، دیتاهای کمی از آنها وجود دارد. برای بهینه تر کردن مدل ما به صورت زیر:

نه تنها softmax بلکه چندین لایه ی اضافه ی دیگری را از سمت راست حذف میکنیم. تعداد لایه هایی که می توانیم در مدل حذف کنیم بستگی به مقدار دیتایی دارد که از آن آبجکت داریم هرچه دیتای بیشتری داشته باشیم میتوانیم لاهای بیشتری را حذف کنیم، همانطور که در تصویر زیر مشخص است:

اگر یک دیتاست معمولی(متوسط) یا کوچک داشته باشیم میتوانیم لایه های مشخص شده را حذف کنیم و خودمان از اول لایه های آموزش دیده را بجای آنها قرار دهیم.

اکنون در قالب یک مثال عملی میخواهیم چند عکس از یک گربه بگیریم و این تصاویر را به یک کلاسیفایر معرفی کنیم و برنامه ایی بنویسیم که تمام کامپیوتر را بگردد و آدرس تصاویر مربوط به گربه ی مشخص شده را برگرداند:

از کراس مدل ذخیره شده مان را لود میکنیم البته قبل از این باید با دستور pipe h5 py را نصب کنیم. بعد از این باید یک سری پرپروسسینگ به صورت زیر روی تصویر انجام بدهیم. کتابخانه های مورد نیاز را ایمپورت میکنیم:

نکته : عبارت %matplotlib inline یک کلمه ی کلیدی در jupyter notebook است(یعنی در محیط برنامه نویسی پایتون نمی توان از آن استفاده کرد) که اگر از نوشتن آن صرف نظر کنیم تا ۹۰ درصد امکان عدم نمایش خروجی در نوتبوک را دارد لذا بهتر است از آن استفاده کنیم.
در ادامه تصویر مورد نظر را وارد میکنیم تصویر را از testset ایمپورت میکنیم testset جایی است که در فرآیند training شرکت نداشته است.

پارامتر target_size را به اندازه شبکه ایی که قبلا تعریف کرده یم قرار میدهیم که در اینجا چون اندازه شبکه را قبلا ۱۵۰ در ۱۵۰ تعریف کرده ایم لذا از همین اندازه استفاده میکنیم.
بعد از نمایش تصویر آنرا بر ۲۵۵ تقسیم میکنیم تا نرمال شود.
بعد از اجرا خروجی به صورت زیر خواهد بود:

که مقدار model.predict و model.predict_classes در بالای تصویر هست. که مقدار model.predict_classes خروجی sigmoid در شبکه کانوشوال است.
نکته: خروجی Sigmid مقداری بین صفر و یک را برمیگرداند که هرچه به صفر نزدیکتر باشد با احتمال قوی تری می گوید که تصویر گربه است و هرچه به یک نزدیک باشد بلعکس خواهد بود و اگر مدل نتواند تصوری را تشخیص دهد مقداری در حدود نیم خواهد داد.

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

و فضای نورونی جدیدی را به صورت زیر داریم:

در بخش اول کد با include_top=false همه ی fully connectedها را دور میریزم. با input_shape=(150, 150, 3) ابعاد عکس را تعیین میکنیم که به ترتیب طول و عرض و convolutionاست . در این جا وزن ها را روی چالش ‘imagenet’ تنظیم کردیم .

conv_base.summary():(VGG)summary هست ولی با (150, 150, 3) تنظیم شده است و با pollingهم به اتمام رسیده است. در توضیح Non-trainable هم وقتی freeze نکرده باشیم قاعدتا Non-trainable هم نداریم . بیشتر بودن وزن include_top نیز به خاطر fully connected میباشد.

base_dirمسیری هست که دیتای تمیز شده در آن موجود میباشد. extract_features هم عکس ها را Fitمیکند به شبکه وبعد featureها را برمیدارد و در numpy arrayذخیره میکند . featuresخود به این معنی است که تعدادی عکس با این dimensional میخواهیم و موقتا با صفر پرشده است . در generatorچون بحث در کلاس است به صورت binaryمیباشد .

inputs_batch در این جا 20 تا (3* 150* 150)داریم و features_batch20تا 512*4*4است. آرایه های labelsو featuresقرار است تا ماتریس های 2000تایی رو پر بکند. Featuresدر این جا لایه آخر convolutionاست. این جا خروجی قرار است با train_features, train_labelsباشد که در train_labels خروجی 1*2000 داریم.

در قطعه کد بالا reshapeها کار floatکردن را مثل دیتاست هدی انجام میدهد.ما در این جا برای trainکردن یک classifierداریم . در این جا ayers.Dropout(0.5) برای overfitنشدن هست(به این منظور که یکسان زیاد میبینیم)که راه دیگر data augmentation هست . activation=’sigmoid’ است چون کلا در این جا دو کلاسه هستیم . ما به جای generator،model.fit داریم چون از دایرکتوری چیزی را نمیخواند . حال این سوال مطرح میشود که چرا data augmentation مفید نمیباشد؟
باید بگوییم این جا 30 تا epoch 2000 تایی داریم وبا numpy array یک بار این 2000 تا عکس را trainمیکنیم نه 30 بار! ولی در augmentation چون نمیتوانیم reuseکنیم و عکس جدید میخواهد مفید نیست!

فوتر سایت

اسلایدر سایدبار

درباره ما

درباره ما

ما گروهی از دانشجویان رشته کامپیوتر دانشگاه شهید رجایی هستیم که به راهنمایی و تدریس استاد علی‌رضا اخوان‌پور به دنیای یادگیری عمیق پا گذاشتیم و دوست داریم چیزهایی که در این مسیر یادمی‌گیریم رو به اشتراک بذاریم.

شبکه های اجتماعی

مطالب اخیر