תמיר נווה

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

הכרות פרקטית ל Machine Learning מומחשת עם בעיה מהעולם הפיננסי

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

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

ראשית אסביר מה הכוונה לפתור בעיה זו שלא באמצעות Machine Learning, כדי להבין טוב יותר מה זה בכלל Machine Learning.

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

אילו היינו מנסים לנבא את סיכוי החזר ההלוואה שלא באמצעות Machine Learning היינו בונים כנראה כמה תנאים המבוססים על הידע שלנו כבני אדם או יותר טוב כאנשי מקצוע פיננסיים. (מה שנקרא Feature Engineering)

למשל: אם גובה ההלוואה גדול מ 100,000 ש”ח וההכנסה השנתית של מבקש ההלוואה קטנה מ 80,000 ש”ח אז הסיכוי 0.5, אחרת הסיכוי תלוי גם במאפיינים נוספים ולכן נבדוק גם את ממוצע עיסקאות האשראי ואז אם…

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

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

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

כשמאמנים מודל Machine Learning על Database שכזה זה נקרא Supervised Learning (לימוד מפוקח) כיוון שאנחנו כאילו “מפקחים” על המודל בזמן הלמידה. אם אלו המאפיינים של מבקש ההלוואה אזי זה מה שקרה איתו (החזיר\לא החזיר את ההלוואה). אילו היו בידינו את המאפיינים ולא את התוצאה (החזיר\לא החזיר) אז היינו בעולם ה Unsupervised Learning.

בעולם ה Supervised Learning (ז”א כשיש לנו את התשובות הנכונות) ישנם מודלים רבים המסוגלים ללמוד את הנתונים ואז לקבל נתונים חדשים (קרי מבקש הלוואה חדש שאיננו יודעים אם אכן יחזיר או לא) ואז המודל ינבא את יכולת ההחזר הלוואה שלו. כמובן יש מודלים המצליחים יותר ויש פחות – אין כמעט אף פעם 100% הצלחה. אבל אם מודל מאומן מנבא בהצלחה של נניח 70% זה כבר עשוי לחסוך כסף רב לבנק. (בטח לעומת החלופה של לאשר לכולם הלוואה)

אז כעת נכיר שני מודלים פשוטים ופופולאריים בעולם ה Supervised learning שנקראים KNN ו Logistic Regression. אך לפני זה נכתוב בצורה מפורשת איך נראים הנתונים שלנו.

הכרת הנתונים

כאמור בדוגמה שלנו הנתונים שלנו הם אוסף של מבקשי הלוואות ולכל אחד מהם 86 מאפיינים (את זה נהוג לסמן ב X1,X2,X3,…,X86 או פשוט כוקטור X) ולכל מבקש הלוואה כזה את התשובה הנכונה (שנקראת ה label ואותה נהוג לסמן ב Y) ז”א האם החזיר את ההלוואה (ניתן לזה ערך 1) או לא החזיר את ההלוואה (ניתן לזה ערך 0). הטבלה הבאה ממחישה נתונים לדוגמא:

משכורת חודשית (X1)גובה משכנתא (X2)גיל (X3)ותק בבנק (X86)החזיר\לא החזיר (Y)
10,000350,000374.51
17,00004121
13,000100,0003530

מודל KNN

השם המלא של המודל הינו K Nearest Neighbor והשם מלמד על הרעיון שבו: ניבוי באמצעות הצבעה של K דוגמאות דומות לדוגמה הנבדקת.

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

נקבע את K  להיות ערך שלם כלשהוא, נניח 5.

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

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

למי שקצת יודע לכתוב קוד אז פייתון היא שפת התיכנות אולי הכי פופולארית בעולם ה Machine Learning וספציפית יש חבילה שנקראת Sklearn שבה ממומש KNN ועוד מודלים רבים של Machine Learning.

אז שתי שורות קוד מבצעות את הרעיון הנ”ל:

model = KNeighborsClassifier(n_neighbors=5)

model.fit(x, y)

אותו K ממקודם נקרא מספר השכנים n_neighbors השכנים, הנתונים שברשותינו נקראים x והתשובות הנכונות שברשותינו נקראים y.

שתי שורות הקוד הנ”ל הם ההכנה ונקראות התאמת או אימון המודל לנתונים. ושורת הקוד הבאה משתמשת במודל המאומן כדי לנבא החזר או אי החזר הלוואה על מבקש הלוואה חדש x_new:

model.predict(x_new)

מודל Logistic Regression

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

logistic regression

(אקספוננט של צירוף לינארי על הנתונים עם מקדמים β‘s ייתן את היחס בין ההסתברות להחזר ההלוואה לבין אי החזר ההלוואה)

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

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

ושוב ניתן להשתמש בזה באופן דומה למקודם באמצעות שתי שורות קוד בפייתון (עם חבילת Sklearn), אימון המודל (קרי מציאת המקדמים על בסיס נתונים ולייבלים קיימים x,y):

()model = LogisticRegression

model.fit(x, y)

ושימוש במודל כדי לנבא יכולת החזר של מבקש הלוואה חדש:

model.predict(x_new)

דוגמת קוד

בקישור הזה יש קוד מלא מא’ עד ת’ שממחיש טעינה של נתונים לדוגמא ואימון שני המודלים המדוברים על הנתונים. (הנתונים לקוחים מכאן)

להלן עיקרי הקוד עם הסברים:

  1. חבילות פייתון שיש להשתמש בהם

import pandas as pd

from sklearn.preprocessing import StandardScaler

from sklearn.linear_model import LogisticRegression

from sklearn.neighbors import KNeighborsClassifier

2. טעינת הנתונים

train_df = pd.read_csv(Path(‘2019loans.csv’))

test_df = pd.read_csv(Path(‘2020Q1loans.csv’))

טכניקה שקיימת בכל עולם ה Machine Learning הינה פיצול הנתונים שלנו לשתי קבוצות:  קבוצת האימון (train) וקבוצת הבדיקה\ואלידציה (test).

בנתונים מקבוצת האימון נשתמש לאמן את המודל ובנתונים מקבוצת הבדיקה נשתמש לבחון את הצלחת המודל המאומן.

שתי הקבוצות חייבות להיות נפרדות (ללא חפיפה כלל) ועל שתיהן לייצג נאמנה את המציאות.

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

3. שליפת הנתונים והלייבלים

הנתונים שלנו לקוחים מקבצי אקסל ועלינו להפריד בין מאפייני מבקשי ההלוואות (x) לבין התשובה הנכונה (ה label שלהם) ז”א האם אישרו להם הלוואה בסופו של דבר או לא  (y).

y_train = train_df[“loan_status”]                       # Take target feature for training data

X_train = train_df.drop(columns = [“loan_status”])      # Drop target from training data

:Same for testing #

y_test = test_df[“loan_status”]

X_test = test_df.drop(columns = [“loan_status”])

4. המרת משתנים קטגוריאליים

חלק מאותם 86 מאפיינים לכל מבקש הלוואה אינם משתנים מספריים אלא קטגוריאליים. ז”א הערך הוא אחד מבין כמה ערכים מוגדרים מראש. למשל מאפיין בעלות הבית (home_ownership) הינו אחד מבין: MORTGAGE, OWN  או RENT.

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

X_train = pd.get_dummies(X_train) 

X_test = pd.get_dummies(X_test)

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

home_ownershiphome_ownership_RENThome_ownership_MORTGAGEhome_ownership_OWN
RENT100
MORTGAGE010
OWN001

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

5. נירמול הנתונים

אחת הפעולות שנהוג לעשות על הנתונים בהרבה מודלים של Machine Learning זה לנרמל אותם ולהביא אותם לאותה סקאלה על ערכים מספריים (לרוב נהוג בין אפס לאחד).

הסיבות לזה הם בעיקר נומריות, והנירמול גורם למודלים רבים להתכנס יותר טוב:

()scaler = StandardScaler

scaler.fit(X_train)

X_train_scaled = scaler.transform(X_train)

X_test_scaled = scaler.transform(X_test)

6. אימון המודלים ובדיקתם

נתחיל במודל KNN כפי שראינו מקודם, הגדרת המודל:

model = KNeighborsClassifier(n_neighbors=12)

אימון המודל:

model.fit(X_train_scaled, y_train)

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

train_accuracy = model.score(X_train_scaled, y_train)

ויותר חשוב מזה, בדיקת המודל על קבוצת הבדיקה:

test_accuracy = model.score(X_test_scaled, y_test)

ובאותו אופן מודל ה Logistic Regression הגדרה, אימון ובדיקות:

model = LogisticRegression(max_iter=1000)

model.fit(X_train_scaled, y_train)

train_accuracy = model.score(X_train_scaled, y_train)

test_accuracy = model.score(X_test_scaled, y_test)

7. תוצאות הבדיקות

תוצאות מודל KNN הינן:

Train Accuracy: 0.708128078817734

Test Accuracy: 0.5133985538068907

דיוק הפרדיקציה (הסתברות החזר ההלוואה) בקבוצת האימון הינה בערך 70% ובקבוצת הבדיקה 51%. ז”א שהמודל אכן למד משהו (כי 70% הצלחה זה לא מקרי) אבל זה לא עוזר לנו בכלום כי על מבקשי הלוואה אחרים שלא השתמשנו בהם באימון הוא כלל לא מצליח (מצליח ב 50% שזה כמו לנחש סתם).

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

לעומת זאת, תוצאות מודל ה Logistic Regression הינן:

Train Accuracy: 0.7128899835796387

Test Accuracy: 0.7205444491705657

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

בזאת סיימתי לתת כניסה קלה ופרקטית לעולם ה Machine Learning, אם היה מוצלח ומועיל בעינכם ותרצו עוד כאלו, מוזמנים להגיב בהתאם 😊

Posted by תמיר נווה in deep

אלגוריתם Reinforce – Vanilla Policy Gradients

מיועד ל- מטיבי לכת (כתבה מאוד טכנית)

נכתב על ידי תמיר נווה

כשמתפרסם מאמר ב Science  בתחום שלי (Machine Leaning) זה משהו מיוחד כי זה לא קורה כל יום.

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

בימים אלו אני בונה קורס חדש (Reinforcement Learning), והחלטתי גם לסדר את החומרים לפוסט שיאמלק לכם את הבסיס האלגוריתמי לחידושים אלו.

לא הצלחתי למצוא תירגום טוב למונח: גראדיאנטים של מדיניות (אשמח לעזרה…)

אבל Policy Gradient הינה גישה אלגוריתמית לפתירת בעיות Reinforcement Learning שנגזרו ממנה אלגוריתמים רבים כגון: Actor Critic, A2C, A3C, TRPO, PPO, SAC ועוד ועוד…

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

רקע קצר על למידה באמצעות חיזוקים (Reinforcement Learning)

יש סוכן (Agent) שחי בסביבה דינאמית (Environment) ויש לו סט של פעולות (Actions) שהוא יכול לעשות בסביבה. הפעולות שלו עשויות לשנות את המצב (State) של הסביבה, ועל כל פעולה שלו הוא עשוי לקבל פידבק מהסביבה שנקרא תגמול (Reward) שיכול להיות חיובי או שלילי. מטרתינו למצוא את המדיניות (Policy) שהינו אלגוריתם שמחליט בעבור הסוכן איך לפעול בסביבה (איזו פעולה לבחור בכל רגע) באופן כזה שיביא למקסימום ההחזר (Return) שזה סך כל התגמולים שמקבל הסוכן.

השפה המתמטית לתיאור בעיה זו היא תהליך החלטות מרקובי MDP=Markov Decision Process:

מקור: https://he.wikipedia.org/wiki/%D7%AA%D7%94%D7%9C%D7%99%D7%9A_%D7%94%D7%97%D7%9C%D7%98%D7%94_%D7%9E%D7%A8%D7%A7%D7%95%D7%91%D7%99

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

עידן הלמידה העמוקה חולל מהפיכה גם בתחום ה Reinforcement Learning במובן הזה שרשת נוירונים עמוקה מהווה את המדיניות (Policy), ז”א מקבל כקלט את ה State ומחזירה את הפעולה (Action) הרצוייה.

כעת חלק הכיפי,

פורמליזם מתמטי לתיאור הבעיה

בכל נקודת זמן t יש לנו מצב, פעולה ותגמול:

ומאחורי הקלעים קיימת פונקציית הסתברות המעברים בין המצבים:

שמשמעותה: מה ההסתברות שאם התחלנו במצב St והסוכן בחר לבצע פעולה At הסביבה עברה למצב St+1.

למשל אם הסוכן שלנו הוא רכב, המצב שלנו הוא מיקומו במרחב (x,y) והפעולה היא לקחת הגה ימינה, מה ההסתברות שהרכב יעבור למצב (x+5,y). אז בהסתברות גבוהה זה יקרה. אבל לא תמיד זה יקרה כי אולי יש שמן על הכביש והפעולה הביאה את הרכב למצב אחר (x+500,y).

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

מסלול (Trajectory) סופי הינו וקטור של השלשות הבאות:

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

כל אחד מהאלמנטים במסלול 𝜏 הינו וקטור אקראי, וההסתברות לקבל מסלול שלם הינה:

ההסתברות לקבל מסלול 𝜏 היא מכפלת ההסתברות להיות במצב הראשון S1 כפול

 ההסתברות לבחור פעולה A1 כפול ההסתברות לעבור למצב S2 כפול ההסתברות לבחור פעולה A2 וכו’…

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

פונקציית המטרה שלנו J שאותה נאפטם (ז”א נשאף למצוא לה מקסימום) הינה התוחלת של סכום התגמולים:

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

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

נשים לב ש  כולל בתוכו למעשה גם את  על אף שהסימון אינו מייצג זאת.

מדוע לא פשוט לאמן מודל עם פונקציית מטרה?

התחום Reinforcement Learning אומנם יושב תחת המטריה הרחבה של עולם ה Machine Learning אבל הוא אינו Supervised Learning וגם אינו Unsupervised Learning כי זה לא שיש לנו Ground Truth של אילו החלטות היה הסוכן אמור לבחור בכל צעד שלו, אבל מצד שני גם לא יהיה נכון לומר שלא קיים ברשותינו מידע לגבי מה נכון ומה לא כי יש לנו את התגמולים. ולכן זה מן תחום כלאיים בין Supervised לבין Unsupervised.

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

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

כידוע בלמידה עמוקה משתמשים ב Gradient Descent (או בשיכלולים שלו) כדי לאמן את המודל:

אם כן ננסה לגזור את פונקציית המטרה שהגדרנו מקודם לפי משקלי המודל:

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

אז מה עושים בכל זאת ?

מכיוון שלכל f(x) מתקיים:

נוכל להשתמש בזה לטובתינו:

ולקבל:

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

נשים לב שההסתברות לקבלת מסלול   תלויה ב θ אבל סך התגמולים  אינו תלוי ב θ עבור מסלול מסויים 𝜏.

הטריק הזה שהוסיף לנו log עזר לנו להמנע מנגזרת של מכפלות.

נזכור שההסתברות לקבל מסלול היא מכפלת ההסתברויות של המעברים בתוך המסלול:

וכשמפעילים על מכפלות אלו לוג זה הופך לסכומי הסתברויות:

ואז הגרדיאנט שלנו לפי θ נהיה פשוט יותר כי כל מה שלא תלוי בו מתאפס:

 

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

 

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

 

כאשר i רץ על פני כל ה trajectories שהקלטנו ו t הוא האינדקס בכל trajectory.

 

פירוש לתוצאה:

המרכיב השמאלי בביטוי הוא ה Maximum Likelihood של ההסתברות  ז”א הוא מבטא איך לעדכן את המשקולות כדי שבסבירות גבוהה יותר הסוכן יעבור את המסלולים שאגרנו.

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

צעד אחרון לפני מימוש

אז אפילו שיש נוסחה שימושית מפורשת לקח לי לא מעט זמן להבין קודים לדוגמא המממשים Vanilla Policy Gradient (אלגוריתם Reinforce), ורק בזכות הקורס של ברקלי הבנתי שאם מניחים התפלגות נורמלית למדיניות ומשתמשים בפרדיקציה של הרשת  fלהיות וקטור התוחלות:

אז עידכון המשקולות נהיה בפועל:

 

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

 

לשם הפשטות נתעלם ממטריצת הקוואריאנס ומהחצי המופיע בביטוי. (נניח שמטריצת הקוואריאנס הינה מטריצת היחידה וממילא החצי נבלע ב Learning Rate):

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

וכעת כשמסתכלים על מימושים הכל נראה ברור יותר… לא כך ?

מקורות

Posted by תמיר נווה in deep

הפוטושופ של המובייל

המרואיין: דרור יפה מייסד ומנהל פיתוח

רקע

התחלנו ב 2012 בתקופה בה המצלמה רק הצטרפה לטלפון, ומטרתו עד היום לייצר כלי נוח לעריכת תמונה במובייל. ההשראה מגיעה מפוטושופ והמצאנו מחדש כמה קונספטים למובייל (בין השאר Touch Screen במקום עכבר) ויצרנו חוויה יותר פשוטה ויותר עוצמתית. יש לנו מיליוני משתמשים בכל חודש שיוצרים מגוון יצירות ולכן יש לנו נגישות לדאטאסטים בתחום עיבוד התמונה, כמובן תחת מגבלות Privacy.

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

 

כמה אנשי פיתוח ? איך מחולקים ?

6 אנשי פיתוח. כולנו בוגרי מדמ”ח, 2 אנדרואיד , 4 אייפון (אותם אנשים עושים backend, UI)

מהם המוצרים בחברה ?

אפליקציית IOS  ולראשונה השנה נשיק ב Android.

 

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

המון… למשל:

  • להיפטר מרקע מתמונה

אנו מאפשרים עבודה ב-עד מאה תמונות בו זמנית. ולכן חשוב להפטר מרקע של תמונות. יש מורכבות כי אנחנו בעצם רוצים יותר מזיהוי foreground\background אלא שיערוך alpha matting. (כדי שנוכל לשלב תמונות שונות ע”י שינוי העמימות של כל ערוץ באופן כזה שייראה טוב). בפרט מתמודדים עם instance segmentation.  

  • השלמה אוטומטית של תמונה (Healing)

משתמשים בפתרון CV  קלאסי שנקרא Patch Match. מחפשים לייעל אותו שיעבוד RT גם על תמונות גדולות 12MP ויותר.

  • יצירת תוכן\תבניות דינאמי

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

  • כמובן הרבה פילטרים ובפרט Style Transfer. פיצ’רים כמו של אפליקציית פריזמה שלוקחת תמונות של אנשים והופכת אותם לסגונות אחרים זה כמובן הפך להיות must בעולמנו.
  • יישור תמונות במרחב הצבע,ז”א Histogram Equalization אבל מתוחכם יותר…

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

מה עובד לכם טוב ? (דוגמאות לאלגוריתמים)

משתמשים Grab Cut לסגמנטציה, משתמשים ב Deeplab אחרי שהתאמנו אותו למובייל. ועוד הרבה פרטים יחסית קטנים במוצר (שלאו דווקא מורגשים ע”י המשתמשים שלנו), למשל אם יש תמונה ורוצים שהחלק המרכזי שלה יהיה בתוך עיגול. איך יודעים מהו החלק המרכזי ? משתמשים ב Salient detection של COREML.

מה מאתגר אתכם ?

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

בעיות שפתרתם בדרך יצירתית ?

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

ספר על משימת איסוף ה DB אצלכם ? (מי עושה ? מי בודק ? מי מתייג ? מי מנהל ?)

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

מהם אתגרי העתיד ?

היום אנו משתמשים בשרותים ווביים לחלק מהשירותים אבל אנחנו רוצים לממש אותו אצלנו. יש לנו הרבה אלגוריתמי ראייה ממוחשבת קלאסיים שברצונינו להמירם ל  Deep Learning. אנחנו רוצים להכנס חזק לעולם ה – Generative Models שמאפשר לנו כר נרחב של פיצ’רים. בסופו של יום המוצר שלנו עוסק באסתטיקה ובאומנות וכידוע תחום זה עובר בהדרגה לבינה מלאכותית. בישביל לעשות דברים יפה לא המשתמש הוא זה שחייב להיות מוכשר, אלא התוכנה והאלגוריתמים!

הדרישות עברו להיות מהבן אדם לתוכנה.

Posted by תמיר נווה in companies

איך מתקינים מה שצריך עבור Deep Learning עם Anaconda ?

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

הדרך הכי נוחה ונטולת התקנות לפתח Machine Learning & Deep Learning זה השירות Colab שהינו שירות חינמי של גוגל שמספק מחשב עם GPU לכל דורש והוא מאוד מומלץ למשחקים וללימודים. כשרוצים לפתח משהו קצת יותר גדול ומורכב המגבלות של Colab באות לידי ביטוי: זמן מוגבל של סשן, חוסר יכולת לשים break points על הקוד, החרדות שהקוד שלי יושב בשרתי גוגל (ולפעמים בפרויקטים בטחוניים בכלל אין לנו חיבור לרשת החיצונית) וכו’…

אז אנחנו רוצים לפתח קוד שממש יישב אצלנו, על המחשב שלנו ואנחנו מאוד חוששים מההתקנות המייגעות… (קצת בצדק…)

אם יש GPU צריך להתקין Cuda ואם חלילה אין תאימות בין הגירסאות נבין את זה אחרי המתנה של שעות התקנה שירדו לטימיון, אם בטעות בחרנו פייתון 32bits פתאום נגלה את זה אחרי שכבר סיימנו את ההתקנה כי איזשהיא package  לא מתאימה, ועוד ועוד צרות מייגעות…

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

מהן סביבות עבודה ?

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

אז למעשה סביבה היא תיקייה בה נשמרים כל החבילות בגירסותיהן השונות עם המפרש (Python interpreter)  שמאפשר להריץ קוד פייתון. גם למפרש יש הרי גירסאות שונות ואפשר להחזיק סביבת פייתון 2 וסביבת פייתון 3 במקביל.

מה עושים שלב אחרי שלב ?

מורידים Anaconda מהקישור הבא:

https://www.anaconda.com/distribution/

אחרי שמתקינים נוצר לנו Anacoda Prompt שזה כמו ה Command line הרגיל רק שמשמאל ל path הנוכחי מופיע בסוגריים שם הסביבה הנוכחית (ברירת המחדל הינה base):

אם רוצים לקבל את רשימת הסביבות הקיימות רושמים:

conda info –envs

ומקבלים (מה שיש אצלי כרגע):

אם רוצים לעבור לסביבה אחרת:

ניתן לראות ששם הסביבה הנוכחית השתנה ל (tf_gpu).

אם רוצים לקבל את רשימת החבילות המותקנות בסביבה הנוכחית:

conda list

ואם רוצים ליצור סביבה חדשה:

conda create –name XXX

ואז כל התקנה שנעשה תישמר בסביבה הנוכחית.

התקנה חדשה תיעשה ע”י

conda install XXX

או גם בדרך המוכרת:

pip install XXX

מחיקת סביבה:

conda remove –name old_name –all

שינוי שם של סביבה אי אפשר, אבל אפשר לשכפל בשם אחר ואז למחוק:

conda create –name new_name –clone old_name

conda remove –name old_name –all

לבטחוניסטיים שביננו יש אפשרות גם לבצע התקנות ללא חיבור לאינטרנט:

conda create –offline –name $NAME

 

אז לאחר שהתקנו Anaconda ויצרנו סביבה והתקנו בה את החבילות שאנחנו רוצים (למשל TensorFlow, Keras, Numpy)

השלב הבא הוא לבחור סביבת פיתוח (IDE) ולקשר אותה לסביבות העבודה אותם יצרנו ב Anaconda.

אז אדגים זאת על Pycharm, ראשית נתקין את גירסת ה-Community החינמית: (או הגירסה המקצועית בתשלום)

https://www.jetbrains.com/pycharm/download/#section=windows

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

אז סביבה כבר הגדרנו בAnaconda Prompt  ומה שנותר זה להגדיר ל PyCharm היכן יושבת הסביבה שהגדרנו מקודם. אז נלך ל Settings שם מצד שמאל נראה Project: project_name (אצלי שם הפרויקט הוא desktop)

ונלחץ על Project Interpreter:

ואז על Add ז”א הוספת סביבת עבודה:

פה נבחר סביבת Anaconda  קיימת ונזין את מיקום ה Interpreter כפי שהופיע לנו כשבנינו את הסביבה ב Anaconda Prompt (ואם שכחנו אפשר לכתו where python ב anaconda prompt  בכדי לקבל זאת שוב)

ורצוי לשים וי על Make available to all projects כדי שהסביבה הזו תהיה מוכרת לכל פרויקט עתידי גם.

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

תחת Run-Edit Configuration נבחר סביבת עבודה לפרויקט שלנו מתוך הסביבות הקיימות (אותן הגדרנו בעבר):

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

Posted by תמיר נווה in deep

סדר בניהול הריצות Machine Learning

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

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

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

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

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

מהו Neptune

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

כמובן שהכל מגובה ומאובטח.

איך משתמשים ?

ראשית נרשמים כאן ומקבליםtoken  אישי, מגדירים את ה token כמשתנה מערכת:


NEPTUNE_API_TOKEN=”…”

ואז הגישה יכולה להיות מ R או פייתון, אדגים עם פייתון.

מתקינים:


pip install neptune-client

ואז מכניסים לקוד שלכם את שלושת שורות הקוד הבאות:

 

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

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

לצורך כך הוסיפו שורות שכאלו:

neptune.send_metric(‘Variable I want to store’,var1)

neptune.send_image(‘Image I want to see while training’,img1)

כשהקוד ירוץ תתווסף שורה לרשימת ה experiments ב dashboard של Neptune עם כל המאפיינים:

התגיות מועילות כי בעוד חודש שנשכח למשל שבדקנו איך dropout הישפיע על הביצועים נחפש את כל הריצות עם התגית הזו, עוד שנה שננסה להיזכר מה הייתה הריצה הכי טובה עם מודל ה Xception למשל נחפש תגיות (שאנחנו כתבנו בשורת ה  neptune.create_experiment עם המילים best, xception)

גישה לתמונות ולגרפים

כדי לראות את נתוני הריצה נלחץ על ה experiment  הרצוי ושם כל אלמנט ששלחנו יוצג (משתנים\תמונות\גרפים וכו’). לחיצה על כל אחד תציג אותו:

השוואות בין ריצות

כשנרצה להשוות בין משתנים כלשהם מריצות שונות נסמן את הריצות הרצויות מהרשימה ונלחץ על compare.

מה שנקבל זה גרפים של המשתנים ששלחנו וכל ריצה תהיה בצבע אחר:

לסיכום

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

Posted by תמיר נווה in deep

הבינה המלאכותית שמשפרת את אנשי המכירות – GONG

המרואיין: עמרי אלוש מנהל קבוצת המחקר

כמה אנשי פיתוח ? איך מחולקים ?

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

רקע

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

אנו מתעסקים בעיקר בחברות B2B בהן תהליכי המכירה הינם מורכבים וארוכים (מספר חודשים). בעזרת המערכת שלנו תקבל תובנות כמו: “אתה צריך לדבר יותר על המתחרים, אבל בשלב מאוחר יותר בשיחה, אחרי שדיברת על הערך והפיצ’רים של המוצר לפחות ארבע דקות”. כל התובנות שלנו מתוך data אמיתי של החברה עצמה, ולא מתוך Best practices שאולי לא תופסים עבור החברה הספציפית. אנו מעבדים גם טקסט (NLP), גם Voice וגם Video.

מהם המוצרים של החברה ?

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

המערכת משלבת את הניתוחים הללו גם להמלצות לשיפור, למשל:

  • “בהזדמנות המכירה הזו עדיין לא דיברת מספיק על המחיר ואנחנו יודעים שבעיסקאות כאלו בשלב כזה מדברים על המחיר לפחות X דקות”
  • “הלקוח נשמע נלהב אך לא שואל הרבה שאלות, וזה מעורר חשד!”

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

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

בתחום ה-Speech, תימלול, חלוקה לדוברים, זיהוי ארועים (צחוק, מוסיקה), זיהוי חתימה קולית.

בתחום ה NLP זיהוי נושאי שיחה, סיווג אימיילים.

בתחום ה-Video שהינו תחום יחסית קטן והוא בעדיפות נמוכה: OCR, סיווג (איזה מסך כרגע בשימוש)

ובאופן כללי הסקת נתונים.

מה עובד לכם טוב ? (דוגמאות לאלגוריתמים)

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

אנחנו משלבים שיטות ML קלאסיות עם Deep Learning ולכל בעיה בוחרים את הפתרון המתאים ביותר אליה. למשל, אחרי התמלול של ה  Voice מתקבל טקסט חסר סימני פיסוק וכדי להקל על העיבוד כטקסט יש לנקד אותו. את הוספת סימני פיסוק אנו עושים בעזרת רשתBi-Directional LSTM (bLSTM) עם Attention.

לזיהוי המתרחש בוידאו בזמן שיחה אנחנו משתמשים ב-Convolutional Neural Network , ועוד.

מה מאתגר אתכם ?

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

בעיות שפתרתם בדרך יצירתית ?

דוגמא חמודה היא זיהוי החתימה הקולית של משתמש.

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

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

ספר על משימת איסוף ה DB אצלכם ? (מי עושה ? מי בודק ? מי מתייג ? מי מנהל ?)

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

מהם אתגרי העתיד ?

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

Posted by תמיר נווה in companies

Dataloop – המזון של תעשיית ה AI

המרואיין: ערן שלמה (CEO)

כמה אנשי פיתוח ? איך מחולקים ?

שמונה אנשי פיתוח, מחולקים לשני Front End לארבע Back End  לאחד  SDKואלגוריתמאי. ונשמח לשמוע מאנשי FrontEnd ואלגוריתמיקה.

רקע

אנחנו בונים AI שעוזר לייצר את המזון או האנרגיה לתעשיית ה AI (שהוא הרי Data מתוייג).

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

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

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

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

אנחנו מקבלים מחברות שמתעסקות ב Computer Vision מאגרי תמונות ומספקת Training Sets (ז”א תמונות מתוייגות) ואם צריך גם מודלים מאומנים.

 

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

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

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

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

מהם המוצרים בחברה ?

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

המערכת שלנו מכילה דאטאבייסים עם המון מטה-דאטא. ז”א לא רק את התמונות והתיוגים אלא גם נתונים על עבודת התיוג לכל תמונה. (משך התעכבות, תנועות עכבר, וכו…)

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

 

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

אנו חברה שלא רק מנהלת את תהליך התיוג של ה Data בפלטפורמת תוכנה נוחה אלא גם אנו מאמנים מודלים משלנו שיעזרו בניהול תהליך התיוג:

מודל שיחזה טעויות תיוג

לרוב לצוותים הללו יש איש  QA שעובר מדגמית (ביחס של 1:10) והוא יקר יותר.אנחנו מאמנים מודל להיות QA שמציע ל QA האנושי הצעות שיותר סביר שבעלות טעות ובכך לחסוך את זמן העבודה שלו.

למשל יש עשרת אלפים מלבנים של כלב\חתול שאתה בוטח בהם (כי עליהם עבר האיש QA) ובתשעים אלף אחרים אינך בוטח.אנו מאמנים מסווג לארבע מחלקות:Good/Bad Dog Annotation, Good/Bad Cat Annotation. בכדי לאמן מודל כזה ביעילות אנו עושים אוגמנטציות למשל ע”י הזזה של המלבן מדוגמאות שאתה בטוח לגביהן בכדי לקבל דוגמא של Bad Dog/Cat.

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

מודל שיחזה עלות תיוג

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

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

מודל שייעל את התיוג

 

 

אימון מודלים כדי שיציעו הצעות למתייגים כדי לייעל את התהליך. למשל אולי המודל כבר מצליח 80% במשימתו אז נשתמש בו וזה יחסוך זמן תיוג.

מה עובד לכם טוב ?

גילינו דבר מעניין:

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

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

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

מה מאתגר אתכם ?

יצרת שפה משותפת בין בני אדם למכונות שתמנע המון קשיי תקשורת

בעיות שפתרתם בדרך יצירתית ?

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

מהם אתגרי העתיד ?

בעתיד נאפשר ללקוחות לבנות Pipelnes של מודלים שלנו או של הלקוח שיכולים לעשות את החישו

בים אצלנו וכך הלקוח לא יצטרך לנהל שרתים.

Posted by תמיר נווה in companies

ניהול צי של רחפני צילום – vHive

המרואיין: תומר דניאל (CTO)

כמה אנשי פיתוח ? איך מחולקים ?

אנחנו סטארט אפ קטן וצומח, כרגע כל הפיתוח מונה 7 מהנדסים, מהם שניים עוסקים באלגוריתמים והשאר מפתחים מנוסים בתחומם – Back End, מובייל ו-Web. אנחנו עובדים במתודולוגית Agile בספרינטים מוכווני לקוח ומחשבה רבה על איכות.

מהם המוצרים בחברה ?

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

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

המוצר שלנו עתיר באלגוריתמיקה; אנחנו מפתחים אלגוריתמים גיאומטרים לתכנון והטסה של סקרי צילום אווירי מרובי רחפנים, תוך שימוש באלגוריתמי אופטימיזציה למציאת פתרון אופטימלי במהירות תחת מספר רב של אילוצים  ממספר גדול של קונפיגורציות על בסיס constraint based programming וב mixed integer programming בו האתגר הוא התכנסות מהירה.

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

מה עובד לכם טוב ? (דוגמאות לאלגוריתמים)

לדוגמא, לצורך יצירת מודל תלת מימדי מדויק נדרש לעגן את התמונות במרחב בדיוק גבוה. לשם כך מניחים בשטח אובייקטים הנקראים Ground Control Points שהמיקום שלהם ידוע ברמת דיוק גבוהה. בתהליך יצירת המודל התלת מימדי נדרש לסמן את האובייקטים בתמונות. בנינו אלגוריתם מבוסס DL, שמזהה את האובייקטים בתמונות (מבוסס על Faster R-CNN) ומאפשר לחסוך מהמשתמש שעות רבות של תיוג התמונות ולקבל מודל תלת מימדי איכותי.

מה מאתגר אתכם ?

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

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

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

בעיות שפתרתם בדרך יצירתית ?

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

ספר על משימת איסוף ה DB אצלכם ? (מי עושה ? מי בודק ? מי מתייג ? מי מנהל ?)

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

מהם אתגרי העתיד ?

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

Posted by תמיר נווה in companies

ניווט בתוך הסימפונות – BodyVision

המרואיין: דימה סזגנוב (VP R&D)

רקע

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

כמה אנשי פיתוח ? איך מחולקים ?

שני צוותי פיתוח 5-6 אנשים כל אחד. הצוותים הם feature teams – מאורגנים סביב יכולות במוצר וגם full stack במובן שהצוות מסוגל לסגור feature קצה לקצה, כולל איפיון, אלגורימים, bench tests, אינטגרציה, UI\UX, בדיקות תוכנה. הרכב הצוותים מאוד דינאמי ומשתנה לפעמים כל ספרינט.

מהם המוצרים בחברה ?

לחברה שני מוצרים:

LungVision System – הינה מערכת דימות שמאפשרת ניווט בתוך הראות ע”י הכוונה של רופא לאיזור העניין ומיקום הכלים באופן מדויק. זה נעשה באמצעות fusion  בין תמונות מסוגים שונים בזמן אמת.

LungVision Tool – הינו כלי מכני, או קטטר, שמאפשר גישה פיזית לכל נקודה בתוך הראות.

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

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

משמעות ה Fusion הינה רגיסטרציה (ע”י מציאת פיצ’רים תואמים) בין תמונות ממקורות שונים. (CT,xray,… )

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

מה עובד לכם טוב ?

אנחנו מצליחים לחבר את צוות הפיתוח לשטח ולמשתמשים באופן יום יומי.

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

אחת הבעיות למשל שאנו פותרים כדי לתכנן את הפרוצדורה היא לזהות את נתיבי האוויר שבריאות. אנו עושים סגמנטציה על סריקת ה CT ומשתמשים הן באלגוריתם קלאסי מבוסס Gradient Vector Flow והן בגישות למידה עמוקה כמו U-Net ובפרט בגירסה מתקדמת של U-Net המתאימה למקרה שלנו.

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

מה מאתגר אתכם ?

איזון בין השקעה במחקר (לטווח ארוך) לבין פיתוח (לטווח קצר)

תשתית – זמן אימון, יכולת לדבג, אירגון דאטה, העברת ידע, הדרכת צוות.

בעיות שפתרתם בדרך יצירתית ?

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

ספר על משימת איסוף ה DB אצלכם ? (מי עושה ? מי בודק ? מי מתייג ? מי מנהל ?)

צוות הפיתוח אחראי על ה-DB מקצה לקצה. אנחנו מפעילים צוות של סטודנטים שעובדים מרחוק ובשעות גמישות. משום שהרבה עבודת תיוג מבוצעת על תמונות תלת ממדיות ומצריכה ידע מיוחד (כמו אנטומיה) קיים יתרון משמעותי בהעסקה של אנשים קבועים שנמצאים קרוב ועוברים הכשרה והכוונה ע”י צוות הפיתוח.

מהם אתגרי העתיד ?

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

Scale-up של המוצר והתאמתו לקהל רחב של משתמשים – המוצר צריך להיות אמין ואינטואיטיבי לשימוש.

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

 

Posted by תמיר נווה in companies

איפה יש חניה פנויה ? Parkam

המרואיין: עופר חסון (CTO)

רקע

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

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

כמה אנשי פיתוח ? איך מחולקים ?

אנשי הפיתוח בחברה מחולקים לשלוש קבוצות: צוות פיתוח מובייל (אנדרואיד ו-iOS), צוות Datascience, וצוות הליבה (Backend, Server, Frontend).

מהם המוצרים בחברה ?

1) אפליקציית ניווט לציבור הרחב.

2) ממשק בקרה לבעלי חניונים/עיריות.

3) API לאינטגרציה עבור לקוחות שכבר יש להם מערכת בקרה קיימת.

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

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

חלק ראשון: עיבוד התמונה (Deep Learning) למטרת זיהוי חניה תפוסה/פנויה.

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

פיתחנו ארכיטקטורות Light Weight משלנו מבוססות Shufflenet בשילוב עם Squeeze-and-Excitation Networks.

כמו כן, אנו עוסקים בהבנת סצינה באמצעות  Semantic Segmentation ו- Object Detection כדי לעזור למיפוי להיות יותר אוטומטי.

חלק שני:הניווט

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

מה עובד לכם טוב ?

בהקשר של הצד ההנדסי, העבודה ב -Scale, הניהול של ה- Data והתיוג, בנינו  Pipelines אוטומטיים שעובדים יפה.

פיתחנו כלים שמאפשרים לכל צוות לעבוד בצורה עצמאית כולל Pipeline מלא עד העלאה ל Production, דבר זה גם מייעל את העבודה וגם נותן תחושת אחריות לצוותים.

הרשת שפיתחנו נותנת תוצאות מדהימות!

מה מאתגר אתכם ?

קשיים של העולם האמיתי: מצלמות מתלכלכות, זזות וכו’.

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

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

בעיות שפתרתם בדרך יצירתית ?

לבעיית זיהוי הרכב: האם זה אותו רכב או לא ? לקחנו אלגוריתם מתחום ה- Audio של זיהוי דוברים והשמשנו אותו לבעיה שלנו וזה עובד לנו טוב!

ספר על משימת איסוף ה-DBאצלכם ? (מי עושה ? מי בודק ? מי מתייג ? מי מנהל ?)

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

כשהם מסיימים זה עובר אוטומטית לצוות ה-Datascience שלנו לואלידציה.

ה-Flow שפיתחנו הוא אוטומטי ועובד ביעילות.

מהם אתגרי העתיד ?

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

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

הבינה המלאכותית שמנהלת את הפירסום באינטרנט – Amobee

המאוריין: אלון רוזנטל מנהל קבוצת ה DataSciense

רקע

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

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

לניתוח וקבלת ההחלטה המהירה הזו יש חלק ניכר לענקית אמובי.

באמובי יש צוות חזק שעוסק בעיקר ב NLP. לא מזמן זכינו במקום הראשון בתחרות Sentiment Detection ב WASA2018

כמה  אנשי  פיתוח  ? איך מחולקים  ?

קבוצת ה Datasciense של המרכז בארץ מונים 6 מפתחים.

כולם בעלי יכולות תיכנות גבוהות.

שלושה דאטאסיינס, שני מהנדסי Big Data, ואחד גם וגם.

מהם  המוצרים  בחברה ?

אתאר את עיקרי השירותים שאנו מציעים:

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

אילו חלקים במוצר מצריכים אלגוריתמיקה ?

כל השירותים שהזכרתי קודם מצריכים אלגוריתמיקה, בעיקר בתחום ה NLP ובייצוג משתמשים.

אחלק את עיקרי הפעילות שלנו לשתים:

תחום ה User Profiling עוסק בהיסטוריה של ארועים והגלישה שיש על המשתמש.

חשוב להבין שעל כל משתמש יש מגוון מקורות מידע: ההתנהגות שלו ברשת, במובייל, ובטלוויזיה.

המטרה לאפשר פילוח של המשתמשים לפי בקשה.

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

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

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

בעיות NLP קלאסיות כמו Sentiment Detection, Topic Detection בכדי להחליט איזו פרסומת תתאים

לאיזה משתמש ולאיזה עמוד.

מה עובד לכם טוב ?

הפתרונות לבעיות ה NLP שלנו השתדרגו משמעותית עם השימוש ב ,Language Modeling שזה קונספט די חדש (מהשנתיים האחרונות).

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

מה מאתגר אתכם ?

אנחנו מנסים לשפר את ה State of the art  של מודל השפה וזה מאוד מאתגר.

למשל לוקחים את הכי טוב של גוגל Bert ומשלבים עם Evolved Transformer.

בעיות שפתרתם בדרך יצירתית ?

לגבי ה Topic Classification יש דרישה מהתעשייה שהתוצאות יהיו היררכיות, ז”א במבנה של עץ. למשל:

ספורט – > פוטבול -> שחקן מפורסם

רכב – > אופנועים

        -> מכוניות מירוץ

       -> ג’יפים

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

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

כך שלמעשה מהקלט הגולמי חוזים את התת נושא.

ממש תפרנו את הרשת לבעיה וזה היה יפה!

ספר על משימת איסוף ה DB אצלכם ? (מי עושה ? מי בודק ? מי מתייג ? מי מנהל ?)

יש לנו כמות לא שגרתית של Data והשימוש בו מאוד תלוי משימה.

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

מהם אתגרי העתיד ?

  • השלמה ואחידות המידע על היוזרים שהמידעים שלהם מגיע ממקורות שונים מבוסס GAN.
  • שיפור מודל השפה כי הכל מבוסס עליו
Posted by תמיר נווה in companies

מסייע ויזואלי לתמיכה טכנית – Techsee

המרואיין: רונן רוזנברג (CTO)

רקע

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

כמה אנשי פיתוח ? איך מחולקים ?

בחברה סה”כ 47 אנשים מתוכם 22 אנשי פיתוח ומתוכם 8 עוסקים באלגוריתמים.

מהם המוצרים בחברה?

Eve –Self Service

מסייע טכני ויזואלי. זו למעשה אפליקציית מוביל\וואב שבאמצעות Computer Vision AI&Augmented Reality מסייעת למשתמש הלא טכני לבצע פעולות התקנה או תיקון למוצרים ביתיים.

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

למשל בהתקנת ראוטר חדש (unboxing) האפליקציה תזהה את הכבל שמחזיק המשתמש ותכוון אותו לחבר לשקע הנכון.

TechSee Live Contact Centers

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

סרט של לקוח שלנו שמשתמש במוצר זה:

איזה חלק במוצר מצריך אלגוריתמיקה?

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

משתמשים בין השאר ב PSPNET לסגמטציה ועשינו לה התאמות ואופטימיזציות שתעבוד מהר ומדויק גם בארכיטקטורה רזה במיוחד. לגבי מציאות רבודה (Augmented reality) כל נסיון להשתמש בחבילות תוכנה מוכנות כדוגמת ARKit/ARCore נכשל בשטח כישלון חרוץ, אז פיתחנו משהו מתקדם שמשלב AI עם הספריות הקיימות. אנו נהנים משני העולמות!

מה קל לכם? (אלגוריתמית)

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

מה קשה לכם? (אלגוריתמית)

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

בעיות שפתרתם בדרך יצירתית?

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

ספר על משימת איסוף ה DB אצלכם? (מי עושה? מי בודק? מי מתייג? מי מנהל?)

פיתחנו מגוון כלים לתיוג תמונות, חלקם אוטומטיים וחלקם ידניים.

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

מהם אתגרי העתיד?

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

Posted by תמיר נווה in companies

ניתוח תלת מימד של CT לצורך ניבוי סרטן ריאות

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

בכתבה זו אספר על בעיית עיבוד סריקות CT (שהינן תמונות תלת מימדיות) ובפרט אספר על תחרות ה-Kaggle לזיהוי סרטן ריאות: Data Sciense Bowl 2017 ועל הפתרונות המנצחים בתחרות זו מתוך ה-1972 צוותים שהשתתפו בתחרות.

האלגוריתם שזכה מקום ראשון (של צוות grt123 בתוצאה של loss=0.39975) נמצא כאן וכמובן הוציאו על זה מאמר.

תיאור הבעיה

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

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

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

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

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

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

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

לקוח מ Evaluate the Malignancy of Pulmonary Nodules Using the 3D Deep Leaky Noisy-or Network

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

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

על ה-DB

המידע שיש ב Dicom הינו צילום תלת מימדי וניתן להתייחס ולהציג אותו בעצם כמו סרטון שחור לבן (המיוצג ע”י מטריצה תלת מימדית או בהכללה טנזור). כאשר ציר הזמן הוא אחד מצירי העומק של סריקת ה-CT.

כל מכונת סריקה מייצרת סריקה בקצב דגימה שונה בציר העומק ולכן המרווח בין זוג תמונות חתך עוקבות (slice thickness) הוא שונה. וזו תופעה איתה יש להתמודד (בשלב העיבוד המקדים Pre-Processing).

הגושים (Nodules) אותם יש לחפש הינם בגודל טיפוסי של 1x1x1 סמ”ר  בעוד סריקת CT ממוצעת הינה בגודל 30x30x40 סמ”ר ולכן מדובר בחיפוש מחט בערימת שחת. אם נשווה לעולם היותר מוכר (לי) של דו מימד, זה כמו לחפש אוביקט בעל שטח של בערך 30 פיקסלים (ז”א בערך 5×5 פיקסלים) בתמונה בגודל 1000×1000. התיוג של ה DB מבוסס על שקלול אבחנות של כמה רופאים.

הרחבת DB תלת מימדי (Augmentation)

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

בעולם התלת מימדי יש לנו יותר אפשרויות של הרחבה מאשר בדו מימד.

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

אם יש בקוביה גוש, גם יהיה גוש בכל אחת מה 48 סיבובים\היפוכים שלה:

תודה ל Дейка2

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

על הפתרון שזכה במקום הראשון

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

עיבוד מקדים (Pre-Processing)

לפני השלב הראשון יש כמו תמיד עיבוד מקדים שמטרתו לייצר אחידות בין הסריקות ולהסיר את כל מה שמחוץ לריאות. העיבוד המקדים כולל המרת התמונות ל- (Hounsfield Scale=HU) שהינו נירמול רמות הצבע כמקובל בסריקות CT, המרה לתמונה בינארית (לפי סף) ומחיקת כל מה שאינו בתוך ה- Connected Component  העיקרי בתמונה (שהינו הריאות). כמו כן פעולות מורפולוגיות בכדי ליצור מסיכה (mask) שבעזרתה ניקח מהתמונה המקורית רק את אזור הריאות.

שלב ראשון – גילוי מועמדים

השלב הראשון ממומש באמצעות מה שהכותבים מכנים N-Net = Nodule Net שהינה רשת 3D RPN מבוססת U-Net אשר מחזירה מלבנים (Bounding Boxes) סביב הגושים עם סף גילוי נמוך כדי לקבל כמה שיותר מועמדים גם אם אינם משמעותיים להחלטה הסופית. רשת זו מאמנים עם הרבה אוגמנטציות (Augmentation) של היפוכים (Flips), סיבובים, שינויי גודל והזזות קטנות. אגב, על רשת ה U-Net ניתן לקרוא בבלוג זה כאן.

בשלב השני לוקחים את חמשת הגושים החשודים ביותר שאותרו בשלב הראשון ובאמצעות אלגוריתםLeaky noisy-or model (יוסבר בהמשך) מחשבים פרדיקציה לקיום המחלה. אלגוריתם זה מניח שיש “זליגה” קלה של הסתברות לקיום האירוע (המחלה) גם אם אין אף תופעה (גוש) המרמז על כך.

חפיפה בין המודלים

לכל אחד מהשלבים (הראשון והשני) יש מודל אחר. האחד מחזיר מלבנים והשני מסווג קיום או אי קיום סרטן (Detection & Classification) והאימון מתבצע לסירוגין בין שני המודלים (Epoch לזה ו Epoch לזה) כאשר עיקר המשקולות של שתי המודלים משותפים. שיטה זו עוזרת למנוע Overfitting (שהרי מקטינה את כמות המשקלים לאימון).

המודל השני (שכאמור חופף חלקית עם המודל הראשון) מוסבר בתרשים הבא:

לקוח מ Evaluate the Malignancy of Pulmonary Nodules Using the 3D Deep Leaky Noisy-or Network

חלק עליון בתרשים (a):

לוקחים את החלק המרכזי (Crop בגודל 96x96x96) מתמונת הגוש (הקוביה) שיצא מהשלב הראשון מזינים אותו לרשת ה N-Net (המודל הראשון) ולוקחים את השכבת הקונבולוציה האחרונה שלו כפיצ’ר בגודל 24x24x24x128 ממנו לוקחים רק את המרכז בגודל 2x2x2x128 עושים עליו max-pooling ונשארים עם פיצ’ר וקטור בגודל 128 לכל גוש מועמד.

חלק תחתון בתרשים (b):

ומשם עוד Fully-connected, Max-pooling, Sigmoid activation בכדי להגיע לפרדיקציה הסופית (המשקללת את המידע מחמשת הפיצ’רים של הגושים העיקריים).

שלב שני – שיקלול הנתונים של כל גוש (Leaky Noisy-or Method)

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

שיקלול שכן לוקח בחשבון את סך הפרדיקציות מכל גוש הינו Noisy-Or ההופכי למכפלת ההסתברויות של העדר סרטן: (ההסתברות שהראשון מעיד על סרטן או שהשני או שהשלישי…)

אך מה קורה אם גוש ממאיר ביותר התפספס בגילוי בשלב הראשון ?

לצורך כך משתמשים במודל ה- Leaky Noisy-or method שמניח שייתכן והפרדיקציה חיובית על אף שאף גוש לא ניבא זאת. הפרמטר Pd נלמד גם כן בשלב האימון. (ז”א הוא תלוי תמונה ולא תלוי גוש)

זה אכן המודל שהביא לתוצאה הטובה ביותר.

באימון המודלים משתמשים בין השאר ב Gradient clipping וב- Batch normalization.

על הפתרון שזכה במקום השני

לאלגוריתם (ולצוות) שלקח את המקום השני בתחרות יש שתי כתבות מפורטות של כל אחד מהמפתחים  Daniel Hammackו Julian de Wit.

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

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

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

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

מה שהם עשו זה השתמשו במאגר נתונים המקורי שממנו נגזר המאגר של התחרות שנקרא LIDC-IDRI שמכיל בנוסף לסריקות ולגושים אותם איבחנו רופאים, גם מאפיינים אותם איבחנו הרופאים לכל גוש. למשל גודל, מידת הממאירות, חיספוס וכו’… מידע זה שהוסר מהמאגר שבתחרות היווה נקודת מפתח להצלחה.

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

לקוח מ 2nd place solution for the 2017 national datascience bowl

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

טכניקת אימון אותה שווה להזכיר בה הם השתמשו נקראת Curriculum Learning. הרעיון הוא קודם לאמן דגימות קטנות ופשוטות ואז לאמן עם הדוגמאות הקשות. גישה זו אינטואיטיבית לנו הלומדים האנושיים כי תמיד הורגלנו ללמוד את הפשוט (כיתה א’) ואז כשזה מוטמע במוחנו, ללמוד את הנושאים היותר מסובכים (כיתה ב’ וכו’…). לפי התיאור שלהם הם קודם אימנו עם קוביות בגודל 32x32x32 ואז אימנו עם קוביות בגודל 64x64x64.

קישורים

  1. למי שמחפש מאגרי נתונים ובעיות בתחום הרפואי חייבים להכיר את: Grand-Challenges
  2. LUNA16  הינה תחרות לזיהוי גושים (Nodules) בכמעט אלף תמונות CT
  3. מאגר LIDC-IDRI בתחום סרטן הריאות
  4. MicroDicom – כלי חינמי מומלץ לראות Dicoms

Posted by תמיר נווה in deep

מיני-פרויקט בלמידה חיזוקית (Reinforcement Learning)

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

אז אחרי שבניתי את הרובוט הזה (ראו את התמונה בעמוד הראשי של כל הכתבות) אני רוצה להכניס לו קצת בינה ודעת…

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

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

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

קצת טרמינולוגית RL

תודה ל https://becominghuman.ai/the-very-basics-of-reinforcement-learning-154f28a79071

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

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

Episode = אפיזודה\משחק שלם. ז”א שרשרת של מעברים ממצב ראשוני כלשהוא למצב סופי כלשהוא. במקרה של המשחק המתואר זה שרשרת המצבים מתחילת המשחק עד שהכדור מוחזק ע”י הסוכן והסוכן מגיע למשבצות האדומות.

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

π=Policy = מדיניות לפיה מחליט הסוכן איזו פעולה לבחור בכל מצב. למעשה פונקציה המקבלת מצב ומחזירה פעולה. בקוד תוכלו לראות שתי גישות אותן ניסיתי (ε-Greedy או Softmax Action Selection).

Return=G = סכום התגמולים שנתקבלו החל מצמד (פעולה, מצב) ועד לסיומה של האפיזודה

Quality=Q = טבלת הערך לכל צמד (פעולה, מצב). מחושב למשל כממוצע של כל ה-G שנתקבלו עבור על צמד (פעולה, מצב). המשמעות הינה כמה מוצלחת הפעולה הזו בהינתן המצב הזה?

Value=V = טבלת הערך לכל מצב. (לעיתים משתמשים ב V ולעיתים ב Q) המשמעות הינה עד כמה כדאי להימצא במצב הזה ? (מבחינת אפשרויות לנצחון)

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

אילו יש בידינו (בידי הסוכן) את הערכים האופטימליים לכל מצב\פעולה אז ישנן מדינויות  (Policies) לפעול כמו ε-greedy או softmax action selection. הרחבה על נושא זה תמצאו בכתבה הזו.

בכתבה זו נעסוק במספר שיטות לעידכון פונקציות הערך Q או V.

שיטת מונטה קרלו

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

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

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

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

שיטת Q-Learning

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

הערך Q עבור בחירת פעולה מסויימת At במצב מסויים St (בזמן\תור t) הינו הערך שהיה ועוד קומבינציה לינארית בין התגמול שנתקבל מפעולה זו לבין הערך הגבוה ביותר שניתן לקבל בעבור המצב הבא. (ע”י השוואה בין כל הפעולות האפשריות מהמצב החדש)

ראו כתבה קודמת ממוקדת על שיטה זו.

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

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

שיטת Deep Q-Learning

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

גם כאן ניתן לפעול לפי מדיניות כלשהיא, למשל ε-Greedy או Softmax Action Selection או כל מדיניות אחרת שמשתמשת ב Q שהרשת מספקת לכל מצב. ואת הלימוד (back propagate) של הרשת מבצעים באופן דומה ל Q Learning, תוך כדי המשחק. התהליך כולו (עליו חוזרים לאורך אפיסודות\משחקים רבים) נראה כך:

  • מזינים את המצב הנוכחי לרשת ומקבלים וקטור q1 (ערך לכל פעולה אפשרית). הפעלת זו של הרשת הינה רק קדימה ז”א ללא אימון BackPropagation.
  • בוחרים פעולה ומשחקים אותה (או בעלת הערך הגבוה ממה שיצא ברשת או אקראי תלוי במדיניות)
  • מזינים את המצב הנוכחי (שהוא החדש) לרשת ומקבלים וקטור q2 (זו שוב הפעלת הרשת קדימה ז”א ללא אימון עדיין)
  • בונים וקטור פרדיקציה (שישמש לשלב האימון) באופן הבא:

לוקחים את הווקטור q1 כאשר מחליפים בו את האלמנט של הפעולה בה בחרנו ושמים שם ערך חדש לפי נוסחת ה- Q-Learning:

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

האינטואיציה לכך: מצב ייחשב מוצלח אם ניתן להגיע ממנו למצב מוצלח אחר. (כמו במשחק השחמט: אומרים “שח” כי זה מצב ממנו ניתן לנצח בתור הבא)

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

כשאימנתי לפי שיטה זו היו דרושים יותר משחקי אימון (מאשר בשיטת Q-Learning) כדי להגיע להצלחה, אני מניח שזה מכיוון שזה קצת overkill לבעיה. היתרון הגדול בשימוש ב CNN לבעיות כאלו הם כשהמצב (state) הינו תמונה (כמו במשחקי אטארי) ולא וקטור או מטריצה (תמציתית) המתארת את המצב הנוכחי במשחק. במקרים שהמצב הוא תמונה, לתחזק טבלת ערכים לכל מצב אינו ריאלי.

טיפים לניפוי הקוד

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

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

  • חישוב והצגה של גרף של כמות האיטרציות כפונקציה של מספר האפיזודות (המשחקים) אליהן אומן הסוכן אמור להיות גרף יורד. מדד זה סיפק לי מידע אם אני בכיוון הנכון בכל הרצה. במילים אחרות: ככל שהסוכן מתאמן יותר, הוא אמור לנצח יותר מהר במשחק.
  • להשוות ביצועים של סוכן שמתנהג בצורה אקראית לגמרי (כמה תורות בממוצע ינצח במשחק ?) לעומת מודל מאומן.
  • לייצר ויזואליזציה של המשחק (זה מומלץ בכל domain), לאפשר לי משחק אינטראקטיבי (ז”א שאוכל לשחק כנגדו) שיגרום לי להבין מה בכל זאת למד המודל. למשל למד אסטרטגיות כאלו שמביאות אותו לפעולות מחזוריות ולכן לתקיעות. בכל צעד שהמודל “משחק” להציג את השיקולים שלו (ז”א את ערכי ה Q  לאותו המצב)
  • להתחיל במקרה פשוט ולאט לאט לסבך אותו (זה גם מומלץ בכל domain). במקרה זה התחלתי בלוח פשוט ביותר של 2×2 כאשר מצב הפתיחה קבוע. ואז מצב פתיחה אקראי, ואז הגדלת גודל לוח המשחק, וכו’

הסבר על הקוד

את הקוד תמצאו ב GitHub שלי !

Solve_game.py זהו הקוד הראשי שפותר את המשחק לפי כל אחת מהשיטות (זה הקוד שיש להריץ).

Game.py המחלקה המממשת את המשחק עצמו, מאפשרת לאתחל משחק לפי פרמטרים שונים, להקליט משחק, לשחק (לא משנה אם אדם או אלגוריתם), להציג לוח משחק ועוד… שימו לב למטודה state_as_tensor שמחזירה את מצב המשחק כטנזור בגודל nxnx2. כאשר n הוא גודל לוח המשבצות וערוץ אחד עבור מיקום הסוכן והערוץ השני עבור מיקום הכדור ומצבו (מוחזק או לא מוחזק ע”י הסוכן)

interactive_play.py מאפשר למשתמש (אנושי) לשחק במשחק

policies.py מאפשר מדיניות משחק: אפסילון החמדן (Greedy Epsilon) או Softmax Selection. בפרט שליטה על דעיכת הפרמטר אפסילון (ε).

Deep_Q_learning.py מימוש שיטת Deep-Q Learning כמוסבר מעלה.

tabular_learning.py מימוש שיטות מונטה קרלו או Q-Learning כמוסבר מעלה.

לסיכום

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

ראו סרטון שמדגים את תהליך הלמידה: (בהתחלה משחק אקראי וככל שמתקדם האימון משחק יותר ויותר בהגיון):


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

אשמח לשאלות ופידבקים!

Posted by תמיר נווה in deep

לחולל DATA חדש כדי לשפר סיווג (הרחבת Data בעזרת GAN)

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

מה עושים כשאין מספיק Data ?

כשרוצים לאמן רשת Deep Learning ואין מספיק Data ישנם מספר שיטות מה לעשות, העיקריות הינן:

  • – Data Augmentation (למשל בתמונות: סיבובים, הזזות, הרעשות, מחיקות, שינויי הארה)
  • – הקטנת המודל
  • – יצירת DB סינטטי
  • – עזרה לאימון ע”י Data Preprocessing (למשל בתמונות Cropping מתוך הבנה מה חשוב ומה מיותר בתמונה על מנת לסווג)

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

רציתי להתעמק ולהבין למה שזה יעבוד ועד כמה זה בכלל משפר תוצאות ?

גיגול קצר הביא אותי לשני המאמרים האלו: (ששניהם אגב יצאו במרץ 2018 ואף אחד מהם לא מצטט את השני)

DATA AUGMENTATION GENERATIVE ADVERSARIAL NETWORKS

GAN-based Synthetic Medical Image Augmentation for increased CNN Performance in Liver Lesion Classification

בחרתי להתעמק במאמר הראשון מבין השניים (שנקרא בקיצור DAGAN), כי הם מצרפים לו קוד שאפילו רץ לי במכה ראשונה 🙂

בתמונות פנים הבאות ניתן לראות שהתמונות האמיתיות (לקוחות מ VGG-Face) הם רק בעמודה השמאלית הן של הגברים והן של הנשים, ובכל השאר העמודות התמונות מג’נרטות\מזויפות. (ז”א תוצר של DAGAN)

תודה ל DATA AUGMENTATION GENERATIVE ADVERSARIAL NETWORKS

איך בדיוק קורה הקסם ?

הרעיון לקבל תמונה ממחלקה מסוימת ולחולל על בסיסה תמונות נוספות מאותה מחלקה באמצעות Wasserstein GAN (שהינו שיכלול של אלגוריתם GAN).

מדובר על Database המחולק לכמה מחלקות ומטרתנו להגדיל את ה DB כדי לשפר רשת סיווג (אחרת).

הרשת שמגדילה את ה DB מורכבת מGeneratror  ו Discriminator.

רשת ה Generator מנסה לשנות\לעוות את התמונה בכל אופן שמצליחה כל עוד התמונה נשארת באותה מחלקה. רשת ה Discriminator תפקידה לקבל זוג תמונות מאותה מחלקה ולהחליט אם הם באמת שייכות לאותה מחלקה או שאחת מהן מזויפת (ז”א תולדה של ה Generator).

התרשים הבא (לקוח מהמאמר) והוא מסביר הכל:

תודה ל  DATA AUGMENTATION GENERATIVE ADVERSARIAL NETWORKS

מאמנים רשת Generator (צד שמאל בתרשים) המקבלת רעש גאוסיאני (z) ותמונה אמיתית (xi) ממחלקה c ועל בסיסם לג’נרט תמונה מזויפת (xg). ובמקביל לאמן רשת Discriminator (צד ימין בתרשים) להבדיל בין זוג תמונות אמיתי (xi, xj) ממחלקה c לבין זוג תמונות שאחת מהן אמיתית ואחת מזויפת (xi,xg) כאשר השניה (xg) נוצרה על בסיס הראשונה (xi).

בצד שמאל (הג’ינרוט) משתמשים במקודד-מפענח כאשר המפענח מקבל שירשור של הטלה לינארית ל z (הרעש המוגרל) ושל xi (התמונה האמיתית).

המימוש המוצע

הכותבים מימשו את הרעיון באופן הבא:

ה Generator (המחולק לEncoder  ול- Decoder) ממומש ע”י שילוב של UNet ושל ResNet והכותבים קוראים לו UResNet:

תודה ל DATA AUGMENTATION GENERATIVE ADVERSARIAL NETWORKS

ה Discriminator ממומש ע”י DenseNet.

סדרי גודל ותוצאות

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

הבחינה נעשתה על שלושה אתגרי קלאסיפיקציה:

האחד במאגר Omniglot שהינו מאגר של עשרות אלפי תמונות של 1623 אותיות שונות מחמישים שפות שונות בכתב יד. השני ממאגר תמונות פנים VGG-Face והשלישי ממאגר תמונות כתב יד EMNIST שהינו הרחבה של MNIST  הפופולארי.

השיפור בביצועי הקלאסיפיקציה משמעותי:

הבעיה עם Augmentation רגיל   עם Gan Augmentation 
Omniglot 69% 82%
EMNIST 73.9% 76%
VGG-Face 4.5% 12%

 

הריצה מאוד ארוכה אגב: 500 epochs על עשרות אלפי תמונות, חייבים כמה GPUים כדי להריץ בזמן סביר.

קישורים

ניתן להשתמש ב-DAGAN להרחבת DB כלשהוא של תמונות, כקופסה שחורה באמצעות הקוד הבא:

https://github.com/AntreasAntoniou/DAGAN

Posted by תמיר נווה in deep

בעיית הידיות הגונבות Multi-Armed Bandit

מיועד ל- כל אחד (כתבה לא טכנית)

נכתב על ידי תמיר נווה

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

בעולם ה Reinforcement Learning (למידה חיזוקית) ישנו סוכן Agent שחי בסביבה כלשהיא Environment ויש לו אוסף כלשהוא של פעולות Actions שיכול לעשות בסביבה. הסוכן מקבל תגמול Reward מהסביבה בהתאם לפעולותיו ובכל רגע נתון הסוכן נמצא במצב State כלשהוא. מצב (state) הינו כל האינפורמציה הידועה לסוכן (זה שמקבל את ההחלטות בכל רגע).

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

בכתבה זו אסקור בעיה בסיסית ופשוטה Multi-Armed bandit (אם טעיתי בתרגום בכותרת אנא תקנו אותי…) עם מצב state בודד ומספר קטן של אפשרויות פעולה action בכל תור (כמספר הידיות).

איך להרוויח הכי מהר שאפשר בקזינו ?

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

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

בבעיית הידיות (הקזינו) יש מצב state יחיד כי בכל רגע נתון הסוכן יודע שיש את אותם האפשרויות לפעול ואין לו מידע חדש מהסביבה (לא כולל מידע שהוא צבר מניסיונותיו). בעיות עם ריבוי מצבים הינן למשל לשחק ב GO או רובוט שלומד לפתוח דלת על בסיס מה שרואה (ז”א מה שמתקבל ממצלמה שמותקנת עליו). באלו יש המון מצבים states כי האינפורמציה מהסביבה כל רגע\תור משתנית.

בעיית הפשרה בין מחקר ופיתוח

אז במה להשקיע את הניסיונות משחק שלך (שעולות לך 5$ לכל ניסיון) ?

בלשחק במכונה מוכרת או בלחקור ולהכיר עוד מכונות ? (נקראת דילמת ה –  exploration\exploitation)

או אפילו בלהכיר יותר טוב מכונה שכבר קצת הכרנו, כי למשל אם שיחקנו במכונה ועד עתה אלו היו הזכיות שלנו:

2,5,3 אז הממוצע בינתיים הינו 3.333, ואם נשחק במכונה זו עוד הממוצע כנראה ישתנה, וככל שנשחק במכונה יותר כך “נאמין” לממוצע שיוצא לנו יותר (כי הרי אמרנו שהמכונות מכווננות על ממוצע מסוים)

הפתרון

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

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

Multi-Armed Bandit

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

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

Posted by תמיר נווה in deep

שיעור #7 – קוד של DCGAN המלל

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

את הקישור לקוד תמצאו בתחתית העמוד. ראשית הריצו את create_bench_folders ושנו את משתנה bench_name כרצונכם להיות שם התיקיה לשמירת התוצאות. קוד זה יבנה ארבע תיקיות תחת תיקיית התוצאות הראשית.

כעת ניגש לקוד הראשי main.py.

משתמש ב tensorflow  וב matplotlib ומעבר לזה שני מודלים שכתבתי שמייד נעבור עליהם. אחד מייצר את ה database הסינתטי והשני בונה את המודלים ז”א את הרשתות CNN.

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

נעבור על database.py שתפקידו לבנות את מאגר התמונות שלנו של מלבנים. ישנה פונקציה rest_img קיצור של restore image (סליחה על הבחירה הלא מלאה של שמות ועל מחסור בהערות – להבא אשתפר…) שתפקידה להחזיר מטריצה של ערכים בין -1 ל 1 לתמונה בתחום דינאמי של 0..255.

ויש את המחלקה Real_DB שבה הפונקציה החשובות הינה Get_Next_Batch. אם אנחנו ב DB_Type=0 הפונקציה תייצר batch של תמונות על בסיס תמונה קיימת, אחרת אם DB_Type=1 הפונקציה תייצר תמונות סינתטיות לחלוטין עם מספר אקראי של מלבנים בצבעים אקראיים במיקום וגודל אקראי.

ובקובץ קוד העיקרי שנקרא gan_model.py יש את הגדרת הרשתותgenerator, discriminator  ואת הפונקציה שמאמנת ושדוגמת. מהפונקציות G_inv, Sample_G_inv, Train_G_inv  ומכל מה שקשור באותו generator inverse אפשר להתעלם, זה ניסיון לא גמור שלי.

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

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

https://github.com/tamirnave/dcgan—demo-with-synthetic-db

חזור לוידאו

Posted by תמיר נווה in gan המלל

שיעור #7 – קוד של DCGAN

[wpum_restrict_logged_in]


 

מלל השיעור

[/wpum_restrict_logged_in]

בשיעור זה נעבור ממעוף הציפור על קוד המממש אלגוריתם DCGAN

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

ז”א האלגוריתם לומד ליצור תמונות מתוך חיקוי של דוגמאות שמוצגות לו מבלי להסביר לו מה זה מלבן ואיך הוא אמור להראות.

קישור לקוד:

https://github.com/tamirnave/dcgan—demo-with-synthetic-db

תמונות לדוגמא של התמונות איתן מתבצע האימון:

dcgan

תמונות מתחילת האימון:

dcgan

תמונות משלב מתקדם באימון:

dcgan

 

 

Posted by תמיר נווה in GAN

העמקה לרשת הקפסולות Dynamic Routing Between Capsules – תיאוריה

מיועד ל- מטיבי לכת (כתבה מאוד טכנית)

נכתב על ידי תמיר נווה

בכתבה זו מטרתי להסביר את התיאוריה שבמאמר “Dynamic Routing between Capsules”. למי שלא מכיר את ההקשר ממליץ לקרוא קודם את הרקע בכתבה הזו: “הרעיון מאחורי רשת הקפסולות” שמסבירה את המאמר המוקדם יותר של הינטון: “Transforming Auto-“encoders. (אם כי אפשר להבין גם הכול מכתבה זו בלבד)

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

תיאוריה

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

capsules demo

capsules demo


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

אז מהן בדיוק קפסולות ?

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

כל קפסולה מחזירה:

1. וקטור מוצא שלה (*) – שגודלו מעיד על ההסתברות לקיומו של האלמנט וכיוונו מקודד את המאפיינים שלו.

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

המשמעות של וקטורי הפרדיקציה הינם: מה לדעת קפסולה i יהיה המוצא של קפסולה j. אם נניח קפסולה i מומחית בזיהוי עיגולים ומזהה בהסתברות גבוהה עיגול בקורדינאטה (x3,y3) בתמונה, אז תנבא שקפסולה משכבה גבוהה ממנה שאחראית על זיהוי פנים תוציא כפלט פנים במיקום (x1,y1) .

כל קפסולה מקבלת:

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

(*) – וקטור תוצאה של קפסולה הינו שיקלול חכם ומנורמל של וקטורי הפרדיקציה מכל הקפסולות בשכבה שלפניה. השיקלול הזה מתואר באלגוריתם Dynamic Routing.

מהו אלגוריתם Dynamic Routing

וקטור מוצא של קפסולה הינו סכום משוקלל של וקטורי הפרדיקציה שהגיעו מהקפסולות שבשכבה הקודמת.
השיקלול ממומש באמצעות אלגוריתם Dynamic Routing ומהותו עידכון המשקלים\מקדמי צימוד (של כל אחד מאותם וקטורי פרדיקציה) באופן איטרטיבי לפי מידת ה-“הסכמה” בין וקטור פרדיקציה כלשהוא לבין וקטור התוצאה (כפי שהוא באיטרציה הנוכחית). ככל שוקטור פרדיקציה כלשהוא תואם לכיוון של וקטור התוצאה כך יגדל המקדם\המשקל שלו. מידת התאימות מחושבת ע”י מכפלה סקלרית בינהם. (הרי מכפלה סקלרית בין וקטורים בעלי אותו כיוון הינה 1 ואחרת אם הם בכיוונים שונים פחות מ-1)

תיאור האלגוריתם בין שכבת קפסולות l לבין השכבה הבאה l+1 בעבור r איטרציות ניתוב (routing):

קלט:  וקטורי הפרדיקציה של כל אחת מקפסולות i מהשכבה l לכל אחת מהקפסולות j בשכבה l+1: \widehat{u}_{j|i}

פלט: וקטור המוצא של כל קפסולה j משכבה l+1 : v_{j}

האלגוריתם:

בהתחלה אפס את כל מקדמי הצימוד  b_{i,j} 

בצע r איטרציות את שתי הפעולות הבאות: (שיקלול וקטור מוצא + עידכון משקלים)

1. v_{j}=squash(\Sigma_{i}c_{ij}\widehat{u}_{j|i})

כאשר מקדמי הצימוד בין הקפסולות מנורמלים באופן הבא:

c_{i}=softmax(b_{i})=\frac{e^{b_{i}}}{\sum_{k}e^{^{b_{k}}}}

2. עדכן את מקדמי הצימוד לפי מידת ההסכמה (המכפלה הסקלרית) בין וקטורי הפרדיקציה לוקטור התוצאה:

b_{ij}=b_{ij}+\widehat{u}_{_j|i}\cdot v_{j}

סוף!

 

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

העמקה לרשת הקפסולות Dynamic Routing Between Capsules – פרקטיקה

Posted by תמיר נווה in deep

העמקה לרשת הקפסולות Dynamic Routing Between Capsules – פרקטיקה

מיועד ל- מטיבי לכת (כתבה מאוד טכנית)

נכתב על ידי תמיר נווה

בכתבה זו מטרתי להסביר באופן מפורש ומספיק מפורט עד כדי שהקורא החרוץ יידע לממש בעצמו את המאמר “Dynamic Routing between Capsules”. למי שלא מכיר את ההקשר ממליץ לקרוא קודם את הרקע בכתבה הזו: “הרעיון מאחורי רשת הקפסולות” שמסבירה את המאמר המוקדם יותר של הינטון: “Transforming Auto-encoders. ואז את הכתבה הזו: “העמקה לרשת הקפסולות Dynamic Routing Between Capsules – תיאוריה” שמסבירה על התיאוריה שבמאמר.

פרקטיקה

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

נשים לב כי באופן כללי אלגוריתם Routing פועל בין כל שתי שכבות קפסולות סמוכות אך במימוש המוצע הוא פועל רק פעם אחת כי יש סה”כ 2 שכבות של קפסולות.

להלן התרשים של מבנה הרשת במאמר: (חייב להגיד שלקח לי זמן רב להבין ממנו מה באמת קורה באלגוריתם, מקווה שאצליח לחסוך לכם זמן זה…)

capsulenet

תודה ל Dynamic Routing between Capsules

הסבר על כל בלוק:

  • בלוק הכי שמאלי: הרשת מקבלת תמונה (של ספרה) בגודל 28×28

  • בלוק ReLU Conv1: שכבת קונבולוציה שהינה 256 פילטרים בגודל 9×9 ב stride=1 עם אקטיבציית Relu. לכן הטנזור במוצא בגודל 20x20x256.
  • בלוק PrimaryCaps: שכבת קונבולוציה שהינה 256 פילטרים בגודל 9×9 ב stride=2 עם אקטיבציית Squash (*). לכן הטנזור במוצא בגודל 6x6x256. אותו טנזור בגודל 6*6*256 אלמנטים מסודר כ 32 טנזורים בגודל 6x6x8. כל אחד מבין ה 32x6x6  וקטורים בגודל 8 כל אחד יסומן u_{i}
  • בלוק DigitCaps: שכבת Fully Connected שממומשת ע”י מטריצה W שהופכת כל אחד מה 6x6x32=1152  וקטורי u_{i} לעשרה וקטורי (פרדיקציה) \widehat{u}_{j|i} בגודל 16.

(*) – אקטיבציית squash הינה פעולה לא לינארית שהופכת וקטור Sj להפוך לוקטור Vj בגודל שבין 0 ל 1:

squash function

squash function

אם כך זו רשת CNN רגילה… איפה פה הקפסולות ?

“חבויות” פה שתי שכבות קפסולות:

  • האחת נקראת Primary Caps ומכילה 6*6*32=1152 קפסולות שכל אחת מחזירה וקטור u_{i} ממימד 8 ובנוסף מחזירה 10 וקטורי פרדיקציה \widehat{u}_{j|i} שהינם המוצא של בלוק DigitCaps. j=1..10, i=1..1152)).

וקטורי המוצא של קפסולות אלו מסודרות כ-32 לוחות כל אחד בגודל 6×6, מיקום הקפסולות בלוח ה- 6×6 פורפורציונלי למיקום (x,y) בתמונה המקורית. (ז”א למשל קפסולה במיקום שמאלי עליון בלוח 6×6 מייצג את המידע בתמונה שנמצא בפינה שמאלית עליונה)

  • השניה נקראת DigitCaps מכילה 10 קפסולות שכל אחת מחזירה וקטור v_{j} ממימד 16 (מחושבים באמצעות אלגוריתם Routing). קפסולות אלו לא מחזירות וקטורי פרדיקציה כי אין שכבה שלישית במימוש זה. (התרשים לא מראה את ה dynamic routing על אף שהינו חלק מהרשת)

מה שקצת מבלבל פה זה שמשתתפים פה באימון משתנים נוספים שכדאי שנשים לב אליהם:

כל אחד מהוקטורים v_{j} יש לסמן כ v_{j}^{r} (עם מציין לאינדקס האיטרציה) כי למעשה וקטורי r+1 מחושבים על בסיס וקטורי r.

אז מה בדיוק מאמנים פה ? מהי פונקציית ה Loss ?

פונקציית ה Loss מורכבת ממרכיב ה Margin Loss ומרכיב ה Reconstruction Loss.

מרכיב ה Margin Loss מבוסס על עשרת וקטורי המוצא v_{j} של שכבת הקפסולות השניה (DigitCaps) .

ה- Margin Loss הינו סכום עבור k=0..9  של:

capsule loss function

capsule loss function

כאשר Tk=1 אם ורק אם התמונה שהוזנה מכילה ספרה k, והפרמטרים +-m הינם ספים 0.1\0.9 בהתאמה, ו λ=0.5. (ערכים מומלצים לפי המאמר).

משמעות Loss זה בפשטות הינו תתגמל אם Vk מצביעה על הספרה של התמונה שהוזנה ותעניש אם לא.

כמו כן ישנו את מרכיב ה Reconstrucion Loss לו נותנים משקל נמוך והוא למעשה הפרש הריבועים בין התמונה המקורית לבין תמונה משוחזרת.

התמונה המשוחזרת נבנית באמצעות Decoder המורכב משלושה שכבות Fully Connceted שמקבלות את מוצא ה DigitCaps.

מרכיב ה- Reconstruction Loss אינו חובה וכשהוסיפו אותו אכן שיפר תוצאות.

קצת על הקוד

בקישור זה למשל תוכלו למצוא מימוש מלא ב TensorFlow:

https://github.com/naturomics/CapsNet-Tensorflow

הדבר הייחודי ששווה להזכיר שב Dynamic Routing יש לולאה בה כל המשתנים הם חלק מהאימון (ז”א ה Back-Propogation מעדכן אותם) הוא די מבלבל ולא סטנדרטי.

כך למשל ניתן לממש לולאה של טנזורים: (בקישור המימוש קצת שונה)

def condition(input, counter):
     return tf.less(counter, 100)

def loop_body(input, counter):
    output = tf.add(input, tf.square(counter))
    return output, tf.add(counter, 1)

with tf.name_scope(“compute_sum_of_squares”):
    counter = tf.constant(1)
    sum_of_squares = tf.constant(0)
    result = tf.while_loop(condition, loop_body, [sum_of_squares, counter])

with tf.Session() as sess:
    print(sess.run(result))

זהו להפעם… אשמח לשאלות ודיונים בנושא!

Posted by תמיר נווה in deep

רשת הInception הקיצונית: Xception

מיועד ל- מטיבי לכת (כתבה מאוד טכנית)

נכתב על ידי תמיר נווה

רקע

רשתות Inception v4 ו  Xception הינן מהרשתות הטובות ביותר כיום בזיהוי מה רואים בתמונה.

ב 2014 גוגל ניצחה בתחרות ILSVRC עם רשת GoogLeNet שהראתה לקהילה ארכיטקטורה חדשנית בשם Inception לפיה שכבות לאו דווקא חייבות להיות בטור אלא במקביל ואת תוצאותיהן משרשרים. השיטה הזו חסכה בזיכרון והביאה לביצועים הטובים ביותר דאז. מאז יצאו גירסאות נוספות שנקראות inception v2, v3, v4 או Inception-Resnet שמשלבת את הרעיון הזה של גוגל עם רעיון המעקפים של מיקרוסופט של רשת Resnet.

כל רשתות CNN=Convolution Neural Network מכילות פעולות קונבולוציה. ב 2016 יצאה רשת Xception שחידשה את פעולת הקונבולוציה ע”י כך שהיקצינה את מודל ה Inception.

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

הרשת Xception (extreme inception) מקצינה את הרעיון הזה באמצעות פעולה שנקראת depthwise separable convolution.

כותב המאמר Xception הינו François Chollet שגם ידוע כיוצר של Keras!

טכני

בקונבולוציה רגילה, בעבור טנזור בגודל 6x6x3 נצטרך kernel בגודל nxnx3. נניח n=2 אז קובית ה kernel בגודל 2x2x3 נעה בכיוון x,y בלבד על פני הקוביה הגדולה של ה 6x6x3 ובכל מעבר סוכמים את המכפלות. מימדי העומק של הטנזור ושל הגרעין שניהם שווים (לשלוש בדוגמא זו) ולכן הקוביה הקטנה לא נעה בכיוון z.

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

בפעולת ה depthwise separable convolution לעומת זאת, יש שני שלבים, באחת הקוביה הקטנה נעה בכיוונים x,y ובשניה קוביה קטנה (אחרת) נעה בכיוון z.

ישנן גירסאות מימוש שונות, לפי המימוש המקובל (למשל ב Tensorflow) קודם מבצעים קונבולוציות מרחביות  לכל ערוץ בנפרד (ז”א ה-kernel בגודל nxnx1) ואז מבצעים קונבולוציה למימד הערוץ ז”א מימד עומק (ה-kernel בגודל 1x1xc)

למשל, שורות הקוד הבאות מדגימות טנזור בגודל 6x6x3 שעובר separable conv עם פילטר מרחבי בגודל 3×3 ומכפיל את הערוצים פי 2 ועם פילטר “עומקי” שמגדיל 6 ערוצים ל 12 ערוצים:

x = tf.placeholder(tf.float32, [None, 6, 6, 3])
depthwise_filter = tf.get_variable(
‘depthwise_filter’, shape=[3, 3, 3, 2])
pointwise_filter = tf.get_variable(
‘pointwise_filter’, shape=[1, 1, 6, 12])
y = tf.nn.separable_conv2d(x,depthwise_filter, pointwise_filter,
strides=[1, 1, 1, 1], padding=‘SAME’)

 

והתוצאה הינה טנזור בגודל:

?x6x6x12

(? מייצג את גודל ה batch)

ארכיטקטורת Xception כפי במוצגת במאמר כוללת שלושה מרכיבים: middle, entry, exit  הכוללים בעיקר פעולות Seperable Conv, ReLu, MaxPooling:

תודה ל Xception

תוצאות

באותו מאמר הם מציגים ביצועים על מאגר ImageNet (מאגר של עשרות מיליוני תמונות עם אלף מחלקות).

תודה ל xception

ותוצאות על FastEval14K (מאגר של 14,000 תמונות עם 6,000 מחלקות) כאשר הרשת אומנה על JFT (מאגר פנימי של גוגל של 350 מיליון תמונות עם 17,000 מחלקות):

תודה ל xception

 

כמו כן הרשת MobileNet (רשת קלה וקומפקטית שרצה על מובייל) מבוססת על Xception.

קישורים

מימוש Xception ב Tensorflow:

https://github.com/kwotsin/TensorFlow-Xception

מימוש Xception ב Keras:

https://github.com/keras-team/keras/blob/master/keras/applications/xception.py

Posted by תמיר נווה in deep

סיסמת הפנים – רשתות קומפקטיות שרצות ללא ענן

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

רקע

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

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

תוצאות נכון להיום (אימות תמונות פנים במובייל)

ישנן רשתות קומפקטיות (מתאימות למובייל) שמוצלחות בזיהוי (לאו דווקא של פנים) כמו ShuffleNet, SqueezeNet ו MobileNetV2. אך לאחרונה יצאה רשת MobileFaceNet  שנראה שמתמחה בזיהוי הפנים.

במאמר המציג את MobileFaceNet בחנו ביצועים על מאגר התמונות LFW=Labeled Faces in the Wild המכיל 13,000 תמונות פנים שנאספו מהרשת, (in the wild הכוונה שאלו תמונות שצולמו בתנאים בלתי נשלטים, ז”א במגוון תנאי תאורה, הבעות פנים, רעשים, הסתרות, תנוחות וכו’) ועל מאגר התמונות AgeDB שגם מכיל תיוג גיל לכל תמונה.

רשת MobileFaceNet  מגיעה לדיוקים של 99.55% על LFW ו 96.07% על AgeDB. הרשת צורכת 4MB  זכרון (פחות ממיליון פרמטרים) ונותנת תשובה תוך 24 מילישניות (על מעבד של mobile) על תמונה באורך\רוחב 112 או 96 פיקסלים. (תלוי בגירסה). הגדולה של רשת זו היא שהביצועים שלה גבוהים כמו של הרשתות הגדולות והכבדות הדורשות מאות MB זכרון (שאינן מתאימות למובייל).

את הרשת אימנו על מאגר בן 10 מיליון תמונות פנים של 100 אלף סלבריטאים MS-celeb-1M.

על הארכיטקטורה של הרשת ומה החידוש בה, במאמר הבא.

מה קורה ב MobileFaceNet 

ה tradeoff בין דיוק גבוה של רשת לבין כמות פרמטרים הינו נושא מחקר פורה. אחרי שנדהמנו מהדיוקים של Alexnet ואלו שבאו אחריה נעשו ונעשים מחקרים רבים המנסים לשחזר דיוקים עם רשתות קומפקטיות. ראו למשל SqueezeNet, MobileNetV1, MobileNetV2, ShuffleNet, NasNet, Light CNN-29, LMobileNetE. הגישות של הרשתות הקומפקטיות מתבססות על טכניקות כגון bottleneck, depthwise convolution layer או מציאת רשת באמצעות reinforcement learning או גישת ה  .knowledge distillation

אימות תמונת פנים מתבצע באופן כללי בשלושה שלבים: עיבוד מקדים (preprocessing), חישוב פיצ’רים מהתמונה בעזרת רשת CNN, השוואה בין פיצ’רים של שתי תמונות פנים.

במאמר הם מנתחים את אזורי ה reception field (האזור בשכבה שמשפיע על נקודה בשכבות הבאות) של הפיצ’רים במוצא ה CNN ועל בסיס הניתוח כמו גם על בסיס ניסויים מראים שהחולשה של רשתות שרצות על מובייל היא שכבת ה averaging pooling שמתייחסת באופן שווה לכל היחידות. כיוון שלהחליף אותה ב fully connected זו לא אופציה כיוון שיעלה משמעותית את כמות הפרמטרים של הרשת, הם מציעים להחליף אותה בשכבת global depthwise convolution=GDConv. להלן הארכיטקטורה המלאה של הרשת:

תודה ל MobileFaceNets: Efficient CNNs for Accurate Real-time Face Verification on Mobile Devices

Posted by תמיר נווה in deep

החוליה שהייתה חסרה לניווט רובוטים (SLAM)

מיועד ל- כל אחד (כתבה לא טכנית)

נכתב על ידי תמיר נווה

כל פעם מדהים אותי מחדש איך deep learning משדרג ביצועים באופן דרמטי בתחומים נוספים!

הפעם אכתוב סקירה כללית על SLAM=Simultaneously Localization and Mapping ואספר על החידושים בתחום שנובעים מלמידה עמוקה.

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

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

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

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

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

האופציה הנוספת נקראת Visual-Slam (או בקיצור VSLAM) והיא מתבססת על מצלמה פשוטה ומתוך ניתוח התמונות העוקבות המתקבלות האלגוריתם משערך את מיקומו במרחב ואיך נראה המרחב בו זמנית.

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

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

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

מציאת נקודות עניין והתאמתן בין פריימים עוקבים נעשה באמצעות כלים קלאסיים של עיבוד תמונה כמוOrb,Fast, Harris, Sift, Surf .

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

אז איפה קפיצת המדרגה עקב למידה עמוקה (ובפרט Convolutional Neural Networks=CNN) ?

אלגוריתם CNN-SLAM מחדש באופן שהוא משלב בין השלשה הבאה: אלגוריתם SLAM רגיל, אלגוריתם מבוסס CNN שנותן מפת עומק (Depth Map Prediction), ואלגוריתם מבוסס CNN שמחלק את התמונה לאזורים (Semantic Segmentation) כמו ריצפה, תקרה, ריהוט, קירות וחפצים.

האלגוריתם (המשולב) הורץ על שני מאגרי נתונים מקובלים בתחוםICL-NUIM, TUM RGB-D SLAM  שמכילים מפות עומק ומסלולי תנועה של מצלמה. המאגרים נבנו או באופן סינתטי או באמצעות חיישני עומק כמו Kinect.

בהשוואת ביצועים בין CNN-SLAM לבין האלגוריתמים הטובים ביותר שיש ב SLAM המבוסס על מצלמה בודדת (Monocular SLAM): בין השאר ORB-SLAM, LSD-SLAM שעושים שיערוך מסלול וREMODE  שעושה שיערוך עומק. האלגוריתם מבוסס CNN (כתוב Ours בתרשים מהמאמר) מוביל בביצועים:

תודה ל CNN-SLAM: Real-time dense monocular SLAM with learned depth prediction

Posted by תמיר נווה in deep

הרעיון מאחורי רשת הקפסולות

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

תסכימו שזה מעורר סקרנות לשמוע את הינטון שנחשב לאחד האושיות של הלמידה העמוקה נותן הרצאה ב MIT ששמה “מה הבעיה ברשתות קונבולוציה ?”

רקע

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

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

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

סיכום המאמרTransforming Auto-encoders” (2011)

המושג קפסולה מוזכר לראשונה במאמר זה ומודגם עם ארכיטקטורה מאוד פשוטה. (ללא כל קישור לקוד)

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

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

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

הרעיון של הקפסולות פותח בהתחלה ברשת שנקראת .Transforming Auto-encoders רשת זו “מאלצת” את המשתנים הפנימיים שלה ללמוד לזהות חלקים בתמונה ואת מיקומם היחסי.

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

ב- Transforming Auto-encoders מאלצים את הרשת לקודד את התמונה לפי חלקים שלה ומיקומם היחסי.

תודה ל Transforming Auto-encoders

בתרשים זה ניתן לראות הדגמה פשוטה של הרעיון רק על הזזה. בתרשים יש שלוש קפסולות שכל אחת מהם מקבלת תמונת קלט (הסיפרה 2) והיא מורכבת משכבת מקודד Encoder (העיגולים האדומים) ומשכבת מפענח Decoder (העיגולים הירוקים). מאמנים את הרשת הזו כך שתקבל את התמונה ותחזיר אותה מוסטת ב ∆y,∆x. בנוסף לקלט התמונה גם מזינים את ההסטה ז”א את זוג הערכים ∆y,∆x. כל קפסולה מכילה רק שלושה משתנים פנימיים x,y,p שמשמעותם מיקום האלמנט (או מיקום האוביקט כולו בתמונה אם זה האלמנט שלו) וההסתברות לקיומו בתמונה. תמונת הפלט הסופית משלושת הקפסולות משקללות פלט של כל קפסולה לפי ההסתברות p שלה.

כותבי המאמר לקחו רשת מבנה כזה אך עשיר יותר (30 קפסולות, 10 נוירונים במקודד ו 20 נוירונים במפענח) ואימנו אותה על מאגר MNIST כאשר מבצעים בכל פעם הסטה אקראית של התמונה אופקית או אנכית עד כשני פיקסלים בכל פעם. הם קיבלו שהמשתנים הפנימיים x,y במוצא ה encoder תואמים להסטה של התמונה ∆y,∆x מה שאומר שכל קפסולה למדה לזהות אלמנט מסויים בתמונה במיקום מסוים. וכשישנה הסכמה על המיקומים של האלמנטים המרכיבים ספרה מסוימת אזי זו אכן הספרה המסוימת ולא אחרת.

איך התקדם מאז ?

ארכיטקטורת הקפסולות חזרה לכותרות ב 2017 במאמר של הינטון וחבריו האחרים בו הם מציעים ארכיטקטורת קפסולות יותר מורכבת ויותר חשוב מזה מציגים שיטה איך לאמן קפסולות (Dynamic Routing). ייתכן ואכתוב על כך מאמר נוסף בהמשך (תלוי בביקוש שלכם הקוראים…) אך מה שחשוב להבין זה את התוצאות שלהם. כשהשוו ביצועים של CNN קלאסי לזיהוי ספרות ב MNIST הדורש אותם משאבי חישוב בערך כמו רשת הקפסולות שלהם, ניצחה רשת הקפסולות בהסתברות הזיהוי (הגיעה ל-0.25%  שגיאה), מה גם שדרשה פחות זיכרון. (8.2M  פרמטרים לעומת 35.4M פרמטרים ב CNN אליו הושוו התוצאות)

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

Posted by תמיר נווה in deep

המפתח לאימון רשתות נוירונים – BackPropogation

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי תמיר נווה

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

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

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

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

אז תמיד בהרצאות שואלים אותי בפליאה: אבל איך המשקלים מתכווננים ? איך זה בדיוק קורה ?

כי הרי באמת שם כביכול טמון הקסם…

התשובה הינה BackPropagation (חלחול לאחור) שהינה שיטה שהייתה ידועה בכל מיני גרסאות שונות עוד משנות השישים

(ובשנות השמונים הייתה בשימוש בעולם הרשתות נוירונים).

אותו שכר ועונש שאנחנו “נותנים” לרשת נוירונים אותה אנו מאמנים נקראת פונקצית ההפסד או פונקצית המחיר (loss function) וערכה קובע עד כמה מוצלחת הרשת בתוצאותיה. תהליך האימון הינו למעשה שינוי המשקלים (הפרמטרים) של הרשת כך שפונקצית ההפסד תהיה מינימאלית. (או לחילופין שהרשת תקבל מקסימום תגמול)

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

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

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

לרב עושים זאת תהליך (אופטימיזציה) זה באמצעות Gradient Descent שמתואר ע”י המשוואה הבאה:

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

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

זהו סוד הקסם (לפחות ברמת האינטואיציה…)

Posted by תמיר נווה in deep