Pooling و Memory در CNN | Padding، Stride و معماری پایه

Padding و Stride، Memory، Pooling و معماری پایه CNN

توسط admin | گروه هوش مصنوعی | 1405/06/01

نظرات 0

Padding و Stride، Memory، Pooling و معماری پایه CNN

کتاب
Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow
بخش منبع
Padding and Strides; Memory Requirements; Pooling Layers; Implementing Pooling with Keras; CNN Architectures; Basic Fashion MNIST CNN
صفحات این PDF
87-95
صفحات چاپی کتاب
489-497
جایگاه در مجموعه
بخش ۵۵ از مجموعهٔ Machine_Learning_405_06؛ مادر: Machine_Learning_405_06_01.html

Padding، Stride و اندازهٔ Output در Conv2D

دو حالت رایج Padding در Keras عبارت‌اند از valid و same. در حالت valid هیچ Zero Padding اضافه نمی‌شود؛ در same تا حد امکان Spatial Size حفظ می‌شود. وقتی Stride بزرگ‌تر از ۱ است حتی Same Padding Output کوچک‌تر می‌شود، چون Window با Step بزرگ‌تری حرکت می‌کند.

مقایسه valid و same padding در convolution
شکل 14-7. دو گزینهٔ Padding با Stride برابر ۱
مقایسه خروجی convolution با stride دو و padding متفاوت
شکل 14-8. کوچک شدن Output با Stride بزرگ‌تر از ۱

اگر بخواهیم اندازهٔ خروجی را دقیق محاسبه کنیم، برای padding="valid" و عرض ورودی iw، عرض خروجی برابر است با (iw - fw + sw) / sw که به پایین گرد می‌شود؛ باقی‌ماندهٔ تقسیم به ستون‌هایی در سمت راست ورودی مربوط است که نادیده گرفته می‌شوند. همین منطق برای ارتفاع نیز برقرار است. در padding="same" عرض خروجی برابر iw / sw است که به بالا گرد می‌شود. اگر عرض خروجی را ow بنامیم، تعداد ستون‌های صفر لازم برای Padding برابر (ow - 1) × sw + fw - iw است و Keras آن‌ها را تا حد امکان متقارن در دو طرف قرار می‌دهد.

Weightهای Conv2D نیز مانند Dense Layer از طریق weights یا get_weights() قابل‌دسترسی‌اند. در مثال کتاب، Layer دارای ۳۲ Filter هفت‌درهفت روی Input سه‌کاناله است:

kernels, biases = conv_layer.get_weights()
print(kernels.shape)  # (7, 7, 3, 32)
print(biases.shape)   # (32,)

آرایهٔ Kernel چهار‌بعدی است و Shape آن [kernel_height, kernel_width, input_channels, output_channels] است؛ Bias نیز Vector یک‌بعدی با طول output_channels است. Height و Width خود Image در Shape Kernel ظاهر نمی‌شوند، زیرا همهٔ Neuronهای هر Feature Map همان Weightها را Share می‌کنند. در نتیجه همین Layer می‌تواند Imageهایی با اندازه‌های Spatial متفاوت را پردازش کند، به شرط آنکه Image از Kernel کوچک‌تر نباشد و تعداد Channelها با Layer سازگار باشد.

از آنجا که Convolution ذاتاً Operation خطی است، معمولاً همراه آن Activation Function مانند ReLU و Initializer متناسب، مانند He Initialization، تعیین می‌شود؛ Stack کردن چند Convolution بدون Nonlinearity در نهایت همچنان یک Transformation خطی خواهد بود. Conv Layer Hyperparameterهای زیادی دارد: تعداد Filterها، Kernel Size، Stride، Padding، Activation، Initializer و Regularizer/Constraint. Cross-Validation می‌تواند برای تنظیم آن‌ها استفاده شود، اما جست‌وجوی گسترده بسیار زمان‌بر است؛ به همین دلیل معماری‌های استاندارد بخش‌های بعدی نقطهٔ شروع عملی خوبی فراهم می‌کنند.

نیاز حافظه در CNN

Convolutional Layerها علاوه بر Weightها، Activationهای بزرگ تولید می‌کنند. مثال عددی کتاب این هزینه را روشن می‌کند: Layerای با ۲۰۰ Filter پنج‌درپنج، stride=1 و padding="same" را روی یک Image رنگی 150×100 در نظر بگیرید. تعداد Parameterها فقط (5×5×3 + 1) × 200 = 15,200 است؛ عددی نسبتاً کوچک در مقایسه با Fully Connected Layer هم‌اندازه. با این حال هر یک از ۲۰۰ Feature Map دارای 150×100 Neuron است و هر Neuron مجموع Weightدار 5×5×3 = 75 Input را محاسبه می‌کند؛ در مجموع حدود ۲۲۵ میلیون ضرب Float برای یک Forward Pass همین Layer لازم است.

اگر Feature Mapها با Float32 ذخیره شوند، Output این Layer برای فقط یک نمونه 200×150×100×32 = 96,000,000 بیت، یعنی حدود ۱۲ MB RAM اشغال می‌کند. با Batch شامل ۱۰۰ نمونه، تنها Output همین Layer تقریباً ۱٫۲ GB حافظه می‌خواهد. این مثال نشان می‌دهد که تعداد Parameter پایین لزوماً به معنی Memory Cost پایین نیست؛ Activationها می‌توانند بخش اصلی مصرف حافظه باشند.

در Inference، Memory اشغال‌شده توسط یک Layer را می‌توان به‌محض محاسبهٔ Layer بعدی آزاد کرد، بنابراین تقریباً حافظهٔ دو Layer متوالی به‌اضافهٔ Weightها کافی است. اما در Training همهٔ مقدارهای میانی Forward Pass باید تا Reverse Pass نگه داشته شوند تا Gradientها محاسبه شوند، در نتیجه RAM موردنیاز دست‌کم مجموع حافظهٔ Activationهای Layerهای مختلف است.

طبق پیشنهاد متن منبع، اگر Training به خطای Out-of-Memory برخورد کرد، اولین گزینه کاهش Mini-Batch Size است. گزینه‌های دیگر عبارت‌اند از کاهش ابعاد با Stride، حذف چند Layer، استفاده از Float16 به‌جای Float32، یا توزیع CNN روی چند Device. این‌ها راهکارهایی هستند که خود متن فصل برای این مثال ذکر می‌کند.

Pooling Layerها

Pooling Layer برای Subsampling استفاده می‌شود: Spatial Dimension را کاهش می‌دهد، Compute و Memory را پایین می‌آورد و مقداری Invariance نسبت به Translationهای کوچک ایجاد می‌کند. Max Pooling معمولاً با Window کوچک، مثلاً ۲×۲، و Stride ۲ اجرا می‌شود. هر Neuron فقط بیشترین مقدار داخل Receptive Field را برمی‌گرداند و Parameter قابل‌Train ندارد.

نمونهٔ انتخاب بیشینه از Receptive Fieldهای pooling
شکل 14-9. Max Pooling با Kernel دو در دو و Stride دو

Max Pooling مقدار دقیق Position را تا حدی نادیده می‌گیرد. اگر Feature کمی جابه‌جا شود اما همچنان در همان Window قرار گیرد، Output Pooling ممکن است ثابت بماند. این خاصیت در Classification تصویر مفید است، چون Object باید با جابه‌جایی کوچک همچنان شناسایی شود.

اثر max pooling بر ثبات خروجی در برابر translation کوچک
شکل 14-10. Invariance نسبت به جابه‌جایی‌های کوچک

Average Pooling به‌جای Max میانگین Window را می‌گیرد. در بیشتر CNNهای مدرن Max Pooling برای Featureهای محلی رایج‌تر بوده، هرچند در Architectureهای جدید گاهی Convolution Strided یا Global Average Pooling جای آن را می‌گیرد.

Pooling در عمق و Global Average Pooling

Pooling معمولاً روی Height/Width انجام می‌شود و Depth را تغییر نمی‌دهد، اما می‌توان Pooling را در Dimension Channel نیز تصور کرد. Depthwise Max Pooling می‌تواند بعضی Invarianceها را میان Feature Mapهای مشابه ایجاد کند.

Pooling در عمق Feature Mapها برای یادگیری invariance
شکل 14-11. Depthwise Max Pooling و Invariance

در Keras:

max_pool = tf.keras.layers.MaxPool2D(pool_size=2)
avg_pool = tf.keras.layers.AveragePooling2D(pool_size=2)
global_avg_pool = tf.keras.layers.GlobalAveragePooling2D()

GlobalAveragePooling2D برای هر Feature Map میانگین تمام Pixelهای Spatial را می‌گیرد و Tensor [batch, height, width, channels] را به [batch, channels] تبدیل می‌کند. این کار اغلب پیش از Output Layer در CNNهای مدرن استفاده می‌شود و تعداد Parameter را نسبت به Flatten + Dense به‌شدت کاهش می‌دهد.

معماری معمول CNN

یک CNN کلاسیک چند Block از Convolution + Activation دارد، گاهی پس از چند Conv یک Pooling Layer اضافه می‌شود، Depth Feature Mapها به‌تدریج زیاد و Spatial Size کم می‌شود. در پایان، Featureهای سطح بالا وارد Dense/Output Layer می‌شوند.

ترتیب Convolution، Pooling و Fully Connected در CNN کلاسیک
شکل 14-12. معماری معمول CNN

مثال ساده برای Fashion MNIST:

from functools import partial

DefaultConv2D = partial(
    tf.keras.layers.Conv2D,
    kernel_size=3, padding="same",
    activation="relu", kernel_initializer="he_normal")

model = tf.keras.Sequential([
    tf.keras.layers.Reshape([28, 28, 1], input_shape=[28, 28]),
    DefaultConv2D(filters=64, kernel_size=7),
    tf.keras.layers.MaxPool2D(pool_size=2),
    DefaultConv2D(filters=128),
    DefaultConv2D(filters=128),
    tf.keras.layers.MaxPool2D(pool_size=2),
    DefaultConv2D(filters=256),
    DefaultConv2D(filters=256),
    tf.keras.layers.MaxPool2D(pool_size=2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation="relu",
                          kernel_initializer="he_normal"),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(64, activation="relu",
                          kernel_initializer="he_normal"),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(10, activation="softmax")
])

Convolutionهای ابتدایی Featureهای سطح پایین را Extract می‌کنند، Layerهای عمیق‌تر Featureهای پیچیده‌تر را می‌سازند، Pooling Spatial Size را کاهش می‌دهد و Dense Layerهای انتهایی Classification را انجام می‌دهند. در Practice برای Imageهای بزرگ‌تر، Architectureهای مدرن معمولاً از Batch Normalization، Skip Connection، Global Average Pooling و Blockهای تخصصی استفاده می‌کنند.

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

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

0 / 500

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620