שכבת נורמליזציה של אצווה של Keras היא אינטליגנציה של PlatoBlockchain Data שבורה. חיפוש אנכי. איי.

שכבת הנורמליזציה של אצווה נשברת

עדכון: למרבה הצער בקשת המשיכה שלי ל- Keras ששינתה את התנהגות שכבת הנורמליזציה לא התקבלה. תוכלו לקרוא את הפרטים כאן. לאלו מכם שאמיצים מספיק להתעסק עם יישומים בהתאמה אישית, תוכלו למצוא את הקוד ב הסניף שלי. אני יכול לתחזק אותו ולמזג אותו עם הגרסה האחרונה היציבה של Keras (2.1.6, 2.2.2 ו 2.2.4) כל עוד אני משתמש בו אך אין הבטחות.

רוב האנשים שעובדים בלמידה עמוקה השתמשו או שמעו עליהם קרס. לאלו מכם שלא, זוהי ספרייה נהדרת המופשטת את המסגרות הבסיסיות של Deep Learning כמו TensorFlow, Theano ו- CNTK ומספקת ממשק API ברמה גבוהה לאימוני ANNs. זה קל לשימוש, מאפשר אב טיפוס מהיר ויש לו קהילה פעילה ידידותית. אני משתמש בו בכבדות ותורם לפרויקט מעת לעת לא מעט זמן ואני בהחלט ממליץ עליו לכל מי שרוצה לעבוד על למידה עמוקה.

למרות שקרס הקל על חיי, פעמים רבות די ננשכתי מהתנהגות משונה של שכבת הנורמליזציה. התנהגות ברירת המחדל שלה השתנתה לאורך זמן, עם זאת היא עדיין גורמת לבעיות למשתמשים רבים וכתוצאה מכך ישנם מספר קשורים זה לזה בעיות פתוחות על גיטוב. בפוסט בבלוג זה אנסה לבנות מקרה מדוע שכבת BatchNormalization של קרס לא משחקת יפה עם Transfer Learning, אני אספק את הקוד שמתקן את הבעיה ואני אתן דוגמאות עם התוצאות של תיקון.

בחלקים הבאים להלן, אני מביא מבוא כיצד משתמשים בלמידה בהעברה בלמידה עמוקה, מהי שכבת הנורמליזציה של אצווה, כיצד פועלת learningining_phase ואיך Keras שינה את התנהגות BN לאורך זמן. אם אתה כבר יודע את אלה, אתה יכול לקפוץ בבטחה ישירות לסעיף 2.

1.1 השימוש בלמידה העברה הוא קריטי למידה עמוקה

אחת הסיבות לכך שנמתחה ביקורת בעבר על Deep Learning היא שהיא דורשת יותר מדי נתונים. זה לא תמיד נכון; ישנן כמה טכניקות לטיפול במגבלה זו, אחת מהן היא לימוד העברות.

נניח שאתה עובד על יישום מחשב ראייה ואתה רוצה לבנות מסווג המבדיל חתולים מכלבים. כדי לא לאמן את המודל בפועל אינך זקוק למיליוני תמונות חתול / כלב. במקום זאת תוכלו להשתמש בסיווג שהוכשר מראש ולכוונן את המהמורות העליונות עם פחות נתונים. הרעיון שעומד מאחוריו הוא שמכיוון שהמודל שהוכשר מראש היה כשיר לתמונות, התפתלויות התחתונות יכולות לזהות תכונות כמו קווים, קצוות ודפוסים שימושיים אחרים, כלומר אתה יכול להשתמש במשקולותיו כערכי אתחול טובים או להכשיר את הרשת באופן חלקי עם הנתונים שלך .
שכבת נורמליזציה של אצווה של Keras היא אינטליגנציה של PlatoBlockchain Data שבורה. חיפוש אנכי. איי.
Keras מגיע עם מספר דגמים שהוכנו מראש ודוגמאות קלות לשימוש כיצד לכוונן דגמים. אתה יכול לקרוא עוד בנושא תיעוד.

1.2 מהי שכבת הנורמליזציה של אצווה?

שכבת הנורמליזציה הוצגה בשנת 2014 על ידי Ioffe ו- Szegedy. היא מטפלת בבעיית הדרגתיות שנעלמת על ידי סטנדרטיזציה של תפוקת השכבה הקודמת, היא מזרזת את האימון על ידי צמצום מספר האיטרציות הנדרשות והיא מאפשרת הכשרה של רשתות עצביות עמוקות יותר. ההסבר כיצד זה עובד בדיוק מעבר לתחום של פוסט זה, אך אני ממליץ לך בחום לקרוא את ההודעה דף מקורי. הסבר מפושט יתר הוא שהוא ממיין מחדש את הקלט על ידי חיסור הממוצע שלו ועל ידי חלוקה עם סטיית התקן שלו; זה יכול גם ללמוד לבטל את השינוי במידת הצורך.
שכבת נורמליזציה של אצווה של Keras היא אינטליגנציה של PlatoBlockchain Data שבורה. חיפוש אנכי. איי.

1.3 מהו שלב הלמידה בכרס?

שכבות מסוימות פועלות בצורה שונה במהלך אימונים ומצב הסקה. הדוגמאות הבולטות ביותר הן שכבת הנורמליות ושכבות הנשירה. במקרה של BN, במהלך האימונים אנו משתמשים בממוצע ובשונות של המיני אצווה כדי לשנות מחדש את הקלט. מצד שני, במהלך ההסקה אנו משתמשים בממוצע נע ובשונות שהוערכו במהלך האימונים.

קרס יודע באיזה מצב לרוץ מכיוון שיש לו מנגנון מובנה הנקרא שלב למידה. שלב הלמידה שולט אם הרשת נמצאת ברכבת או במצב בדיקה. אם המשתמש לא מוגדר באופן ידני, במהלך ההתאמה () הרשת פועלת עם learning_phase = 1 (מצב הרכבת). תוך כדי הפקת חיזויים (למשל כאשר אנו מכנים את שיטות החיזוי () והערכה () או בשלב האימות של ההתאמה ()) הרשת פועלת עם learning_phase = 0 (מצב בדיקה). למרות שזה לא מומלץ, המשתמש יכול גם לשנות את שלב הלמידה באופן סטטי לערך ספציפי אך זה צריך לקרות לפני שמתווסף גרף כל מודל או טנסור. אם שלב הלמידה מוגדר באופן סטטי, Keras יינעל בכל מצב שהמשתמש בחר בו.

1.4 כיצד יישם Keras נורמליזציה של אצווה לאורך זמן?

Keras שינה את התנהגות נורמליזציה של אצווה מספר פעמים אך העדכון המשמעותי האחרון התרחש ב- Keras 2.1.3. לפני v2.1.3 כששכבת BN הוקפאה (ניתנת להדרכה = שקר) היא המשיכה לעדכן את סטטיסטיקות האצווה שלה, דבר שגרם לכאבי ראש אפיים למשתמשים שלה.

זו לא הייתה סתם מדיניות משונה, אלא שהיא הייתה שגויה. תאר לעצמך שקיימת שכבה של BN בין התפתלויות; אם השכבה קפואה לא צריכים לקרות לה שינויים. אם אנו מעדכנים באופן חלקי את משקולותיו והשכבות הבאות גם קפואות, הן לעולם לא יקבלו הזדמנות להסתגל לעדכונים של סטטיסטיקות המיני אצווה המובילות לטעות גבוהה יותר. למרבה המזל החל מגירסה 2.1.3, כאשר שכבת BN קפואה היא כבר לא מעדכנת את הסטטיסטיקה שלה. אבל האם זה מספיק? לא אם אתה משתמש בהעברת למידה.

להלן אני מתאר בדיוק מה הבעיה ואני משרטטת את היישום הטכני לפיתרון. אני גם מספק כמה דוגמאות להראות את ההשפעות על דיוק המודל לפני ואחרי תיקון מוחל.

2.1 תיאור טכני של הבעיה

הבעיה ביישום הנוכחי של Keras היא שכאשר קפואה של שכבת BN היא ממשיכה להשתמש בסטטיסטיקה של מיני אצווה במהלך האימונים. אני מאמין שגישה טובה יותר כאשר ה- BN קפוא היא להשתמש בממוצע ובשונות הנעים שלמד במהלך האימונים. למה? מאותן סיבות מדוע אין לעדכן את סטטיסטיקת המיני אצווה כאשר הקפאה של השכבה: זה יכול להוביל לתוצאות גרועות מכיוון שהשכבות הבאות אינן מאומנות כראוי.

נניח שאתה בונה מודל Vision Computer אבל אין לך מספיק נתונים, אז אתה מחליט להשתמש באחת ה- CNNs שהוכשרו מראש של Keras ולהתאים אותו בצורה עדינה. למרבה הצער, בכך אינך מקבל התחייבות לכך שהממוצע והשונות של מערך הנתונים החדש שלך בשכבות BN יהיו דומים לאלה של המערך המקורי. זכור שכרגע במהלך האימונים הרשת שלך תמיד תשתמש בסטטיסטיקות של מיני אצווה או ששכבת BN קפואה או לא; גם במהלך ההסקה תשתמש בסטטיסטיקה שנלמדה בעבר של שכבות ה- BN הקפואות. כתוצאה מכך, אם תתכוונן את השכבות העליונות, משקולותיהן יותאמו לממוצע / שונות של ה- חדש מערך נתונים. אף על פי כן, במהלך ההסיקות הם יקבלו נתונים המוגדלים באופן שונה בגלל הממוצע / שונות של מְקוֹרִי מערך הנתונים ישמש.
שכבת נורמליזציה של אצווה של Keras היא אינטליגנציה של PlatoBlockchain Data שבורה. חיפוש אנכי. איי.
למעלה אני מספק ארכיטקטורה פשטנית (ולא מציאותית) למטרות הדגמה. בואו נניח שאנו מכווננים את הדגם מ- Convolution k + 1 עד לראש הרשת (צד ימין) ואנחנו ממשיכים להקפיא את החלק התחתון (הצד השמאלי). במהלך האימונים כל שכבות ה- BN בין 1 ל- k ישתמשו בממוצע / שונות של נתוני האימונים שלך. יש לכך השפעות שליליות על ה- ReLUs הקפואים אם הממוצע והשונות על כל BN לא יהיו קרובים לאלה שנלמדו במהלך הכשרה מוקדמת. זה גם יגרום להדרכה של שאר הרשת (מ- CONV k + 1 ואילך) עם כניסות שיש להן מידות שונות בהשוואה למה שיקבלו במהלך ההסקה. במהלך האימונים הרשת שלך יכולה להסתגל לשינויים אלה, בכל זאת ברגע שתעבור למצב חיזוי, Keras ישתמש בסטטיסטיקות סטנדרטיזציה שונות, דבר שיבצע במהירות את התפלגות תשומות השכבות הבאות ויוביל לתוצאות לא טובות.

2.2 איך אתה יכול לגלות אם אתה מושפע?

אחת הדרכים לזהות זאת היא להגדיר באופן סטטי את שלב הלמידה של קרס ל -1 (מצב רכבת) ול- 0 (מצב מבחן) ולהעריך את המודל שלך בכל מקרה. אם יש הבדל משמעותי ברמת הדיוק באותו מערך נתונים, אתה מושפע מהבעיה. ראוי לציין שבשל אופן היישום של מנגנון הלמידה-שלב ב- Keras, בדרך כלל לא מומלץ להתעסק איתו. לשינויים בשלב ה- learning לא תהיה כל השפעה על דגמים שכבר נערכו ונמצאים בשימוש; כפי שתוכלו לראות על הדוגמאות בסעיפים הבאים, הדרך הטובה ביותר לעשות זאת היא להתחיל עם הפעלה נקייה ולשנות את שלב הלמידה לפני שמוגדר טנזור כלשהו בתרשים.

דרך נוספת לאתר את הבעיה תוך כדי עבודה עם מסווגים בינאריים היא לבדוק את הדיוק ואת ה- AUC. אם הדיוק קרוב ל 50% אבל ה- AUC קרוב ל 1 (וגם אתה מבחין בהבדלים בין מצב רכבת / מבחן באותו מערך נתונים), יכול להיות שההסתברויות אינן בקנה מידה בגלל הסטטיסטיקה של BN. באופן דומה, לצורך רגרסיה תוכלו להשתמש ב- MSE ובמתאם של Spearman כדי לאתר אותה.

2.3 כיצד ניתן לתקן את זה?

אני מאמין שניתן לתקן את הבעיה אם שכבות ה- BN הקפואות הן למעשה זו בלבד: נעולות לצמיתות במצב הבדיקה. מבחינה יישום, הדגל הניתן להדרכה צריך להיות חלק מהגרף החישובי והתנהגות ה- BN צריכה להיות תלויה לא רק בשלב הלמידה אלא גם בערך הנכס הניתן להדרכה. אתה יכול למצוא את פרטי היישום שלי ב- GitHub.

על ידי יישום התיקון שלעיל, כאשר שכבת BN קפואה היא כבר לא תשתמש בסטטיסטיקה של מיני אצווה אלא תשתמש באלה שנלמדו במהלך האימונים. כתוצאה מכך, לא תהיה הפרעה בין מצבי אימון למבחן אשר מביאה לדיוק מוגבר. ברור שכששכבת ה- BN אינה קפואה, היא תמשיך להשתמש בסטטיסטיקה של מיני אצווה במהלך האימונים.

2.4 הערכת השפעות המדבקה

למרות שכתבתי את היישום לעיל לאחרונה, הרעיון שעומד מאחוריו נבחן בכבדות על בעיות בעולם האמיתי באמצעות דרכים לעקיפת הבעיה השונות באותה השפעה. לדוגמא, הפער בין מצבי אימון לבדיקה וניתן להימנע מהם על ידי פיצול הרשת בשני חלקים (קפואים ולא קפואים) וביצוע אימונים במטמון (העברת נתונים דרך הדגם הקפוא פעם אחת ואז שימוש בהם כדי להכשיר את הרשת הלא קפואה). אף על פי כן, מכיוון ש"סמוך עלי שעשיתי זאת בעבר "בדרך כלל לא נושא משקל, להלן אני מספק כמה דוגמאות המראות את ההשפעות של היישום החדש בפועל.

להלן מספר נקודות חשובות לגבי הניסוי:

  1. אשתמש בכמות זעירה של נתונים בכדי להתאים את המודל בכוונה ואאמן ואמתן את המודל באותו מערך נתונים. בכך אני מצפה לדיוק מושלם וביצועים זהים במערך הרכבות / אימות.
  2. אם במהלך האימות אקבל דיוק נמוך משמעותית באותו מערך נתונים, תהיה לי אינדיקציה ברורה כי מדיניות ה- BN הנוכחית משפיעה לרעה על ביצועי המודל בזמן ההסקה.
  3. כל עיבוד מוקדם יתבצע מחוץ לגנרטורים. זה נעשה כדי לעקוף את הבאג שהוצג ב- v2.1.5 (קבוע כעת ב- v2.1.6 הקרוב ובמאסטר האחרון).
  4. אנו נכריח את קרס להשתמש בשלבי למידה שונים במהלך ההערכה. אם אנו מבחינים בהבדלים בין הדיוק המדווח, נדע שאנחנו מושפעים ממדיניות BNP הנוכחית.

הקוד לניסוי מוצג להלן:

import numpy as np
from keras.datasets import cifar10
from scipy.misc import imresize

from keras.preprocessing.image import ImageDataGenerator
from keras.applications.resnet50 import ResNet50, preprocess_input
from keras.models import Model, load_model
from keras.layers import Dense, Flatten
from keras import backend as K


seed = 42
epochs = 10
records_per_class = 100

# We take only 2 classes from CIFAR10 and a very small sample to intentionally overfit the model.
# We will also use the same data for train/test and expect that Keras will give the same accuracy.
(x, y), _ = cifar10.load_data()

def filter_resize(category):
   # We do the preprocessing here instead in the Generator to get around a bug on Keras 2.1.5.
   return [preprocess_input(imresize(img, (224,224)).astype('float')) for img in x[y.flatten()==category][:records_per_class]]

x = np.stack(filter_resize(3)+filter_resize(5))
records_per_class = x.shape[0] // 2
y = np.array([[1,0]]*records_per_class + [[0,1]]*records_per_class)


# We will use a pre-trained model and finetune the top layers.
np.random.seed(seed)
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
l = Flatten()(base_model.output)
predictions = Dense(2, activation='softmax')(l)
model = Model(inputs=base_model.input, outputs=predictions)

for layer in model.layers[:140]:
   layer.trainable = False

for layer in model.layers[140:]:
   layer.trainable = True

model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit_generator(ImageDataGenerator().flow(x, y, seed=42), epochs=epochs, validation_data=ImageDataGenerator().flow(x, y, seed=42))

# Store the model on disk
model.save('tmp.h5')


# In every test we will clear the session and reload the model to force Learning_Phase values to change.
print('DYNAMIC LEARNING_PHASE')
K.clear_session()
model = load_model('tmp.h5')
# This accuracy should match exactly the one of the validation set on the last iteration.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))


print('STATIC LEARNING_PHASE = 0')
K.clear_session()
K.set_learning_phase(0)
model = load_model('tmp.h5')
# Again the accuracy should match the above.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))


print('STATIC LEARNING_PHASE = 1')
K.clear_session()
K.set_learning_phase(1)
model = load_model('tmp.h5')
# The accuracy will be close to the one of the training set on the last iteration.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))

בואו לבדוק את התוצאות ב- Keras v2.1.5:

Epoch 1/10
1/7 [===>..........................] - ETA: 25s - loss: 0.8751 - acc: 0.5312
2/7 [=======>......................] - ETA: 11s - loss: 0.8594 - acc: 0.4531
3/7 [===========>..................] - ETA: 7s - loss: 0.8398 - acc: 0.4688 
4/7 [================>.............] - ETA: 4s - loss: 0.8467 - acc: 0.4844
5/7 [====================>.........] - ETA: 2s - loss: 0.7904 - acc: 0.5437
6/7 [========================>.....] - ETA: 1s - loss: 0.7593 - acc: 0.5625
7/7 [==============================] - 12s 2s/step - loss: 0.7536 - acc: 0.5744 - val_loss: 0.6526 - val_acc: 0.6650

Epoch 2/10
1/7 [===>..........................] - ETA: 4s - loss: 0.3881 - acc: 0.8125
2/7 [=======>......................] - ETA: 3s - loss: 0.3945 - acc: 0.7812
3/7 [===========>..................] - ETA: 2s - loss: 0.3956 - acc: 0.8229
4/7 [================>.............] - ETA: 1s - loss: 0.4223 - acc: 0.8047
5/7 [====================>.........] - ETA: 1s - loss: 0.4483 - acc: 0.7812
6/7 [========================>.....] - ETA: 0s - loss: 0.4325 - acc: 0.7917
7/7 [==============================] - 8s 1s/step - loss: 0.4095 - acc: 0.8089 - val_loss: 0.4722 - val_acc: 0.7700

Epoch 3/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2246 - acc: 0.9375
2/7 [=======>......................] - ETA: 3s - loss: 0.2167 - acc: 0.9375
3/7 [===========>..................] - ETA: 2s - loss: 0.2260 - acc: 0.9479
4/7 [================>.............] - ETA: 2s - loss: 0.2179 - acc: 0.9375
5/7 [====================>.........] - ETA: 1s - loss: 0.2356 - acc: 0.9313
6/7 [========================>.....] - ETA: 0s - loss: 0.2392 - acc: 0.9427
7/7 [==============================] - 8s 1s/step - loss: 0.2288 - acc: 0.9456 - val_loss: 0.4282 - val_acc: 0.7800

Epoch 4/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2183 - acc: 0.9688
2/7 [=======>......................] - ETA: 3s - loss: 0.1899 - acc: 0.9844
3/7 [===========>..................] - ETA: 2s - loss: 0.1887 - acc: 0.9792
4/7 [================>.............] - ETA: 1s - loss: 0.1995 - acc: 0.9531
5/7 [====================>.........] - ETA: 1s - loss: 0.1932 - acc: 0.9625
6/7 [========================>.....] - ETA: 0s - loss: 0.1819 - acc: 0.9688
7/7 [==============================] - 8s 1s/step - loss: 0.1743 - acc: 0.9747 - val_loss: 0.3778 - val_acc: 0.8400

Epoch 5/10
1/7 [===>..........................] - ETA: 3s - loss: 0.0973 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0828 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0851 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0897 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0928 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0936 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.1337 - acc: 0.9838 - val_loss: 0.3916 - val_acc: 0.8100

Epoch 6/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0747 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0852 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0812 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0831 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0779 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0766 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.0813 - acc: 1.0000 - val_loss: 0.3637 - val_acc: 0.8550

Epoch 7/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2478 - acc: 0.8750
2/7 [=======>......................] - ETA: 2s - loss: 0.1966 - acc: 0.9375
3/7 [===========>..................] - ETA: 2s - loss: 0.1528 - acc: 0.9583
4/7 [================>.............] - ETA: 1s - loss: 0.1300 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.1193 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.1196 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.1084 - acc: 0.9838 - val_loss: 0.3546 - val_acc: 0.8600

Epoch 8/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0539 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0900 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0815 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0740 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0700 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0701 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.0695 - acc: 1.0000 - val_loss: 0.3269 - val_acc: 0.8600

Epoch 9/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0306 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0377 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0898 - acc: 0.9583
4/7 [================>.............] - ETA: 1s - loss: 0.0773 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.0742 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.0708 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.0659 - acc: 0.9838 - val_loss: 0.3604 - val_acc: 0.8600

Epoch 10/10
1/7 [===>..........................] - ETA: 3s - loss: 0.0354 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0381 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0354 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0828 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.0791 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.0794 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.0704 - acc: 0.9838 - val_loss: 0.3615 - val_acc: 0.8600

DYNAMIC LEARNING_PHASE
[0.3614931714534759, 0.86]

STATIC LEARNING_PHASE = 0
[0.3614931714534759, 0.86]

STATIC LEARNING_PHASE = 1
[0.025861846953630446, 1.0]

כפי שאנו רואים לעיל, במהלך האימונים המודל לומד היטב את הנתונים ומשיג על סט האימונים כמעט מושלם. עדיין בסיום כל איטרציה, תוך הערכת המודל באותו מערך נתונים, אנו מקבלים הבדלים משמעותיים באובדן ודיוק. שים לב שאסור לנו לקבל את זה; אנו מציידים בכוונה יתר על המידה את המודל במערך הנתונים הספציפי וערכות הנתונים של ההדרכה / אימות זהים.

לאחר סיום האימון אנו מעריכים את המודל באמצעות 3 תצורות שונות של למידה_שלב: דינמי, סטטי = 0 (מצב בדיקה) וסטטי = 1 (מצב אימון). כפי שאנו רואים שתי התצורות הראשונות יספקו תוצאות זהות מבחינת אובדן ודיוק וערכן תואם את הדיוק המדווח של המודל בתיקוף שנקבע באיטרציה האחרונה. עם זאת, ברגע שאנחנו עוברים למצב אימונים, אנו מבחינים בפער (שיפור) מאסיבי. למה זה? כפי שאמרנו קודם, משקולות הרשת מכווננות ומצפות לקבל נתונים המוגדלים עם הממוצע / השונות של נתוני האימון. למרבה הצער, נתונים סטטיסטיים אלה שונים מאלה המאוחסנים בשכבות BN. מכיוון ששכבות ה- BN הוקפאו, הסטטיסטיקה הזו מעולם לא עודכנה. פער זה בין ערכי הסטטיסטיקה של BN מוביל להידרדרות הדיוק במהלך ההסקה.

בוא נראה מה קורה ברגע שאנחנו מיישמים את ה- תיקון:

Epoch 1/10
1/7 [===>..........................] - ETA: 26s - loss: 0.9992 - acc: 0.4375
2/7 [=======>......................] - ETA: 12s - loss: 1.0534 - acc: 0.4375
3/7 [===========>..................] - ETA: 7s - loss: 1.0592 - acc: 0.4479 
4/7 [================>.............] - ETA: 4s - loss: 0.9618 - acc: 0.5000
5/7 [====================>.........] - ETA: 2s - loss: 0.8933 - acc: 0.5250
6/7 [========================>.....] - ETA: 1s - loss: 0.8638 - acc: 0.5417
7/7 [==============================] - 13s 2s/step - loss: 0.8357 - acc: 0.5570 - val_loss: 0.2414 - val_acc: 0.9450

Epoch 2/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2331 - acc: 0.9688
2/7 [=======>......................] - ETA: 2s - loss: 0.3308 - acc: 0.8594
3/7 [===========>..................] - ETA: 2s - loss: 0.3986 - acc: 0.8125
4/7 [================>.............] - ETA: 1s - loss: 0.3721 - acc: 0.8281
5/7 [====================>.........] - ETA: 1s - loss: 0.3449 - acc: 0.8438
6/7 [========================>.....] - ETA: 0s - loss: 0.3168 - acc: 0.8646
7/7 [==============================] - 9s 1s/step - loss: 0.3165 - acc: 0.8633 - val_loss: 0.1167 - val_acc: 0.9950

Epoch 3/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2457 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.2592 - acc: 0.9688
3/7 [===========>..................] - ETA: 2s - loss: 0.2173 - acc: 0.9688
4/7 [================>.............] - ETA: 1s - loss: 0.2122 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.2003 - acc: 0.9688
6/7 [========================>.....] - ETA: 0s - loss: 0.1896 - acc: 0.9740
7/7 [==============================] - 9s 1s/step - loss: 0.1835 - acc: 0.9773 - val_loss: 0.0678 - val_acc: 1.0000

Epoch 4/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2051 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.1652 - acc: 0.9844
3/7 [===========>..................] - ETA: 2s - loss: 0.1423 - acc: 0.9896
4/7 [================>.............] - ETA: 1s - loss: 0.1289 - acc: 0.9922
5/7 [====================>.........] - ETA: 1s - loss: 0.1225 - acc: 0.9938
6/7 [========================>.....] - ETA: 0s - loss: 0.1149 - acc: 0.9948
7/7 [==============================] - 9s 1s/step - loss: 0.1060 - acc: 0.9955 - val_loss: 0.0455 - val_acc: 1.0000

Epoch 5/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0769 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0846 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0797 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0736 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0914 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0858 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0808 - acc: 1.0000 - val_loss: 0.0346 - val_acc: 1.0000

Epoch 6/10
1/7 [===>..........................] - ETA: 1s - loss: 0.1267 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.1039 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0893 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0780 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0758 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0789 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0738 - acc: 1.0000 - val_loss: 0.0248 - val_acc: 1.0000

Epoch 7/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0344 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0385 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0467 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0445 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0446 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0429 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0421 - acc: 1.0000 - val_loss: 0.0202 - val_acc: 1.0000

Epoch 8/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0319 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0300 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0320 - acc: 1.0000
4/7 [================>.............] - ETA: 2s - loss: 0.0307 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0303 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0291 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0358 - acc: 1.0000 - val_loss: 0.0167 - val_acc: 1.0000

Epoch 9/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0246 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0255 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0258 - acc: 1.0000
4/7 [================>.............] - ETA: 2s - loss: 0.0250 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0252 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0260 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0327 - acc: 1.0000 - val_loss: 0.0143 - val_acc: 1.0000

Epoch 10/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0251 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0228 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0217 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0249 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0244 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0239 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0290 - acc: 1.0000 - val_loss: 0.0127 - val_acc: 1.0000

DYNAMIC LEARNING_PHASE
[0.012697912137955427, 1.0]

STATIC LEARNING_PHASE = 0
[0.012697912137955427, 1.0]

STATIC LEARNING_PHASE = 1
[0.01744014158844948, 1.0]

ראשית, אנו מבחינים כי הרשת מתכנסת במהירות רבה יותר ומשיגה דיוק מושלם. אנו רואים כי אין עוד אי התאמה מבחינת הדיוק כאשר אנו עוברים בין ערכי שלב למידה שונים.

2.5 כיצד ביצוע התיקון במערך נתונים אמיתי?

אז איך התיקון מבצע ניסוי מציאותי יותר? בוא נשתמש ב- Reseras 50 מאומנים מראש של Keras (בכושר במקור על imagenet), נסלק את שכבת הסיווג העליונה ונתאם אותה עם וללא התיקון ונשווה את התוצאות. לנתונים אנו נשתמש ב- CIFAR10 (חלוקת הרכבת / מבחן הסטנדרטית המסופקת על ידי Keras) ונשנה את גודל התמונות ל 224 × 224 בכדי להפוך אותן לתאימות לגודל הקלט של ResNet50.

נעשה 10 תקופות כדי לאמן את שכבת הסיווג העליונה באמצעות RSMprop ואז נעשה עוד 5 כדי לכוונן את הכל אחרי השכבה ה 139 באמצעות SGD (lr = 1e-4, מומנטום = 0.9). ללא התיקון הדגם שלנו משיג דיוק של 87.44%. בעזרת התיקון אנו משיגים דיוק של 92.36%, כמעט 5 נקודות יותר.

2.6 האם עלינו להחיל את אותה התיקון על שכבות אחרות כמו Dropout?

נורמליזציה של אצווה אינה השכבה היחידה שפועלת באופן שונה בין מצבי רכבת ומבחן. לנשירה ולווריאציות שלה יש גם אותה השפעה. האם עלינו להחיל את אותה מדיניות על כל הרבדים הללו? אני מאמין שלא (למרות שהייתי שמח לשמוע את המחשבות שלך על זה). הסיבה לכך היא שנשירה משמשת למניעת התאמה יתר, ובכך נעילה קבועה למצב חיזוי במהלך אימון תביס את מטרתה. מה אתה חושב?

אני מאמין מאוד כי יש לפתור את ההתאמה הזו בכרס. ראיתי השפעות עמוקות יותר (מ- 100% עד 50% דיוק) ביישומים בעולם האמיתי הנגרמים כתוצאה מבעיה זו. אני מתכנן לשלוח כבר שלחו PR לקאראס עם התיקון ומקווה שהוא יתקבל.

אם אהבתם את עמוד הבלוג הזה, אנא הקדישו רגע לשתף אותו בפייסבוק או בטוויטר. 🙂

בול זמן:

עוד מ דטומבוקס