تجربه مسابقه Kaggleمن، 3 چیز که کشف کردم و 3 چیز که دفعه بعد امتحان خواهم کرد. Kaggle (www.kaggle.com) یک سایت میزبان مسابقات است. برای مثال یک رقابت معمولی مانند یافتن یک مدل پیشبینی که از یک مجموعه داده شروع میشود. برنده کسی است که بهترین مدل را طبق یک مجموعه آزمایشی پیدا کند.(نوشته مارکو فابیانی)
نکته جالب این است که Kaggle نه تنها میزبان مسابقات دستگرمی است، بلکه میزبان مشکلات واقعی شرکت هایی است که مایل به پرداخت برای بهترین راه حل ها هستند. و جوایز از چند هزار تا چیزی در حدود 500 هزار برای مسابقات گذشته (همه اطلاعات در وب سایت) است.
این یک زمینه کاملاً متفاوت است: دیگر هیچ سوال مقدماتی وجود ندارد، دیگر افراد بی انگیزه با مجموعه دادهها بازی نمیکنند. در اینجا پول واقعی روی میز است، بازی سخت و سختتر می شود!
قبلاً Kaggle را میشناختم، در گذشته چند مسابقه دستگرمی انجام دادم تا برخی از الگوریتمهای یادگیری ماشین را بررسی کنم. در چند سال گذشته به یادگیری عمیق علاقه نشان داده بودم (من به عنوان مدیر تحقیق و توسعه بینایی کامپیوتر کار می کنم و بیش از 20 سال تجربه در شبکه های عصبی دارم، بنابراین یادگیری عمیق برای من یک راه واضح است) و چند هفته قبلتر متوجه شدم که Kaggle میزبانی مسابقه مرتبط با طبقه بندی تصاویر را دارد. همراه با 56 هزار دلار جایزه. بنابراین وقت آن رسیده بود که وارد میدان شوم و تخصص خود را در مقایسه با گروهی از رقبای بسیار تهاجمی بررسی کنم.
با خودم فکر کردم: "من یک متخصص یادگیری عمیق هستم"، ببینیم در مقایسه با بهترین های جهان در کجا هستم!".
بنابراین من مجموعه داده را دریافت کردم و شروع به بازی با چند مدل یادگیری عمیق استاندارد کردم. من ترجیح دادم به انجمنها نگاه نکنم، معمولاً مملو از نکات خوب، و به تصاویر موجود در مجموعه آزمایشی نگاه نکنم تا تصور درستی از سطح مهارت فعلیام داشته باشم. چند روز بعد از ارائه اولین آزمونم. "1300 شرکت کننده وجود دارد. خوب، مطمئناً من در نیمه بالایی نردبان هستم. شاید در 10٪ بالا، بگذارید ببینیم."
چه شکستی!
"خوب، شاید من مهارتهایم را در یادگیری عمیق دستکم در مقابل بقیه دنیا بیش از حد برآورد کردهام. بیایید کمی به آن بپردازیم."
بنابراین به نامزدم گفتم که در آن آخر هفته روی من حساب نکند و من شروع کردم. زمان بسیار کوتاه بود - من نزدیک زمان پایان به مسابقه ملحق شدم و بدتر از آن، یک سفر کاری برای آخرین هفته موجود برنامه ریزی کرده بودم، بنابراین فقط چند روز فرصت داشتم تا موقعیت خود را بهبود بخشم.
بعد از 30 تست ، که یک جفت از آن ها برای آموزش شبکه یک روز طول کشید، موقعیت من حدود 400 با 1400 شرکت کننده بهبود پیدا کرد. من از سفر خود برگشتم و بررسی کردم که چه اتفاقی افتاده است: در حال حاضر من با 1450 شرکت کننده در رتبه 489 هستم. فکر نمی کنم بتوانم تست های بیشتری انجام دهم، رقابت تا 2 روز دیگر به پایان می رسد، بنابراین فکر می کنم در 33 درصد بالای نردبان باقی بمانم. اما من میخواهم یافتهها و ایدههایی را به اشتراک بگذارم که اگر وقت داشتم آنها را آزمایش میکردم و مطمئناً با کار طبقهبندی تصویر بعدی که Kaggle میزبانی خواهد کرد، تلاش خواهم کرد!
3 نکته برای انجام یادگیری عمیق
1- از فرم درآوردن تصویر برای افزایش دیتاست.
تقویت مجموعه داده ها یک چیز بدیهی در یادگیری عمیق است، و بر طبق تجربه من است، یکی از مهم ترین چیزهایی است که باید درک و اعمال شود. یک رویکرد صحیح در تقویت مجموعه داده به منظور جلوگیری از تطبیق بیش از حد و تعمیم، حیاتی است. برای این مسابقه از چند تکنیک استفاده کردم که برای پروژه های دیگر (واقعی) استفاده کردم. به ویژه متوجه شدم که یک چیز بسیار خوب برای این مشکل نه تنها زوم کردن، چرخاندن تصویر به صورت تصادفی (همانطور که معمولاً انجام میشود) بود، بلکه اعمال تغییر شکلهای محلی مانند "پینچ"، "پانچ"، "چرخش" بود. و فیلترهای خنده دار دیگری که می توانید در نرم افزارهای فتوشاپ مانند پیدا کنید. این احتمالاً به شبکه کمک کرد تا برخی از الگوهای مرتبط موجود در تصاویر (دست، تلفن، چرخ و غیره) را بهتر تعمیم دهد.
2- نویز
نویز کلید یادگیری عمیق است. عجیب به نظر می رسد اما نویز (کنترل شده) در آموزش شبکه های عمیق بسیار مفید است. به طور معمول شما نویز را در تصویر منبع اعمال می کنید، و البته من این کار را انجام دادم، و همچنین یک سری تبدیل های نویز مانند مانند گرادیان نور، تاری تصادفی، انعکاس نور شبیه سازی شده و غیره را هم اعمال کردم. اما این بار چیز دیگری را امتحان کردم: اعمال نویز در خروجی لایههای میانی، و فکر میکنم این به شبکه کمک میکند تا فیلترهای «محکمتر» را در لایههای میانی پیدا کند. نتیجه نهایی بهبود یافت، اما من وقت نداشتم جزئیات را بررسی کنم تا بفهمم چه اتفاقی افتاده است: تزریق تصادفی نویز در لایه میانی چیزی است که من قطعاً می خواهم بررسی کنم.
3) استفاده از لایه های نه چندان ساده
من تقریباً همیشه از پشتههای لایهها به شکل N تایی (کانولوشن 3*3، strike=1 , pad=1 , ReLU) وبعد استفاده از یک ماکسپول 2*2 استفاده میکنم.
من تقریباً همیشه از پشتههای لایهها به شکل N تایی (کانولوشن 3*3، strike=1 , pad=1 , ReLU) وبعد استفاده از یک ماکسپول 2*2 استفاده میکنم.
ماکس پولینگ چیست؟
ادغام یک ویژگی است که معمولاً در معماری شبکه عصبی کانولوشنال(CNN) گنجانده شده است. ایده اصلی پشت یک لایه ادغام، «انباشته کردن» ویژگیها از نقشههای تولید شده توسط انحراف یک فیلتر روی یک تصویر است. به طور رسمی، عملکرد آن کاهش تدریجی اندازه فضایی نمایش برای کاهش مقدار پارامترها و محاسبات در شبکه است. رایج ترین شکل Max Poolingاست.
تکنیک Max Pooling موقعی انجام می شود تا با ارائه یک شکل انتزاعی از نمایش، به تطبیق بیش از حد کمک کند. همچنین، هزینه محاسباتی را با کاهش تعداد پارامترهای یادگیری کاهش میدهد و بدون تغییر، ترجمه اولیه را برای نمایش داخلی فراهم میکند. تکنیک Max Pooling با اعمال یک فیلتر برای زیرمنطقه های غیر همپوشانی نمایش اولیه انجام می شود. اشکال دیگر ادغام عبارتند از: متوسط، عمومی.
در ابتدا از تکرارهای کانولوشون 3*3، ReLU، MaxPool، کانولوشون 3*3، ReLU، MaxPool و ... استفاده میکردم. اما متوجه شدم که این معماری آنقدر سطحی است که اجازه کشف رفتارهای جالب را نمی دهد. علاوه بر این، هر فیلتر فقط 3*3 است و به طور معمول برای مشکلات واقعی بسیار کوچک است. با استفاده از تکرارهای کانولوشون 3*3، ReLU، MaxPool، کانولوشون 3*3، ReLU، MaxPool و ... قبل از لایه pooling مانند داشتن فیلترهای بزرگتر است. فیلترکانولوششن 3*3*3 " پنجره ای" از 7*7پیکسل در تصویر است. به دو دلیل مانند استفاده از یک هسته 7*7 نیست: اول، پارامترهای کمتری با استفاده از 3x(3x3 conv) نسبت به تبدیل کانولوشن 7*7 وجود دارد، و دوم اینکه غیرخطی های بیشتری در 3x(3x3 conv) در مقابل یک ReLU پس از تبدیل کانولوشن 7*7وجود دارد. هر دو چیز خوبی هستند. بنابراین به جای استفاده از هسته های بزرگتر، از پشته های 3x3conv + ReLU استفاده کنید. در این مورد خاص، من با استفاده از 3*(3*3 conv), 2*(3*3 conv) و همچنین 4*(3*3 conv) قبل از لایه ادغام (pooling) پایان دادم.
چه چیزی را می خواهم امتحان کنم؟
1- شبکه باقیمانده
در این مورد چیزی نمی توان گفت، من سعی خواهم کرد یک شبکه باقی مانده را پیاده سازی کنم تا ببینم آیا عملکرد بهبود می یابد یا خیر. متأسفانه من فقط رایانه یدکی خود را با کارت گرافیک ارزان قیمت NVidiaبرای این آزمایش ها دارم. بنابراین من مجبور شدم از تصاویر 160x120 به جای 640x480اصلی استفاده کنم. و این مطمئناً بر عملکرد شبکه تأثیر می گذارد. علاوه بر این، مجبور شدم اضافه کردن لایهها را قبل از آنچه احتمالاً لازم بود متوقف کنم. عمیق ترین شبکه آموزش دیده دارای 14 لایه کانولوشن قبل از طبقه بندی کننده است. این می تواند یک مشکل با شبکه های باقی مانده باشد.
یک شبکه باقیمانده شامل واحدها یا بلوک های باقیمانده است که دارای اتصالات پرش (skip)هستند که به آنها اتصالات هویتی نیز گفته می شود. خروجی لایه قبلی بعد از آن در بلوک باقیمانده به خروجی لایه اضافه می شود.
2- مجموعه داده پویا
این چیزی است که من سالهاست به آن فکر می کنم. اگر فرصت پیدا کنم که مدتی را به مطالعه در آن صرف می کنم. ایده این است که به صورت پویا مجموعه داده را در طول آموزش تغییر دهید. من در مورد نویز یا چیزی مربوط به تغییرات تصویر صحبت نمی کنم. من از تکثیر/سرکوب داده ها یا تخصیص مجدد کلاس داده ها صحبت می کنم. یک ایده برای مثال تکرار موارد پرت به منظور "اجبار" کردن شبکه به یادگیری آنها، یا سرکوب نمونه های به خوبی توسط شبکه آموخته شده اند به منظور انعطاف پذیری برای یادگیری موارد دشوار است و زمانی که مثال های سرکوب شده چندان خوب نیستند، دوباره ، آنها را شناسایی می کنید.
3- لایه conv را برای مناطق جداگانه در تصویر جدا کنید.
این موضوعی است که به طور خاص از زمانی که با مشکلات رانندگی خودکار درافتادم به آن فکر می کنم. در بسیاری از پروژه ها ، تصاویر داده شده ، "ایزوتروپیک" نیست. برای مثال، تصاویری که از دوربینهای خودرو به دست میآیند، دارای «مناطق» کاملاً مشخصی هستند. بالا آسمان است، پایین جاده، چپ و راست خطوط و غیره هستند. شما چراغ راهنمایی را در مرکز خط پیدا نخواهید کرد (نه همیشه)، شما تمایل دارید آن را در بالای جاده یا کنار آن پیدا کنید. در مورد رقابت Kaggleهم همینطور است: همه تصاویر با راننده در سمت چپ و فرمان در سمت راست است و بنابراین شما دست راننده را معمولاً در سمت راست و نه در سمت چپ خواهید یافت، اما شما سر را در سمت راست و نه برای مثال بیرون از پنجره پیدا می کند. بنابراین میتوانید در زمان محاسباتی در تقسیم تصویر در مناطق صرفهجویی کنید و از لایههای کانولوشنال با فیلترهای کمتر متمرکز بر مناطق مختلف استفاده کنید. میتوانید انتظار داشته باشید که به فیلترهای کمتری برای کدنویسی آنچه در این مناطق خواهید یافت نیاز داشته باشید. این می تواند به دستورالعمل "یک فیلتر برای همه عکسها" اضافه شود. نمی دانم که این شیوه آخری جواب خواهد داد یا نه اما بالاخره به امتحانش می ارزد.