اذهب إلى المحتوى
  • 0

تطبيق تقنية ال BatchNormalization في كيراس Keras

Chollet ML

السؤال

Recommended Posts

  • 1

هي القيام بعملية تقييس "Scaling" للبيانات ضمن الطبقات الخفية للشبكات العصبونية. اعتدنا دوماً أن نقوم بعملية تقييس لبيانات الدخل بحيث نجعلها تنتمي إلى "Range" معين. مثلاً في الصور كنا نقسم كل البكسلات على 255 بحيث تصبح قيم البكسلات بين ال0 و1. وهذا ماكان يؤدي إلى تحسين أداء النموذج من ناحية السرعة والدقة والتعميم. لكن ماذا عن الطبقات الخفية.
يمكننا القيام بعملية تقييس للبيانات في الطبقات الخفية (قيم ال z أو قيم ال acttivations لكن غالباً مايطبق على z وهذا أفضل عموماً).  وهذا ماسيجعل النموذج يتدرب بشكل أسرع إضافة إلى جعله قادراً على التعميم بشكل أكبر . وتمنحه القدرة على حل مشكلة ال Convariate shift (أي إذا قمنا  بالربط بين المدخلات x والمخرجات y  أي دربنا نموذج للقيام بذلك ) فإن اختلاف توزيع x (الشكل الذي تتوزع به البيانات أي بمعنى آخر مجالات القيم) سيؤدي إلى اختلافات كبيرة في قيم z (أو قيم ال activations) في الطبقات الخفية، وهذ ماسينتج عنه نتائج مختلفة جداً تماماً كمبدأ (أثر الفراشة حيث تؤدي التغيرات البسيطة في البداية إلى أحداث كبيرة لاحقاً).  على سبيل المثال إذا كان نموذجك مدرباً على صور قطط سوداء وبيضاء فقط (توزيع بيانات محدد) وقمت باختباره على قطط ملونة (توزيع مختلف) سيؤدي إلى ظهور نتائج غير صحيحة.. لن أدخل بتفاصيل أكثر.. وتظهر هذه المشكلة عموماً في الشبكات العصبية الكبيرة مثلاً مثل شبكة AlexNet. لذا سأقوم بعرض مثال عليها وكيف نطبق ال Batch Normlaization عليها في كيراس، بعد قليل.
هذه التقنية تعتمد على حساب متوسط مجموع قيم z للطبقة المطبق عليها أي حساب ال mean. ثم حساب ال variance (متوسط مجموع مربعات الفروق بين قيم z وال mean). ثم حساب مايسمى znorm  وتساوي (قيمة z مطروحاً منها قيمة ال mean) والناتج مقسوم على جذر ال variance مضافاً له قيمة متناهية في الصغر تسمى epsilon لتجنب حالة انعدام المقام وبالتالي القسمة على صفر. ثم بعد ذلك حساب قيمة مايسمى ztelde وتساوي قيمة znorm مضروبة بغاما ومضاف لها قيمة بيتا. وهي التي تمثل القيمة النهائية (أي أن ztelde هي القيمة التي سنستبدل بها قيمة z الأصلية). إليك الشكل الرياضي للفكرة، حيث m عدد العينات:Untitled.thumb.png.a416e7ca69ad40810d81858deaf5e731.png
لاحظ أنه كلما ابتعدت قيم غاما وبيتا عن القيم المشار لها في الأعلى يزاد ال normlaize. وكلما اقتربت منها يقل التأثير. الآن قد يتبادر لأذهاننا كيفية اختيار قيم غاما وبيتا والإجابة هي أننا نختارهما بقيم عشوائية لأن الشبكة العصبية تعاملهما معاملة الأوزان وبالتالي تقوم بتعديل قيمهما من خلال خوارزمية الانتشار الخلفي كما تراه مناسباً. أي يتم اعتبارهما learnable parameters. وأي خوارزمية تحسين (adam أو momentum أو  rmsprop أو غيرهم..) تقوم بتحديث قيمهم بنفس الطريقة التي تحدث فيها قيم الأوزان. وتجدر الملاحظة إلى أنه لايجب علينا استخدام هذه التقنية مع طبقة الدخل لأن أثرها سيكون سلبي (لأنها تجعل قيم ال mean=0 وال variance=1 ).
وأيضا عند تطبيقه لايوجد داع لاستخدام قيم لل bias  لأن beta ستفي بالغرض. كما تجدر الملاحظة إلى أن هذه التقنية تضيف نوعا ً من التنعيم للنموذج. لأنه مع كل mini batch يتم حساب mean و variance مختلفين وهذا يضيف نوعاً من التنعيم للنموذج بشكل مشابه لل dropout. الآن يجب أن تعلم أنه عند تطبيق هذه التقنية فإنه يتم حساب ال mean و variance لكل minibatch بشكل منفصل. أي أن كل ميني باتش سيتبع توزيعاً مختلفاً قليلاً عن الآخر تبعاً لاختلافهما. وهنا يظهر ليدنا السؤال التالي، كيف سيتم اختبار قيمهما في وقت الاختبار؟
تكون قيم ال mean و ال variance المستخدمة في وقت الاختبار هي القيمة النهائية المقدرة لهم خلال التدريب  اعتماداً على فكرة المتوسطات الأسية الموزونة EWA ويكون ال Average عبر كل ال minibatches  وهذه الطريقة تسمى running aveeage. فقيم ال mean وال variance تكون مختلفة من mini batch إلى آخر في وقت التدريب وبالتالي نحتاج لقيمة محددة نستخدمها خلال الاختبار  لأنه في وقت الاختبار قد لايكون لديك سوى عينة واحدة فقط وبالتالي حساب ال mean وال variance ليس له معنى .. لذا يجب تحديد قيمة لهم مسبقاً خلال مرحلة التدريب.ليكون عملك فعالاً وصحيحاً. بشكل عام التفاصيل الدقيقة الأخرى لاتهمك كثيراً عند استخدام إطارات العمل فكل هذه التفاصيل تكون تلقائية لكن يهمنا فهم الفكرة العامة. لكي نعرف ماذا نقوم به (لكي لاتكون ببغاءاً في هذا المجال وفاقداً للإبداع في استخدام اطارات العمل). الآن لنرى شكلها العام:

tf.keras.layers.BatchNormalization(
    axis=-1,
    momentum=0.99,
    epsilon=0.001,
    center=True,
    scale=True,
    beta_initializer="zeros",
    gamma_initializer="ones",
    moving_mean_initializer="zeros",
    moving_variance_initializer="ones",
    beta_regularizer=None,
    gamma_regularizer=None,
    beta_constraint=None,
    gamma_constraint=None,
)

في كيراس لها الشكل الجميل السابق حيث تضاف للنموذج كطبقة. وطبعاً كلها ستكون واضحة لك الآن بعد الشرح السابق. الوسيط epsilon تحدثنا عنه (منع القسمة على صفر)، الوسيطين beta_initializer و gamma_initializer يحددان الطريقة التي سيتم تهيئة قيمهما فيها (أيضاً تحدثنا عنهم) لكن لاحظ أنه إياك أن تقوم بتهيئة غاما بصفر فالشبكة ستتعطل. الوسيطين moving_mean_initializer و moving_variance_initializer و momentum هم  الوسطاء الخاصين بال EWA فأول وسيطين هما قيم التهيئة والمومنتوم لها، حيث يتم تحديث قيم الmean وال variance من خلال المعادلات:

moving_mean = moving_mean * momentum + mean(batch) * (1 - momentum)
moving_var = moving_var * momentum + var(batch) * (1 - momentum)

أما بالنسبة للوسيط center ففي حالة وضعه على False سيقوم بإلغاء ال beta (هنا لابد من إضافة ال bias للأوزان). أما ال scale ففي حال وضع False سيتم إلغاء استخدام غاما. أما gamma_regularizer و beta_regularizer فهما لتحديد فيما إذا أردت تطبيق تنعيم عليهم أم لا.الوسيط beta_constraint و gamma_constraint هما قيد اختياري لوزن جاما أو بيتا. وأخيراً axis وهي المحور الذي سيتم تطبيق ال normlaize عليه (عادةً محور ال Features).
الآن يجب أن نعلم أنه خلال التدريب يتم تطبيق ال normlaize بناءان على قيم ال mean و ال var للباتش الحالي. أي:

gamma * (batch - mean(batch)) / sqrt(var(batch) + epsilon) + beta

أما عند الاختبار يتم تطبيقه بناءان على قيم ال mean وال var الذي تم حسابهما خلال مرحلة التدريب اعتماداً على الفكرة التي شرحتها. أي:

gamma * (batch - self.moving_mean) / sqrt(self.moving_var + epsilon) + beta.

أيضاً هناك وسيط آخر لم يذكر في توثيق كيراس لكن يمكن تمريره وهو training ويأخذ إما True أو False ففي حال وضعه على True فهذا يعني أنك الآن في وضع التدريب وبالتالي قيم ال mean وال var تحسب على أساس الباتش الحالي، أما وضعه على false فيعني أنك تحسب على أساس المتوسطات الأسية سالفة الذكر. (افتراضياً يقوم كيراس بضبط هذه الأمور بالشكل الصحيح لذا ربما بم توضع فهو يفهم من تلقاء نفسه أن استدعاء fit يعني أننا في طور التدريب وبالتالي يكون الوسيط مضبوط على true أما عند استخدام evaluate أو pridect فهو يفهم أنك في طور التدريب أي يجعله false). وفي كيراس يطبق على قيم ال Activation. الآن سنضع المثال حيث يتم إضافتها في النموذج كطبقة، مثلاً كان لدينا طبقة Dense وبالتالي إذا وضعنا بعدها طبقة batchnorm فهذا يعني أنه سيتم تطبيق تقنية ال batcjhnorm عليها.المثال التالي يمثل شبكة ALEXNET المشهورة:

#Importing library
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
import numpy as np
np.random.seed(1000)
#Instantiation
AlexNet = Sequential()
#1st Convolutional Layer
AlexNet.add(Conv2D(filters=96, input_shape=(100,100,3), kernel_size=(11,11), strides=(4,4), padding='same'))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))
AlexNet.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))

#2nd Convolutional Layer
AlexNet.add(Conv2D(filters=256, kernel_size=(5, 5), strides=(1,1), padding='same'))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))
AlexNet.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))

#3rd Convolutional Layer
AlexNet.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='same'))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))

#4th Convolutional Layer
AlexNet.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='same'))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))

#5th Convolutional Layer
AlexNet.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='same'))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))
AlexNet.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))

#Passing it to a Fully Connected layer
AlexNet.add(Flatten())

# 1st Fully Connected Layer
AlexNet.add(Dense(2000, input_shape=(32,32,3,)))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))
# Add Dropout to prevent overfitting
AlexNet.add(Dropout(0.4))

#3rd Fully Connected Layer
AlexNet.add(Dense(512))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('relu'))
#Add Dropout
AlexNet.add(Dropout(0.4))

#Output Layer
AlexNet.add(Dense(1))
AlexNet.add(BatchNormalization()) # هنا
AlexNet.add(Activation('sigmoid'))

#Model Summary
AlexNet.summary()
AlexNet.compile(optimizer="adam",loss="binary_crossentropy",metrics=["accuracy"])

#Ali Ahmed is where there is machine learning

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1

تعد Batch Normalization مجرد طبقة ، لذا يمكنك استخدامها على  النحو لإنشاء بنية الشبكة التي تريدها.

حالة الاستخدام العامة هي استخدام Batch Normalization بين الطبقات الخطية وغير الخطية في الموديل الخاص بك ، لأنها تقوم بعمل Normalize للدخل إلى دالة التنشيط ، بحيث تكون متمركزًا في القسم الخطي لدالة التنشيط (مثل Sigmoid). 

وتقوم بشكل اساسي على تحويل بحيث يصبح متوسط الخرج قريبا من 0 والانحراف قريبا من 1.

استخدم Batch Normalization بين الطبقات التلافيفية convolutional layers  وغير الخطية ، مثل طبقات ReLU ، لتسريع تدريب الشبكات العصبية التلافيفية وتقليل تاثر الموديل بالقيم الابتدائية له والتي يتم تعيينها بشكل عشوائي.

يمكنك استخدامها كطبقة من طبقات التعلم كالتالي:


from keras.layers.normalization import BatchNormalization


model = Sequential()


model.add(Dense(64, input_dim=14, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('tanh'))
model.add(Dropout(0.5))
   
model.add(Dense(64, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('tanh'))
model.add(Dropout(0.5))


model.add(Dense(2, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('softmax'))


sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)


model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2)

 

تم التعديل في بواسطة Ahmed Sharshar
رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...