• 0

كيف نقوم بتطبيق التوقف المبكر early stopping في كيراس Keras و تنسرفلو Tensorflow

كيف يمكنني أن أجعل النموذج يتوقف عندما تتوقف دالة التكلفة عن الانخفاض؟ أو بمعنى آخر كيف يمكننا تطبيق مفهوم التوقف المبكر؟

انشر على الشّبكات الاجتماعية


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

يدعم Keras الإيقاف المبكر للتدريب عن طريق callback يسمى EarlyStopping. ويسمح لنا بتحديد مقياس الأداء الذي نريد أن تتم مراقبته، ليتم إيقاف التدريب عند توقف هذا المقياس عن التحسن.(مثلاً عندما تتوقف ال validation accuracy  عن التحسن يقوم النموذج بإيقاف التدريب تلقائياً). تعتمد فكرته على أنه طالما مازالت قيمة المعيار تتحسن سنستمر بالتدريب وبمجرد توقفها عن التحسن (أي تراجعت قيمتها مثلاً في حالة اخترنا المقياس Accuracy وكانت دقة التدريب في مرحلة ما 0.8 ثم في ال epoch التالي تراجعت قيمته لل 0.79 ستم إيقاف التدريب وهنا ستظهر لنا مشكلة سأتحدث عنها في *) .إن استخدام تكنيك التوقف المبكر يتطلب أن يكون لديك validation_data قمت بتحديدها مسبقاً لأننا نطبقه على أساس قيمها وإلا لن يكون لاستخدامه معنى. وكما تعلم هناك طريقتين لنقوم بتحديد ال validation الأولى بأن نحددها من خلال قسم جزء من داتا التدريب باستخدام الوسيطة validation_split:

model.fit(train_X, train_y, validation_split=0.3)

أو أن تكون لدينا بيانات جاهزة:

model.fit(train_X, train_y, validation_data=(val_x, val_y))

يتم تكوين ال EarlyStopping عند إنشاء غرض منه وتمريره للوسيطة callback في الدالة fit. ومن خلال الوسيطة "monitor" نقوم بتحديد مقياس الأداء المراد مراقبته من أجل إنهاء التدريب:

es = EarlyStopping(monitor='val_loss')

بناءً على اختيار مقياس الأداء، يجب تحديد وسيطة "mode" وذلك لتحديد فيما إذا كان الهدف من المقياس المختار هو الزيادة (التكبير أو "الحد الأقصى") أو تقليله (تقليل أو "الحد الأدنى"). على سبيل المثال، سنسعى للحصول على حد أدنى لل validation loss، بينما سنسعى إلى الحد الأقصى لل val_acc.

es = EarlyStopping(monitor='val_loss', mode='min')

بشكل افتراضي ، يتم تعيين الوضع على "auto" وسيعرف أنك تريد التقليل في حالة ال loss أو زيادة الدقة إلى أقصى حد في حالة ال accuracy.
وإذا أردت طباعة رقم ال epoch الذي توقف عنده التدريب فقط نضبط verbose على 1.

es = EarlyStopping(monitor='val_loss', mode='min', verbose=1)

الآن سأتحدث عن المشكلة التي أشرت لها في *، وهي "كانت دقة التدريب في مرحلة ما 0.8 ثم في ال epoch التالي تراجعت قيمته لل 0.79 ستم إيقاف التدريب" في هكذا حالة فإن إيقاف التدريب سيكون أمر خاطئ لأنه ربما في الحقبتين التاليتين سيعود للتحسن وبشكل كبير جداً، أي قد يكون النموذج قد وقع مثلاً في قيمة صغرى محلية ويحتاج للصبر قليلاً لكي يخرج منها ثم يعود للتحسن، وهنا يأتي دور الوسيطة patience والتي تمثل "الصبر" أي أصبر عليها لفترة محددة إذا لم تتحسن توقف:

es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=4)
# epoch هنا سينتظر 4 

أخيرًا ، قد يكون من المستحسن التوقف عن التدريب فقط إذا ظل الأداء أعلى أو أقل من عتبة معينة أو خط أساس معين. على سبيل المثال ، إذا كان لديك إلمام بتدريب النموذج (مثل منحنيات التعلم) وتعلم أنه بمجرد تحقيق validation loss بقيمة معينة ، فلا فائدة من استمرار التدريب. يمكن تحديد ذلك عن طريق تعيين وسيطة "baseline".

es = EarlyStopping(monitor='val_loss', mode='min', baseline=0.4)

مثال كامل:

from sklearn.datasets import make_moons
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
from matplotlib import pyplot
from keras.models import load_model
# توليد بيانات ثنائية الأبعاد للتجربة عليها
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)
# split into train and test
n_train = 30
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
# define model
model = Sequential()
model.add(Dense(500, input_dim=2, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# simple early stopping
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=200)
# لحفظ أفضل نتيجة حصلنا عليها خلال التدريب
mc = ModelCheckpoint('best_model.h5', monitor='val_accuracy', mode='max', verbose=1, save_best_only=True)
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0, callbacks=[es, mc])
# load the saved model
saved_model = load_model('best_model.h5')
# evaluate the model
_, train_acc = saved_model.evaluate(trainX, trainy, verbose=0)
_, test_acc = saved_model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))

 

1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


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

يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن