تصویر نمونه برای نمایش تکنیک های Image data augmentation

استفاده از Image Data Augmentation در کتابخانه Keras

تقویت دیتاست و افزودن داده های تصویری یا Image data augmentation تکنیکی است که با استفاده از آن می توان به طور مصنوعی و بدون تصویربرداری جدید، و تنها با ایجاد نسخه های دستکاری شده از تصاویر موجود اندازه دیتاست را افزایش داد.

آموزش شبکه های عصبی مصنوعی عمیق با داده های بیشتر می تواند به داشتن شبکه های قوی تر منتهی شود؛ و تکنیک های Image data augmentation می توانند گونه هایی از تصاویر را بسازند شبکه با یادگیری خصوصیات جدیدی از آن تصاویر علاوه بر تصاویر اصلی، قدرت درک گستره بیشتری از هر شئ را پیدا می کند و به اصطلاح Generalized می شود.

کتابخانه یادگیری عمیق Keras قابلیت هایی را برای ساده کردن فرآیند آموزش شبکه ها با داده های Image data augmentation فراهم کرده است که در کلاس ImageDataGenerator از این کتابخانه در دسترس است.

بعد از مصالعه و تمام کردن این مطلب آموزشی، شما موارد زیر را فرا می گیرید:

  • استفاده از تکنیک های Image data augmentation برای افزایش انداره دیتاست که موجب بهبود عملکرد و توانایی شبکه یادگیری عمیق می شود.
  • به طور مشخص استفاده از کلاس ImageDataGenerator که در کتابخانه Keras پیاده سازی شده است.
  • نحوه استفاده از تکنیک های shift ، flip ، brightness change ، zoom ،  و غیره.

 

بیایید شروع کنیم!

این آموزش هشت بخش تقسیم شده است که عبارتند از:

  1. تعریف مفهوم Image data augmentation
  2. ارائه تصویر نمونه
  3. استفاده از کلاس ImageDataGenerator برای تقویت و گسترش دیتاست
  4. تکنیک شیفت عمودی و افقی تصاویر
  5. تکنیک برگرداندن تصویر به صورت عمودی و افقی
  6. تکنیک چرخش تصویر به مقدار تصادفی
  7. تکنیک تغییر روشنایی به مقدار تصادفی
  8. تکنیک بزرگنمایی تصویر به مقدار تصادفی

 

تعریف مفهوم Image data augmentation

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

تکنیک Data augmentation در اینجا به کمک ما می آید تا به طور مصنوعی تصاویر جدیدی برای آموزش تولید کند که از تصاویر اصلی به دست می آیند. این کار در هر کاربرد و دامنه ای از شبکه های یادگیری عمیق روش های مخصوص به خود را دارد؛ مثلاً در یادگیری تشخیص گفتار انسانی، صداها کمی نویز به سیگنال صوت استفاده می کنیم تا شبکه تشخیص کلمات یا احساسات را حتی با صداهای غیرشفاف نیز یاد بگیرد. اما در تشخیص وجود شئ در تصویر یا پیدا کردن دقیق جای چند شئ در یک تصویر، تکنیک های دیگری مثل چرخش و تغییر روشنایی و بریدن تصویر استفاده می شود.

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

منظور ما از دگرگونی که گفتیم گستره ای از عملیات های پردازش تصاویر مانند شیفت ها، برگردان ها، بزرگنمایی ها و چیزهای خیلی بیشتر است.

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

پس مشخص است که انتخاب تکنیک data augmentation به کار رفته باید با دقت و مطابق با محتوای دیتاست و نوع مسئله انجام شود. می توانید در این زمینه به آزمایش و خطا هم بپردازید، به این شکل که بخش کوچکی از تصاویر آموزش را با شبکه ای کوچک آموزش دهید و در این آموزش از تنظیم های مختلفی برای تولید تصاویر جدید استفاده کنید و بهبود یا عدم بهبود شبکه را به طور مداوم در نظر داشته باشید.

الگوریتم های مدرن یادگیری عمیق، مثل شبکه های عصبی کانولووشنی یا CNN، می توانند ویژگی هایی را یاد بگیرند که مستقل از جای آن ها در تصویر است. با این وصف تقویت و افزودن دادها با تغییر چرخش و نور و رنگ، می تواند کمک بیشتری به این یادگیری ویژگی های مستقل در تصویر بکند؛ در نهایت شبکه به خوبی یاد می گیرد شئ را اگر در تصویر از چپ به راست برگردانده شده بود یا نور و شفافیت کمی داشت یا خیلی چیزهای دیگر، باز هم به درستی تشخیص دهد.

دقت داشته باشید که Image data augmentation معمولاً باید فقط روی  تصاویر آموزش اعمال کنید و نه داده های validation یا test (مگر اینکه بنا به کاربرد شبکه، دلیل خوبی داشته باشید). اما خب بدیهی است که پیش پردازش هایی مانند تغییر اندازه و نرمال سازی به طور یکسان روی کل تصاویر اعمال می شود و از این لحاظ با اعمال Image data augmentation متفاوت است.

 

یک تصویر نمونه برای آموزش

ما برای نمایش تکنیک های استاندارد data augmentation به یک تصویر نمونه نیاز داریم. در این آموزش ما عکسی از یک پرنده را استفاده خواهیم کرد که از این آدرس برداشته ایم و عنوان آن “دوست پر و بال دار” است.

تصویر را دانلود کنید و با نام ‘bird.jpg’ ذخیره کنید تا در کدهای زیر از آن استفاده کنید.

تصویر نمونه برای نمایش تکنیک های Image data augmentation

Feathered Friend, by AndYaDontStop

 

تقویت و گسترش دیتاست با کلاس ImageDataGenerator

کتابخانه یادگیری عمیق Keras توانایی استفاده راحت از data augmentation را فراهم کرده است و این کار را حین آموزش شبکه به طور اتوماتیک و به طور بهینه انجام می دهد. این قابلیت با استفاده از کلاس ImageDataGenerator در دسترس است.

اول از همه، باید از این کلاس یک شئ ایجاد کنید و تنظیمات انواع و مقدار data augmentation ها را از طریق آرگومان های سازنده کلاس به آن بدهید.

گستره ای از تکنیک ها در این کلاس پیاده سازی و پشتیبانی شده اند که ما اینجا روی پنج نوع اصلی از تکنیک ها برای تصاویر تمرکز می کنیم؛ به خصوص:

  • شیفت پیکسل های تصاویر با آرگومان های width_shift_range و height_shift_range .
  • برگرداندن تصاویر از چپ به راست و پایین به بالا با آرگومان های horizontal_flip و vertical_flip .
  • چرخش تصاویر با آرگومان rotation_range .
  • تغییر روشنایی تصاویر با آرگومان brightness_range .
  • چرخش بزرگنمایی تصاویر با آرگومان zoom_range .

برای مثال، یک شئ از کلاس ImageDataGenerator می تواند به صورت زیر ساخته شود.

بعد از اینکه شئ ساخته شد، می توانیم با آن یک iterator از یک دیتاست تصویر بسازیم. iterator مذکور در حین فرآیند آموزش به صورت دسته ای یا batch based تصاویر تولید شده را به شبکه می دهد.

این iterator حتی با دادن یک تصویر که در حافظه بارگذاری شده هم می تواند ساخته شود که برای این کار از تابع flow استفاده می کنیم. برای مثال:

به عنوان جایگزین، یک iterator می تواند با تصاویر روی دیسک و بدون پیش بارگذاری در حافظه هم ساخته شود و به این ترتیب خواندن اطلاعات فایل تصاویر را هم به عهده همان شئ کلاس ImageDataGenerator گذاشت. اما این شیوه نکته ای دارد و آن این است که در پوشه دیتاست مشخص شده، تصاویر هر دسته در زیرپوشه ای جداگانه قرار داشته باشد و تصاویر دسته های مختلف نمی توانند در هم ریخته باشند. در مثال زیر آرگومان داده شده مسیر اصلی پوشه دیتاست روی دیسک را مشخص می کند.

هنگامی که iterator ساخته شد، می توان از آن برای آموزش شبکه به عنوان آرگومان برای تابع fit_generator بهره برد.

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

مثلا اگر ۱۰۰۰۰ تا تصویر داشته باشیم که data augmentation روی آن اعمال شود و به شبکه داده شود، و اندازه دسته یا همان batch size را ۶۴ در نظر گرفته باشیم، باید ۱۵۷ دسته و گام برای هر ایپاک در نظر بگیریم و مقدار steps_per_epoch برابر با ۱۵۷ می شود (۱۰۰۰۰ تقسیم بر ۶۴ می شود ۱۵۶.۲۵ که ما آن را به ۱۵۷ رند کرده ایم).

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

گاهی از ImageDataGenerator فقط برای نرمال سازی مقدار پیکسل ها استفاده می شود در این صورت می توان آن ها را برای داده های validation و test هم به کار برد؛ اما در این آموزش تمرکز ما به طور خاص روی این مورد نیست و فراتر از آن را بررسی می کنیم.

در بخش های بعدی تکنیک هایی به طور جداگانه معرفی و استفاده می شود و نمونه هایی از نتیجه اعمال آن ها را می بینیم. اینکه روی تعدادی محدود از نمونه ها و به طور جداگانه تکنیک ها را اعمال و نتیجه را بررسی و مشاهده کنید تمرین خوبی برای یافتن تنظیم درستی از ترکیب تکنیک هاست که با داده ها و مسئله ای که می خواهید حل کنید، سازگاری خواهد داشت.

 

تکنیک شیفت عمودی و افقی تصاویر

یک شیفت به تصویر هل دادن تمام پیکسل های تصویر در یک جهت مشخص است، مثل شیفت عمودی و افقی و قطری. در حین این عمل اندازه تصویر ثابت می ماند.

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

آرگومان های width_shift_range و height_shift_range در سازنده ImageDataGenerator را می توان مقداردهی کرد تا ضمن فعال سازی این شیفت ها، بازه ممکن برای شیفت احتمالی افقی و عمودی هر تصویر مشخص شود.

این آرگومان ها می توانند مقدارهای اعشاری در قالب یک عدد یا آرایه ای از اعداد را بگیرند که عدد تنها اگر کمتر از ۱ باشد کسری از تصویر را نشان می دهد که می تواند شیفت بخورد و اگر بیشتر از یک باشد تعداد پیکسل ها را دقیقاً مشخص می کنند. اگر هم آرایه ای از اعداد باشد بازه ممکن برای انتخاب تصادفی میزان شیفت پیکسل ها را مشخص می کند. توضیحات زیر در سایت رسمی Keras هم نوع مقادیر آرگومان ها را توضیح می دهد.

  • width_shift_range: Float, 1-D array-like or int
    • float: fraction of total width, if < 1, or pixels if >= 1.
    • ۱-D array-like: random elements from the array.
    • int: integer number of pixels from interval (-width_shift_range, +width_shift_range)
    • With “width_shift_range=2” possible values are integers [-1, 0, +1], same as with “width_shift_range=[-1, 0, +1]”, while with “width_shift_range=1.0” possible values are floats in the interval [-1.0, +1.0).
  • height_shift_range: Float, 1-D array-like or int
    • float: fraction of total height, if < 1, or pixels if >= 1.
    • ۱-D array-like: random elements from the array.
    • int: integer number of pixels from interval (-height_shift_range, +height_shift_range)
    • With “height_shift_range=2” possible values are integers [-1, 0, +1], same as with “height_shift_range=[-1, 0, +1]”, while with “height_shift_range=1.0” possible values are floats in the interval [-1.0, +1.0).

 

مثال زیر نشان می دهد که یک شیفت افقی با مقداردهی width_shift_range بین [۲۰۰, ۲۰۰-] چطور نوشته می شود و خروجی آن به چه شکل است. در مثال زیر از همان نمونه که نام فایل آن ‘bird.jpg’ بود استفاده کرده ایم

اجرای مثال بالا موجب می شود که یک شئ از  ImageDataGenerator با پیکربندی مشخصی ساخته شود و سپس با مشخص کردن اندازه دسته تصاویر و ساخت یک iterator تصاویر مختلف تولید کنید (و در صورت ایجاد یک شبکه یادگیری عمیق، آن را آموزش را انجام دهیم). گرفتن تصویر و نمایش در حلقه ای با ۹ تکرار انجام شده که به این ترتیب ۹ تصویر متفاوت داریم.

در ادامه همین مثال برای ایجاد شیفت های عمودی نوشته شده که آرگومان height_shift_range را با مقدار ۰.۵ مقداردهی می کند که یعنی تصویر می تواند تا ۵۰ درصد به بالا یا پایین شیفت بخورد.

اجرای این کد ۹ تصویر را ایجاد می کند که به اندازه حداکثر ۵۰ درصد به صورت مثبت یا منفی شیفت خورده اند.

همانطور که می بیند در تصویری که ما به عنوان نمونه داریم، تکرار پیکسل ها برای پر کردن بخش حذف شده از مقدار قبلی پیکسل ها، چندان غیرمنطقی به نظر نمی رسد اما اگر در کاربرد مسئله شما این موضوع باید تغییر کند، می بایست مقدار آرگومان “fill_mode” را مشخص کنید تا از مقدار پیشفرض استفاده نشود.

برگرداندن تصاویر از چپ به راست و بالا به پایین

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

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

در نمونه تصویر این آموزش برگردان افقی تصویر (چپ به راست) منطقی به نظر می رسد اما برگردان عمودی خیر؛ چرا که طوطی ها برعکس و روی هوا زندگی نمی کنند!!!

برای انواع دیگر تصاویر، مانند عکس های هوایی، کیهان شناسی و میکروسکوپی شاید برگردان عمودی (بالا به پایین) هم معنی پیدا کنند.

در مثال زیر با تعیین و مقداردهی horizontal_flip=True در سازنده شئ تعیین شده که به طور شانسی جهت برخی تصاویر را از چپ به راست معکوس کند.

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

تکنیک چرخش تصویر به مقدار تصادفی

فعال سازی تقویت دیتاست با چرخش و دوران تصاویر، به طور شانسی برخی از آن ها را در جهت عقربه های ساعت می چرخاند. سقف حداکثری زاویه  چرخشی که برای آن مشخص شده در سازنده شئ ImageDataGenerator تعیین می شود و آن سقف باید بین ۰ تا ۳۶۰ باشد.

چرخش موجب می شود برخی از پیکسل های اصلی از قاب تصویر خارج شوند و نیاز شود برخی دیگر قسمت ها با مقادیر جدیدی پر شوند که نوع تعیین مقدار با همان آرگومان fill_mode تعیین می شود که مقادیر محتمل برای آن و دیگر آرگومان های سازنده کلاس در این لینک آمده است.

در کد زیر با مقداردهی آرگومان rotation_range در سازنده کلاس، مشخص کرده ایم تصاویر را به طور شانسی بین ۰ تا ۹۰ درجه در جهت عقربه های ساعت، بچرخاند.

اجرای کد بالا نمونه تصاویر زیر را تولید می کند که برای پر کردن پیکسل های از دست رفته (جا به جا شده) مانند کدها و مثال های قبلی از حالت nearest-neighbor fill mode به طور پیش فرض استفاده شده است.

تکنیک تغییر روشنایی به مقدار تصادفی

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

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

اینها با تعیین مقدار برای آرگومان brightness_range در سازنده کلاس ImageDataGenerator فراهم می آید که مقدار این آرگومان باید tuple یا آرایه با دو مقدار اعشاری باشد؛ آن دو مقدار اعشاری میزان حداقل و حداکثر تغییرات را تعیین می کند.

مقادیر کمتر از ۱.۰ روشنایی تصویر را کمتر از ۱۰۰ درصد می کند پس تصویر تاریک می شود. بدیهی است که مقدار بالاتر از ۱.۰ هم تصویر را روشن تر می کند. مثلاً بازه ۰.۵ تا ۱.۰ تصویر را تاریک می کند، و بازه ۱.۰ تا ۱.۵ می تواند تا حداکثر ۵۰ درصد برخی تصاویر را روشن تر کند.

مثال زیر نشان می دهد که چطور می توان این تکنیک را به کار برد و روشنایی را بین ۱۰۰ تا ۲۰ درصد مقدار اصلی تنظیم کند (تصویر تا ۲۰ درصد ممکن است تاریک شود).

اجرای کد بالا تصاویر زیر را تولید می کند روشنایی آن ها بین ۱۰۰ تا ۲۰ درصد از مقدار اصلی به طور تصادفی تنظیم شده است.

تکنیک بزرگنمایی تصویر به اندازه تصادفی

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

مقدار آرگومان zoom_range که در سازنده کلاس ImageDataGenerator می بایست تعیین شود، می تواند فقط یک عدد اعشاری یا یک آرایه دو عددی برای تعیین بازه بزرگنمایی باشد.

اگر تنها یک عدد اعشاری داده شود، به طور خودکار به بازه تبدیل می شود (به شکل [lower, upper] = [1-zoom_range, 1+zoom_range] ).

مقادیر کمتر از ۱.۰ به معنای کوچک کردن تصویر است مثلاً [۰.۵,۰.۵] به طور قطع تمام تصاویر را ۵۰ درصد کوچک تر می کند و بازه [۱.۵, ۱.۵] همه تصاویر را ۵۰ درصد بزرگ می کند. و تعیین بازه به شکل [۱.۰,۱.۰] هم هیچ تاثیری در بزرگنمایی ندارد.

مثال زیر تصویر نمونه را به طور تصادفی تا حداکثر ۵۰ درصد کوچک می کند.

اجرای کد بالا تصاویر زیر را تولید کرده است (توجه داشته باشید که طول و عرض تصویر برابر نیستند و نسبت طول و عرض ۱:۱ نیست).

مطالعه بیشتر

می توانید برای مطالعه و یادگیری بیشتر API ها و مقاله موجود در لینک های زیر را مطالعه کنید.

API

Articles

خلاصه

در این آموزش شما با نحوه استفاده از data augmentation برای آموزش شبکه یادگیری عمیق با داده های بیشتر و متنوع تر آشنا شدید.

به طور دقیق تر، شما آموختید:

  • Image data augmentation را برای افزایش اندازه دیتاست استفاده کنید تا بهبود عملکرد شبکه یادگیری عمیق و تعمیم قدرت تشخیص اشیا حاصل شود.
  • Image data augmentation در کتابخانه Keras پشتیبانی می شود و در کلاس ImageDataGenerator پیاده سازی شده است.
  • نحوه استفاده از شیفت، معکوس کردن (برگرداندن)، چرخش، تغییر روشنایی و بزرگنمایی تصاویر مرور شد.

 

در ضمن مرجع اصلی این مطلب مقاله زیر است:

How to Configure Image Data Augmentation in Keras

 

در پایان، اگر سوالی دارید حتماً در بخش نظرات بپرسید.

 

 

نظرتان را برای ما بنویسید

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