העוגה והדובדבן – ללמוד לפעול באמצעות חיזוי העתיד

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

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

go_lee_sedol

לי סדול, משחקני הגו המובילים בעולם, לפני התבוסה לאלפא-גו במרץ 2016. צילום רפרודוקציה: יונתן לזרסון

אלפא-גו אומן לעשות דבר אחד, והוא – לנצח בגו. הבעייה שהמתכנתים של אלפא-גו התמודדו איתה היא הבעייה המרכזית בתחום שנקרא  Reinforcement Learning (או RL).  בכל שלב במשחק, כשמגיע תורו של אלפא-גו, הוא צריך לבצע הכרעה בין מספר סופי של אפשרויות (בעיקר איפה לשים את האבן שלו על הלוח).  הצרה היא שאחרי שאלפא-גו שם את האבן שלו במקום כלשהו על הלוח, למתכנתים אין מושג אם זו היתה החלטה טובה.  בשביל לדעת אם זו היתה החלטה טובה הם צריכים לחכות עד לסוף המשחק ואז הם מקבלים בסך הכל ביט אחד של אינפורמציה – 1 אם אלפא-גו ניצח, ו-0 אם הפסיד.  הביט הזה, כשהוא 1, אומר לאלפא-גו 'קבל ח"ח', אבל לא מפרט אלו מההחלטות שאלפא-גו קיבל במהלך הדרך היו החלטות חשובות שתרמו לניצחונו.

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

זו מציאות הרבה יותר מאתגרת מהמציאות שבדרך-כלל אנחנו מתמקדים בה בבינה מלאכותית, שנקראת Supervised Learning (או SL). בסיווג תמונה, למשל, כשאנחנו מבקשים מהמחשב להסתכל על תמונה ולומר מה יש בה (למשל הסיכוי שמופיע בה כלב והסיכוי שמופיע בה חתול), המחשב פולט את תשובתו (נגיד 90% חתול ו-10% כלב) ומיד אנחנו יודעים כמה קרוב הוא היה לתשובה הנכונה (100% חתול). במקרה של רשת ניורונים, זו בדיוק הנקודה שבה אנחנו מחשבים את הנגזרת על הפרמטרים של המודל ומעדכנים אותם כך שבפעם הבאה המחשב ייתן תשובה עוד יותר מדוייקת (אולי 94% חתול ו-6% כלב).  

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

כדי לפצות על דלילות האינפורמציה הזו, אנחנו נאלצים ללקט אותה באמצעות הרבה משחקים, ולכן אין פלא שכמעט כל העבודות שנעשות היום על Reinforecment Learning עושות זאת בתחום משחקי המחשב. זוכרים את כל משחקי האטארי ששיחקנו פעם? הם זוכים לעדנה מחודשת כחומר גלם לאימון אלגוריתמים.  DeepMind בנו תשתית שמאפשרת למחשב לשחק בהם בקצב מואץ של מליוני פעמים ביום(!), ובצורה כזו הם מאמנים אותו עד שהוא מגיע לרמה על-אנושית (במקרה של גו אלפא-גו שיחק נגד עצמו). חברת OpenAI אף הגדילה לעשות והקימה "חדר כושר" הפתוח לכלל ציבור השחקנים הממוחשבים.

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

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

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

עשינו פה בעצם טריק שבו השתמשנו בדאטה שלנו (המידע החושי שמגיע כל רגע) להיות ה"אמת" של עצמו. כל רגע הוא מטרת החיזוי של הרגע הקודם. אנחנו גם לא צריכים לעבוד עכשיו קשה ולתייג מיליוני תמונות. עברנו מסביבה של Supervised Learning לסביבה עשירה באינפורמציה של Predictive Learning (או Unsupervised Learning).  ככה המוח מצליח לקבל מספיק אינפורמציה כדי לבנות מודל כללי של "איך העולם עובד".  עם המודל הכללי הזה אנחנו מסוגלים לאפיין הרבה בעיות קטנות וממוקדות יותר ולגשת אליהן כשכעת אנחנו זקוקים להרבה פחות אינפורמציה נוספת (כמו ב-SL ו-RL) כדי להתמקצע בהן, משום שאת ה-heavy lifting כבר עשינו במידול הכללי של העולם.

לכן אלגוריתם הלמידה האולטימטיבי הוא אלגוריתם שיצליח להשתמש בכל רבדי האינפורמציה השונים.  יאן לקון (Yann Lecun), אחד מהאבות המייסדים של רשתות הניורונים של היום, ממשיל את תהליך הלימוד בבינה מלאכותית לעוגת קצפת. העוגה עצמה היא ה-Predictive Learning, שבה האלגוריתם מתכוונן על סמך מיליוני ביטים לכל דוגמית קלט. מעליה יש את הקצפת, ה-Supervised Learning, שבה בני אדם מוסיפים עוד כמה עשרות ביטים של "אינפורמציה חיצונית" לכל דוגמית, ומעל יש את הדובדבן שבקצפת, הוא ה-Reinforcement Learning, שבו ביטים בודדים שניתנים מדי פעם כ"חיזוק חיובי" הם כל מה שמכוון את האלגוריתם. "אנחנו יודעים להכין את הקצפת ואת הדובדבן", אומר לקון, "אבל עדיין לא יודעים איך להכין את העוגה".

נסיון לחזות את הפריימים הבאים.

מודל שחוזה פריימים עתידיים (משמאל, החל מפריים 11). עדיין בחיתוליו. מקור: הונגלאק לי

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

דום

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

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

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

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

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

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

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

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

ביצועים של שלושה שחקנים ממוחשבים במגוון מטרות

ביצועים של שלושה שחקנים ממוחשבים במגוון מטרות. המספריים שבסוגריים מייצגים את משקלות המדדים (הריגות, בריאות, תחמושת). השחקן בטור (a) אומן באמצעות מטרה קבועה (1, 0.5, 0.5). השחקנים ב-(b) ו-(c) אומנו עם מטרות אקראיות מתחלפות (ב-b משקלות חיוביים בלבד וב-c איפשרו גם שליליים). ירוק: ביצועי המנצח בתחרות ה"פציפיסטית". צהוב: ביצועי שחקן (b) על מטרה (1, 0.5, 0.5) טובים כמו אלו של (a) שהתאמן רק עליה. מקור: קולטון ודוסוביצקי, המירקורים שלי.

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

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

לקריאה נוספת:

[1] Alexey Dosovitskiy and Vladlen Koltun. Learning to Act by Predicting the Future. ICLR 2017.

[2] Mnih et. al. Playing Atari with Deep Reinforcement Learning. Deep Mind, 2013.

[3] פוסט של אנדריי קארפאתי על למידת חיזוקים: Deep Reinforcement Learning: Pong from Pixels.

[4] פוסט נוסף של קארפאתי על אלפא-גו, ולמה האלגוריתם בבסיסו לא יעזור לנו לבנות רובוט AI.

[5] Ruben Villegas, Honglack Lee et. al. Learning to Generate Long-term Future via Hierarchical Prediction. ICML 2017.

גילוי נאות: אני מכיר אישית את ולאדלן קולטון (וגם את הונגלאק לי) מסטנפורד, וקולטון אף היה המנחה שלי לסימסטר אחד או שניים.

פורסם בקטגוריה deep learning, Uncategorized | תגובה אחת

ללמוד למבחן טיורינג – על רשתות ניורונים יצירתיות

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

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

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

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

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

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

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

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

וכך בעצם אנחנו יוצרים שתי רשתות. רשת "אומנית" G, שמקבלת וקטור השראה z, ומייצרת ממנו תמונה. ורשת "מבקר אומנות" D, שמקבלת תמונה x ונותנת לה ציון בין 0 ל-1 שקובע עד כמה היא חושבת שהתמונה אמיתית:  מספר קרוב ל-1 אומר שהרשת די בטוחה שהתמונה הגיעה ממצבור התמונות שלנו, ומספר קרוב ל-0 אומר שהרשת חושבת שהתמונה נוצרה על ידי G.  הרשת D למעשה שופטת את G בסוג של מבחן טיורינג:  אם G מצליחה להוליך שולל את D, כלומר D מוציאה ציונים דומים עבור תמונות מזוייפות ואמיתיות, הרי ש-G מייצרת תמונות הגיוניות למראה!

באופן מתמטי, אנחנו רוצים ש-(D(x על כל תמונה "אמיתית" x יהיה כמה שיותר גבוה, ו-((D(G(z על כל וקטור השראה z יהיה כמה שיותר נמוך.  אולם, בניגוד ל-D, הרשת G רוצה ש-((D(G(z יהיה כמה שיותר גבוה על כל וקטור השראה z.  באופן פורמלי, פונקציית המטרה של הרשת, נראית כך:

Screenshot from 2016-08-21 00:51:53

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

lsun_bedrooms_five_epoch_samples

תמונות של חדרי שינה שנוצרו על ידי רשת ניורונים יצירתית. מבולבלים? מקור: A. Radford

לאופרציה הזו קוראים [Generative Adversarial Training [1, או בקיצור GAN, וכיום היא נראית כשיטה המבטיחה ליצירת תמונות הגיוניות למראה. התמונות שלמעלה התקבלו אחרי שאימנו את שתי הרשתות על אוסף תמונות חדרי שינה שנלקח מאתרים של בתי מלון.  כל תמונה של חדר שינה התקבלה מוקטור השראה z אחר.

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

lsun_bedrooms_five_epochs_interps

כל שורה היא טיול על הקו במחבר בין שני חדרי שינה במימד ההשראה. מקור: A. Radford

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

gans-2-6345b04cb02f720a95ea4cb9483e2fd5a5f6e46ec6ea5bbefadf002a010cda82

תמונות שנוצרו על ידי רשת ניורונים שהתאמנה על ImageNet. מקור: OpenAI


בעיות צביעה

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

Screenshot from 2016-08-21 23:47:52

צביעה אוטומטית משחור-לבן באמצעות רשת ניורונים. מקור: ריצ'רד זאנג. צילום: אנסל אדמס.

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

באיזו צבע החולצה?

צביעה אוטומטית באמצעות רשת ניורונים. באיזו צבע החולצה? מקור: ריצ'רד זאנג. צילום: דורותי לאנג.

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


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

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

13768366_1401936413155081_596741931_n

מקור: dustinteractive.com

עדכון [30.12.2016]:

המגזין טיים פרסם השבוע אוסף של תמונות מפורסמות שנצבעו על ידי אומני צביעה (אנושיים). התמונה של האישה למעלה מופיעה בינהן:

1936_lange_migrantmother-color

מתוך http://time.com/4028250/100-influential-photos-colorized/

מעניין להרהר בהבדלים השונים ובידע שהאומן האנושי נזקק לו כדי להחליט באיזה צבע לצבוע כל דבר.

לקריאה נוספת

[1] המאמר המקורי:  Generative Adversarial Networks. Ian J. Goodfellow, Yoshua Bengio et. al. NIPS 2014.

[2] שכלול GAN לתמונותUnsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks. Alec Radford et. al. 2015

[3] פוסט בבלוג של OpenAI על רשתות ניורונים יצירתיות. אנדריי קארפאתי וחברים.

[4] צביעה אוטומטית של תמונות שחור-לבןColorful Image Colorization. Richard Zhang et al. ECCV 2016

פורסם בקטגוריה deep learning | 6 תגובות

הרצאה

מי שרוצה לראות אותי מרצה בלייב על Deep Learning מוזמן להגיע מחר, 20.6, לפאב מ.א.ש (אלנבי 38 תל אביב) בשעה 1930 (ההרצאה מתחילה ב-20). ההרצאה מיועדת לקהל הרחב, ללא תשלום.

פורסם בקטגוריה Uncategorized | כתיבת תגובה

הרצאת מבוא על למידה עמוקה

לפני כשבוע וחצי נתתי הרצאה על Deep Learning למהנדסים ב-meetup בשם "המהנדס הגנרליסט" שאורגן על-ידי חברת Twiggle. אתם מוזמנים לצפות ולהפיץ. את הזקן כבר גילחתי מאז…

חלק ראשון:

חלק שני:

 

פורסם בקטגוריה deep learning, machine learning, קוגניציה | 4 תגובות

איך קראתי את המחקר של דפנה יואל והגעתי למסקנות הפוכות

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

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

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

יתרה מכך, ד"ר יואל מוצאת במחקרה שהפיצ'רים הללו הם בלתי-תלויים:

"Our results demonstrate that even when analyses are restricted to a small number of brain regions (or connections) showing the largest sex/gender differences, internal consistency is rare and is much less common than substantial variability."

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

אז למה מתכוונת פרופ' יואל כשהיא אומרת ש"אין דבר כזה מוח נשי או גברי"?

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

"Our conclusion that substantial variability is much more common than internal consistency in the human brain may have implications for current theories of the sexual differentiation of the brain and, in particular, for the classic view that the female brain is the default pathway and the male brain is a differentiation away from that default."

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

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

Screenshot from 2016-01-04 14:28:28

ההתפלגות של "החומר האפור" אצל נשים (באדום) וגברים (בירוק) בשני איברים שונים במוח. מתוך המאמר של דפנה יואל.

 

לקריאה נוספת:

[1] Sex beyond the genitalia: The human brain mosaic. Daphna Joel et. al. PNAS 2015 [link]

 

פורסם בקטגוריה machine learning | 2 תגובות

אנדריי קארפאת'י והיעילות הלא-סבירה של רשתות ניורונים

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

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

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

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

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

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

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

מבחינה סכמטית ניתן להציג זאת כך:

מתוך הפוסט של קארפאת'י

האותיות שמוקלדות הן הבלוקים האדומים, בהם כל אות מיוצגת כוקטור עם '1' במיקום של האות באלף-בית ו-0 בשאר המקומות. בדוגמה הזו באלף-בית יש רק 4 אותיות (h, e, l, o). התוכן של הזיכרון הפנימי, בבלוקים הירוקים, הוא וקטור 3-מימדי, והוא משתנה אחרי כל הקלדה כפונקציה של האות שהוקלדה והערך הקודם של הזיכרון. לאחר מכן התחזית לאות הבאה, בבלוקים הכחולים, מחושבת כפונקציה של הזיכרון הנוכחי. היינו רוצים שבבלוקים הכחולים המספרים הירוקים (במיקום של האות הבאה) יהיו גבוהים והאדומים נמוכים, וכך אנחנו מאמנים את הרשת. [התמונה מתוך הפוסט של קארפאת'י]

למעשה, כל הבלוקים הירוקים מבצעים בדיוק את אותו החישוב ובעצם יש להם שני קלטים ושני פלטים. הקלטים הם תוכן הזיכרון הקודם והאות הנוכחית, והפלטים הם תוכן הזיכרון המעודכן והחיזוי לאות הבאה. וכל שנותר הוא ללמוד את הפרמטרים של החישוב שממפה את הקלטים אל הפלטים (בדוגמה הם מסומנים כ-W_xh, W_hh ו-W_hy) בצורה שגורמת לטקסט להתכווץ כמה שיותר. למודל הזה קוראים באנגלית Recurrent Neural Network או RNN בקיצור.

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

מתוך XKCD

מתוך XKCD

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

bible1

bible2

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

אז עכשיו בואו ננסה להיכנס לנבכי הרשת ולהבין מה היא כותבת בזיכרון הפנימי שלה. נסיון לעשות reverse engineering לוקטור הזיכרון הפנימי [1], גילה שיש שם אלמנטים שמציינים אם כרגע יש סוגריים או מרכאות פתוחים (כמו עכשיו, כדי שנעלה את הסבירות לכך שהסוגר שלהם יגיע בקרוב… הנה), אם אנחנו בתוך טקסט שהוא לינק לאתר אחר, אם אנחנו קרובים לסוף שורה או שזה זמן טוב ללחוץ "אנטר" ולעבור לשורה הבאה (למשל אחרי נקודותיים). כשמזינים למערכת קוד C, יש תאים בזיכרון שמציינים אם הקוד הוא חלק מתנאי if, אם הוא חלק מהערה, ואת עומקו של ה-scope הנוכחי. כל אלו דברים שבאמת נראה הגיוני שצריך להיות מודעים אליהם כשכותבים טקסט או קוד תוכנה.

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

לקריאה נוספת:

[1] Visualizing and Understanding Recurrent Networks. Andrej Karpathy, Justin Johnson, Fei-Fei Li. Arxiv 2015.  [link]

פורסם בקטגוריה deep learning | עם התגים , , , | 3 תגובות

על תכנות הסתברותי – הסיפור כתוכנה

כשהסברתי לראשונה מה זה "מודל יצירתי", תיארתי זאת כך:

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

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

אחת השפות החלוצות בתחום נקראת Church. היא פותחה ב-MIT של ידי Noah Goodman (היום בסטנפורד) ו-Josh Tenenbaum, במקור דווקא כדי לבחון בקלות מודלים הסתברותיים של קוגניציה.  השפה ש-Church מתבססת עליה היא LISP הידועה לשמצה (שפה פונקציונלית, הידועה בכמות הסוגריים הגדולה שבה).

דוגמה: מה הביטוי המתמטי עבור פונקציה (f(x שעבורה נמדד ש-  f(1) = 5 ו- f(2) = 3  ?

לשם כך ניצור תוכנית שמייצרת באופן הסתברותי ביטוי מתמטי, פונקציה של משתנה x, ומפעילה אותו על הערכים x=1 ו-x=2. הבנייה נעשית באמצעות הילוך בדקדוק הסתברותי ורקורסיבי (pcfg). כל ביטוי הוא אחת מהאפשרויות הבאות:

  1. (בסיכוי 40%) מספר שלם בין 1 ל-10, שנבחר אקראית.
  2. (בסיכוי 30%) המשתנה x.
  3. (בסיכוי 30%) הלחם של שני ביטויים אחרים, כשכל אחד מהם מוגדר באופן רקורסיבי, והחיבור נעשה באמצעות אחת הפעולות פעולות החשבון (+-) שנבחרת באופן אקראי.

הנה הקוד בשפת Church:

(define random-expression
(lambda ()
(define expression-type (sample-discrete (list 0.40 0.30 0.30)))
(cond
((= expression-type 0) (sample-integer 10))
((= expression-type 1) 'x)
(else
(list (uniform-draw '(+ -)) (random-expression) (random-expression))))))

כך, למשל, כדי לקבל את הביטוי (x + (x – 2 היה צריך להלחים שני ביטויים עם חיבור (30%*50%), לבחור x עבור הביטוי השמאלי (30%), ובשביל הימני להלחים שני ביטויים עם חיסור (30%*50%), השמאלי מבינהם x (סיכוי 30%), והשני 2 (40%*10%). סך הכל סיכוי של 0.008%.
 

נשים לב שיש עוד ביטויים שקולים לביטוי (x + (x – 2, למשל

((((x + x) – 2) + x) – x)

אבל ההסתברות ליצירת הביטוי הזה שונה (ונמוכה יותר).

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

אז זהו, שכל פלטפורמת תכנות הסתברותי מצויידת במנוע היסק אוטומטי, שאם הוא עובד כמו שצריך זה אומר שבזה שתיארתם את הסיפור באמצעות קוד תוכנה, עשיתם כבר 90% מהעבודה.  ה-10% הנותרים זה לספק לתוכנה את הנתונים שלכם, ומפה התוכנה כבר תסיק מה התסריטים הסבירים ביותר שיכלו ליצור את הנתונים הללו. באופן יותר פורמלי, התוכנה תדגום תסריטים מההתפלגות (data | תסריט)P.

אם נמשיך את הדוגמה שלהלן, נניח שאני מחפש את הביטוי של פונקציה f שעבורה:

f(1) = 5     ;f(2) = 3

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

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

(define (sample)
(rejection-query

; Randomly generate a new f for the sample.
(define f-expr (random-expression))
(define f-proc (eval (list 'lambda '(x) f-expr)))

f-expr ; The variable we are interested in.

; All samples must satisfy:
(and (= (f-proc 1) 5) ; f(1) = 5
(= (f-proc 2) 3) ; f(2) = 3
))

(apply display (repeat 20 sample)) ; Generate 20 samples.

אתם יכולים לנסות להריץ את הקוד הנ״ל באתר הזה.

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

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

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

גישה נפוצה אחרת נקראת "סינון חלקיקים", או Particle Filtering בלעז.

במקום לייצר את החלקיקים אחד אחרי השני, הגישה הזו מייצרת את כולם במקביל. לצורך כך, קובעים מראש שיש לנו M חלקיקים. מתחילים בכך שמריצים את התוכנה ההסתברותית שכתבנו במקביל (כן, המהדרין עושים את זה ממש על processים שונים!). כך מריצים עד שמגיעים לצומת ההחלטה הראשון, ובו כל חלקיק קיבל החלטה הסתברותית. כעת מסתכלים על ה-data הרלוונטי להחלטה זו, ונותנים לכל חלקיק משקל בהתאם לסבירות של ה-data בהינתן ההחלטה. קיבלנו M חלקיקים ממושקלים. מנרמלים את המשקלים כך שסכומם שווה 1, וכך קיבלנו התפלגות על M החלקיקים. מגרילים מתוכם את הדור הבא של החלקיקים –  M חלקיקים חדשים (עם חזרות). כך, חלקיק עם משקל גבוה יקבל ייצוג מוגבר בדור הבא. כעת ממשיכים להריץ את התוכנות בכל חלקיק במקביל עד נקודת העצירה הבאה, וחוזר חלילה.

הפלטפורמות החדשות ביותר של תכנות הסתברותי חצו את הקווים: מביצוע סימולציות של הרצות מקביליות מתוך כלי מחקר כגון MATLAB, הם ממש משתמשים ביכולות של מערכת ההפעלה לניהול processים מקביליים ואח"כ לסנכרון בינהם. כתוצאה מכך חלק גדול מה-overhead יורד ורמת הביצועים עולה. בין החידושים האחרונים בתחום יש שפת תכנות הסתברותי מבוססת-C.

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

לקריאה נוספת:

שפת צ'רץ':

Noah D. Goodman and Joshua B. Tenenbaum. Probabilistic Models of Cognition.  https://probmods.org/index.html

MCMC בתכנות הסתברותי:

David Wingate, Andreas Stuhlmüller, Noah D. Goodman. Lightweight Implementations of Probabilistic Programming Languages Via Transformational Compilation. [pdf]

Particle Filtering בתכנות הסתברותי:

Frank Wood, Jan W. van de Meent, Vikash Mansinghka. A New Approach to Probabilistic Programming Inference. [pdf]

שפת C הסתברותית:

Brooks Paige, Frank Wood. A Compilation Target for Probabilistic Programming Languages. http://www.robots.ox.ac.uk/~brooks/probabilistic-c/

פורסם בקטגוריה Uncategorized | תגובה אחת