Global & adaptive pooling

در شبکه های عمیق برای کاهش تعداد پارامتر ها  ازmax pooling  استفاده می شود به این صورت که بعد از چند لایه کانولوشنی ابعاد آن لایه های کانولوشنی را تغییر میدهد.

هایپرپارامتر هایی Pooling

  • stride
  • kernel size
  • average or max بودن تابع

درشبکه های عمیق و در لایه های fully connected پارامتر های این لایه ها  به سایز ورودی وابسته بود ولی در لایه های کانولوشنی تعداد پارامتر ها تنها به اندازه و تعداد فیلتر بستگی دارد. برای مثال وقتی مانند شکل زیر لایه آخر5 در 5 در 100 باشد (feature map تصویر) و به یک لایه fully connected صد تایی وصل میکنیم.اگر تصویر ورودی مقداری بزرگتر شود این لایه 100*5*5 تغییر می کند مثلا سایز آن 100*7*7 می شود ، پس تعداد وزن هایی که به نورون های لایه آخر وصل می شوند تغییر می کند.

مشکل : تعداد وزن های لایه flat  و fully conected

راه حل :  global average pooling(GAP)

روش کار

در مقاله [Lin et al., 2013. Network in network] به جای fully connected  ها در انتها global average pooling میزنیم تا future map ها را مستقیم به softmax وصل کنیم و از fully connected  استفاده نکنیم.

لایه آخر را pooling با kernel هم سایز  تصویر ورودی (activation map) میذاریم تا درانتها تنها یک کانال باقی بماند، یعنی طول و عرض هرچه باشد 1 شده و عمقش همان باقی می ماند. حال همین لایه را مستقیم به fully connected وصل می کنیم.

ResNet50 هم به صورت غیر مستقیم از average pooling استفاده کرده. به این صورت که لایه pooling آخرش اندازه خروجی (2048 * 1* 1) شده است ولی از  fully connected ها هم برای کلاس بندی انتهایی استفاده کرده است.

بررسی لایه های آخر  ResNet50

در لایه های انتهایی شبکه به دلیل وجود , Activation ، AveragePooling2D و لایه Dense  برای ما مهم هستند.

  • ابتدا  لایه activation  را بررسی می کنیم؛ این لایه شامل2048  نقشه فعال سازی (activation map )  که سایز آن (7 * 7) است، می باشد.در تصویر بالا k  همان تعداد activation map ها است.

k ={1, 2, 3, …., 2048}

  • لایه (GAP) AveragePooling2D   سایز هر کدام از این  activation map   ها را از (7 * 7) به (1 * 1) کاهش می دهد.
  • لایهDense  که صرفا ورودی را صاف کرده و بدون تغییر در اطلاعاتی که در لایه قبلی GAP ایجاد شده است  تنها دسته یا کلاس آن خروجی را مشخص می کند. حال برای اینکه شبکه هایی که طراحی می کنیم به سایز ورودی وابسته نباشند می توان از این لایه صرف نظر کرد و لایه GAP  را مستقیما به softmax  متصل کرد.

مزایا :

  • متناسب تر با شبکه های کانولوشنی است. زیرا با  ساختار convolution ها بیشتر دارد.  fully connected ساختار کانولوشن را به هم می ریزد. ارتباط بین دسته بندی لایه آخر و  feature map  ها حفظ می کند.
  • از overfitting جلوگیری می کند. : هیچ پارامتری برای بهینه سازی ندارد واز  overfitting  هم دراین لایه جلوگیری می کند. و می توان با کانولوشن بیشتر ، کاری کنیم عمق افزایش یافته و داده کمتری از دست برود.
  • به جابجایی حساس نیست. : نسبت به جابجایی های تصویر عملکرد بهتری دارد. مثلا شبکه ایی برای شناسایی سگ داریم و دیگر جایگاه سگ در هرجای تصویراهمیتی ندارد.

 

استفاده از global average pooling   در framework  های مختلف

در keras کد global average pooling  به صورت زیر است که تنها dataform را میگیرد و سایز ورودی نمی خواهد چون نسبت به سایز activation map سایز آن را انتخاب میکند.

 

pytorch

از بخوایم global pooling در pytorch داشته باشیم adaptivePooling با سایز یک را صدا میزنیم. اینگونه عمل می کند که سایز خروجی رابهش به عنوان پارامتر می دهیم.

 

 

fastai

به این صورت پیاده سازی شده است که AdaptiveAvgPool2d و AdaptiveMaxPool2d   را صدا میزند و خروجی این دو تابع را بهم متصل می کند.

 

مسئله : تشخیص نژاد های مختلف سگ

دیتا شامل پوشه عکس ها و یک فایل اکسل شامل نام عکس و نژادش است.

در کد بالا آدرس پوشه عکس ها را داده خط 2 سایز ورودی را مشخص کرده در خط 3 شبکه را resnex124 تعریف کرده ایم و خط 4  batch size رو هم 58 گذاشتم.

(اگر روی gpu کارکنید و 2 یا 3 گیگ رم دارید احتمالا باید تعداد batch size   را کم کنید.)

لیبل ها را از فایل csv خونده واون label  باز کن و لیستش کن و طول اون لیست رو به ما بعده منهای یک برای جدا کردن هدر لیست  که همان تعداده داده های ماست، توسط تابع get_cv_index(n)   ایندکس های cross validation را جدا می کند اینگونه که 20 درصد index ها را برای cross validation  جدا میکند.

 

 

کد بالا نشان می دهد تا اینجا دو پوشه train و test همراه با label ها جدا شده است.

فایل csv را با پاندا خونده و 5تای اولشو نمایش می دهد.

تعداد هر کلاس را پیدا کرده ایم.

تابع pivot_table   :

 

به تابع tfms_from_model معماری ، سایز ورودی، ارگومیشن هم میخواهیم به صورت side_on ، بیشترین زوم هم 1.1 باشه بر روی تصاویر(چقدر روی عکس هربار رندوم زون کند)

تابع ImageClassifierData.from_csv می گوید از همان ساختاری که عکس های توی یک پوشه هستند و لیبل ها در  csv استفاده  کن. مسیر پوشه ها و اسم پوشه های train و test  را گرفته و اگر valdation_index  بهش پاس بدیم توی train_set اونا رو در نظر نمیگیره. توی اکسل پسوند اسم عکس ها وجود نداشته و به عنوان suffix پسوند پاس داده شده.

بر روی تمام فایل ها سایز ها گرفته و  تمام سایز ها را در size_d  دارد

سایز سطر و ستون را جدا کرده و به صورت هیستوگرام نمایش می دهد. که هیستوگرام نشان می دهد بیشتر تصاویر سایزی در اندازه 500 تا 1000 و کمتر از هزار هستند. پس تصاویر من در اندازه های بزرگ اند.

تابع فوق  داده ها را برمیگرداند با سایز تصویر و batch size ورودی دلخواه. هروقت تابع صدا شود یک trasformation میزند و سپس تصاویر را به اندازه batch size در متغییر data ریخته و در انتها قبل از بازگردانی تصاویر کوچکتر از 300 را ابتدا به 340 تبدیل کرده و سپس در پوشه tmp ذخیره میکند که حداقل تغییر اندازه از 340 باشد به اون سایز که cashing یک بارانجام شده باشد تا در تغییر اندازه تصاویر خیلی بزرگ به سایز کوچک overhead کمتری داشته باشیم و سرعت افزایش بیابد.(چون میخواهیم هر epoch را با یه سایزی پیش بریم)

 

از ConvLearner  متد pretrained را صدا زده و معماری و داده و پارامتر precompute هم true قرار میدهد.

متدpretrained  درای پارامتر ps است که بیانگر احتمال dropout است.

(در هنگام اجرای کد بالا با خطا مواجهه شدید وزن هارا دانلودکرده و در پوشه اشاره شده قرار دهید.)

 

با learning rate  ده به توان منفی 2 ، به تعداد 5 epoch می زند. با سایز وردوی 224 در 224

precompute را false کرده تا data argumation ما فعال بشه.

 

cycle_len= 1  بیانگر این است که یکی   یکی بره بالا

با set_data شبکه رو آگاه! میکنه که سایز عکس قراره تغییرکنه. سپس شبکه را فیریز می کند.

 

 

دیده می شود که بعد از adavtivePooling سایز ورودی از 2048 به سایز 4069 تغییر یافته است.

باTTA() می خواهد ببیند که می توان validation را بهتر کرد ..

مدل را ذخیره می کند.

تطبیق و بازشناسی چهره(2)

رویکرد دیگر در سال 2014 به این صورت بود که تشخیص چهره را به صورت کلاس بندی باینری ببینیم اینگونه که دو عکس مورد بررسی را به شبکه بده و در انتها لایه 128 را وصل کن به یک binary classifier که اگه دو نفر یکسان بودند true و در غیر این صورت،  false برمیگرداند.

دیتا ست در این رویکرد به صورت زیر است که یه مجموعه مقایسه ایست که یکسان بودن و نبودن را بیان می کنند و batch هم ظریب 2 می شود.

باز میبینیم که تعدادحالت های ما بسیار زیاد می شود.

Center loss

برای تصویر تنها تفکیک پذیر(separable) بودن مهم نیست بلکه باید یک فاصله ایی هم در فضا از هم داشته باشند.( discriminative باشند)

فیچر های ماقبل لایه آخر (encoding) درهر mini_batch ، این 128 ها را میانگین بگیرد و  loss  را طوری تعریف می کنیم که علاوه بر softmax همه به سنترمشخص شده نزدیک تر بشن.

separable
separable
discriminative
discriminative

 

 

 

کانال عکس ابتدا وارد می شود.

 

یک شبکه را لود کردیم با پارامتر های تعداد کانال و سایز عکس ها که 96 * 96 است.

 

در کامپایل پارامتر loss را تابعی که خودمان برای loss triplet نوشتیه ایم میگذاریم.

وزن های قبلا train شده را در شبکه خودمون لود میکنیم.

عکس را داده و خروجی 128 تایی لایه آخر شبکه را در یک دیکشنری ذخیره میکنیم.

تابعی که عکس را گرفته و فاصله اقلیدسی آن را با عکس های موجود در دیتاست محاسبه کرده (threshold که براساس تست یافته ایم، cross validtion باید بزنیم تا بهترین کارایی برسیم.)و می گوید این عکس داده شده همان لیبل هست یا نه. true و false برگردان.

پارامتر ها:

  • عکس
  • لیبل عکس
  • دیتاست
  • مدل شبکه

تابعی که عکس را گرفته و recognation انجام می دهد، به این صورت که encoding عکس را از مدل گرفته و در تمام دیتاست موجود چک می شود اگر فاصله اقلیدسی آن از min_dist کوچکتر باشد نام آن را بر می گرداند.