מהנדסי האוגמנטציות

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

אוגמנטציות של חתול: סיבוב, זום וחיתוך, תמונת מראה, או שילוב של כמה מהם.

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

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

מספיק עם התיוגים

השינויים האחרונים בתחום ה-deep שמים את האוגמנטציות אף יותר במרכז הזירה. הסיבה היא ה-holy grail של ה-machine learning, הלא הוא self Supervised Learning: האפשרות ללמוד בלי לייבלים בכלל. דיברנו על זה קצת בעבר.  למעשה, שם התחלנו, כשהלמידה העמוקה היתה בחיתוליה, והדאטה היה חסר. בנינו autoencoders — מודל שמכווץ תמונה לוקטור ייצוג קטן, צוואר-בקבוק, ואז פורש אותו בחזרה לגודל מלא. ממש אימנו את המודל כך שהתמונה המשוחזרת תהיה זהה ככל האפשר למקורית, והתפללנו שכל האינפורמציה החשובה על התמונה תישמר לה בתוך צוואר הבקבוק, מבלי שהנחינו את המודל מה חשוב לשמור.  כך יכולנו לאמן מודלים על מיליוני תמונות לא מתוייגות מהאינטרנט, מודלים שלא עושים הרבה חוץ מלכווץ תמונה לוקטור צוואר-בקבוק (נהוג לקרוא לו פשוט feature vector) ואז לפתוח אותה בחזרה.

ארכיטקטורה של autoencoder. התמונה המקורית מתכווצת לוקטור צוואר-בקבוק ומשם נפתחת בחזרה לגודל המקורי. המודל מאומן כך שהתמונה הצהובה מימין צריכה להיות דומה כמה שיותר לתמונה הצהובה משמאל. מקור: Mohammadreza Amirian (ברשותו).

רק בשלב ב' היינו פונים לדאטה סט הקטן יותר והמתוייג שלנו, שהכיל רק כמה אלפי תמונות, מתוכן, אולי רק כמה עשרות חתולים, ומכווצים את כולן ל-feature vectors באמצעות ה-autoencoder. האמונה שבתוך הוקטור הזה מקודדת גם הידיעה אם בתמונה יש חתול, והיא מקודדת שם בצורה פשוטה יותר לזיהוי מאשר בפיקסלים של התמונה המקורית, גרמה לנו לחשוב שנוכל לאמן מודל לא עמוק ולא כזה שרעב לדאטה, סתם SVM, לסווג את ה-feature vectors למחלקות השונות, וכך נדע לומר לנו אם בתמונה יש חתול או כלב.

אבל אז נבנו הפירמידות.  לצד יתר פלאי העולם החדש, בהם הקוד של גוגל, המחסנים של אמזון, האייפון של אפל והסטרימינג של נטפליקס, ניצב פרוייקט ImageNet, שאוצר דאטה סט של מיליוני תמונות מתוייגות ל-1000 סוגי אובייקטים, בהן אלפי תמונות חתולים. זה היה הפרוייקט הגדול ביותר ב-2012 ב-mechanical Turk, שירות סחר העבדים  העובדים המקוון של אמזון. אז אמרנו שלום ל-autoencoders, ועברנו לאמן מודל עמוק הישר מהתמונה ל-class שלה, והתוצאות השתפרו בהרבה.

אחוז הדיוק של מודלים שונים שהתאמנו ונבחנו על ImageNet, לאורך השנים. מקור: paperswithcode.com

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

השנה, 2020, זה קרה.

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

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

וכך נוצרה לה שיטת האימון הבאה: נותנים למודל שתי תמונות, x ו-x', אחרי שעברו אוגמנטציה כלשהיא. יכול להיות ש-x התקבלה מסיבוב ב-90 מעלות של התמונה המקורית, ו-x' התקבלה באמצעות שינוי היסטוגרמת הצבעים. המודל הוא רשת ניורונים (כמו ה-encoder ב-autoencoder) שיוצר בסוף התהליך וקטור פיצ'רים מכל תמונה, נגיד y ו-y'.  אנחנו לא אומרים למודל מה לשים בכל וקטור פיצ'רים הזה, אבל פונקציית ה-loss של האימון דורשת ממנו דרישה עקיפה – אם שתי האוגמנטציות x ו-x' נוצרו מאותה תמונה היינו רוצים ששני וקטורי הפיצ'רים y ו-y' יהיו מאוד דומים אחד לשני.  מצד שני, אם שתי האוגמנטציות נוצרו מתמונות שונות, אנחנו רוצים שוקטורי הפיצ'רים שלהם יהיו רחוקים.

אילוסטרציה של SimCLR. מקור: Google AI Blog

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

השיטה הזו תפסה תאוצה בשנה האחרונה, עם עבודות כמו SimCLR ו-BYOL (מבית גוגל) שמביאים לשולחן טריקים נוספים כדי לאפשר ללמוד את הפיצ'רים בצורה טובה אף יותר, ועם פחות דוגמאות בכל מקבץ. המספרים האחרונים מלמדים שאם מתייחסים למאגר ImageNet כמאגר תמונות לא מתוייגות ומאמנים איתו את שלב א', אז אפשר בכמות קטנה מאוד של תמונות מתוייגות להגיע בשלב ב' כמעט לאותה רמת ביצועים שמגיע אליה מודל שאומן מלכתחילה על כל ImageNet המתוייגת. הגרפים גם מראים שגישת ה-contrastive learning מצליחה עדיין להשתפר אף יותר אם מגדילים את מספר הפרמטרים של המודל.  אני משוכנע שבמהלך החודשים הקרובים נשמע על שיאים חדשים ב-ImageNet שהושגו בשיטה הזו.

ביצועים על ImageNet כתלות באחוז תמונות ImageNet המתוייגות. האלגוריתמים BYOL ו-SimCLR עושים גם שימוש בכל ImageNet באופן לא מתוייג. אלגוריתם ה-Supervised משתמש רק בתמונות המתוייגות. מקור: מאמר BYOL.

זהה את האוגמנטציה (והאנומליה)

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

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

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

אלא שבמאמר מ-2018, שמו לב יצחק גולן ופרופ' רן אל-יניב שכאשר מודל שהתמחה במשימת "זהה את האוגמנטציה" מקבל תמונה שהיא אנומלית ביחס לדאטה שעליו אומן, המודל מתבלבל באופן אחר לגמרי ביחס לתמונה רגילה. במילים אחרות, פרופיל הבלבול שלו שונה. וככה נוצרה שיטה חדשה לזיהוי אנומליות: תעביר את התמונה החשודה את כל 70 האוגמנטציות, ותראה כמה מהן המודל מצליח לזהות. אם פרופיל הבלבול של המודל שונה מספיק מפרופיל הבלבול הממוצע (שחושב על תמונות "רגילות"), תפעיל את האזעקה וקרא למאבטחים.  באופן מפתיע השיטה הזו ניצחה את ה-autoencoderים שהיו נהוגים לפני כן.

מהנדסי האוגמנטציות

אנשי ה-Deep Learning מתגאים בכך שהם כבר לא עושים Feature Engineering (הנדסת פיצ'רים) כדי להכתיב למודל איך לקרוא את הדאטה, וככל שנעבור לעבוד יותר בגישת ה-self supervised learning גם בלייבלים ותיוגים נשתמש פחות ופחות. אבל בעצם אנחנו עדיין מהנדסים משהו קריטי להצלחת הבעייה:  האוגמנטציות עצמן. בסופו של יום, אם המשימה שלנו היא להבדיל בין סוגים של פרחים, אז שינוי של צבעי התמונה כחלק מהאוגמנטציות האפשריות ימנע מוקטור הפיצ'רים להכיל מידע קריטי על צבע הפרח. לעומת זאת אם המטרה היא להבדיל בין "פרח" ל"מכונית", אז האוגמנטצמיה הזו היא בסדר גמור. אם המטרה שלנו היא למצוא גידול סרטני בריאות שיכול להופיע גם בשוליהם, אז לא נכון יהיה לחתוך חלקים מהתמונה כי אז אנו עשויים לחתוך בטעות גם את הגידול, אבל תמונת מראה של הריאות תעבוד סבבה. אנחנו צריכים לבחור את סט האוגמנטציות בחוכמה, כדי שלא יפגעו במהות של התמונה, במשימה שנרצה לעשות בהמשך הדרך.

שמאל: סוגים שונים של אוגמנטציות. ימין: האם האוגמנטציה שבציר y עוזרת לביצוע משימת הסיווג שמתוארת בציר x. למשל, אם רוצים לבנות מסווג פרחים, אז סיבובים זו אוגמנטציה מועילה, אבל שינוי הצבע של הפרחים פחות. בדיוק הפוך אם המשימה שלי היא להבדיל בין חיות שונות.  מתוך המאמר: What Should Not Be Contrastive in Contrastive Learning מאת Tete Xiao וחברים.

בעצם, כל עוד אנחנו צריכים לבחור מהן האוגמנטציות הנכונות ל-contrastive learning, זה עדיין סוג של supervised learning, לא? כדי להשיל גם את השכבה הזו, נדרש עוד שלב באלגוריתם האימון, שיחליט באופן אוטומטי מהו סט האוגמנטציות הנכון עבור הדאטה שלי ומשימת היעד.  עד אז, אחרי שהורדנו את הינדוס הפיצ'רים, הלייבלים, והארכיטקטורה של המודל מהתהליך, נותרנו עם תפקיד "מהנדסי האוגמנטציות". 

מקורות:

[1] Ting Chen, Simon Kornblith, Mohammad Norouzi, Geoffrey Hinton. SimCLR: A Simple Framework for Contrastive Learning of Visual Representations. PMLR 2020 [arxiv]

[2] Jean-Bastien Grill, et.al. (DeepMind). Bootstrap your own latent: A new approach to self-supervised Learning. NeurIPS 2020. [arxiv]

[3] Yonglong Tian, Chen Sun, Ben Poole et. al. (MIT, Google). What Makes for Good Views for Contrastive Learning? NeurIPS 2020 [pdf

[4] Izhak Golan, Ran El-Yaniv. Deep Anomaly Detection Using Geometric Transformations. NIPS 2018. [arxiv]

פוסט זה פורסם בקטגוריה anomaly detection, deep learning, machine learning, עם התגים , , , . אפשר להגיע ישירות לפוסט זה עם קישור ישיר.

11 תגובות על מהנדסי האוגמנטציות

  1. גל הגיב:

    הי יוני, יופי של פוסט!
    בנוגע לנקודה האחרונה. הנה מאמר ב ICLR שלומד באופן אוטומטי מטלות auxiliary. זה לא בדיוק אוגמנטציות, אבל קרוב.
    https://openreview.net/forum?id=n7wIfYPdVet

  2. Efi Domb הגיב:

    איזה יופי של פוסט.
    קצת התרחקתי ממה שקורה בחזית המחקר וכיף לקרוא על זה ככה.

    האם יש איזשהו גיט שמממש את המודלים האלו ישר מהקופסא?

  3. גלעד הגיב:

    נהניתי מאוד, הרווחת עוקב :-)

  4. יער הגיב:

    כתוב מעולה. תודה.

  5. ליאורה הגיב:

    אחד הפוסטים המעניינים שקראתי! תודה רבה

  6. פינגבאק: Augmentation Engineers – ZEBRA MEDICAL VISION BLOG

  7. Assaf Lavie הגיב:

    מעולה!
    נהנתי לקרוא.

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

    • lifesimulator הגיב:

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

  8. פינגבאק: כמה עדכונים | lifesimulator

כתיבת תגובה