close menu

מה זה ADVERSARIAL TRAINING?

הולך ומתפתח תחום מדעי חדש:
"דברים שאפשר סתם להעתיק לקוד בלי להבין והם בדרך כלל ישפרו את המודל"

נקרא בכנסים גם בשם הלא פורמלי "Adversarial Training"

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

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

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

ישנן גישות רבות כדי לטפל בדוגמאות כאלה, מוזמנים לחפש: defensive distillation, feature squeezing, input denoising, adversarial detection, gradient regularization, and adversarial training.

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

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

אלגוריתם Fast Gradient Method (FGM)

בשיטה זו נייצר דוגמאות אדברסריאליות על ידי מיקסום פונקציית הלוס של המודל.
נעשה זאת באמצעות המשוואה:
x* = x + ∇x J(x, y)
כשJ הוא הלוס של המודל וכאשר `∇x J(x, y)` הוא הגרדיאנט של פונקציית הלוס ביחס ל-`x`, במרחק (נורמת l2) עד כדי אפסילון:
||x^* – x||_l2 <= ?
השימוש באלגוריתם בזמן הלמידה פשוט ביותר, "נזיז" את הדוגמאות בכל צעד אימון כך ש"יבלבלו את המודל עוד קצת":
אלגוריתם: FGM
קלט:
מודל f עם פונקציית לוס J
דוגמה אמיתית x ותיוג y
גודל ההפרעה ?
מספר האיטרציות T
מקדם דעיכה µ
פלט:
דוגמה אדברסריאלית x* כך ש x* – x||_2 ≤ ?||
קבע α = ?/T
קבעא g0 = 0 ו-x*0 = x
עבור t = 0 עד T-1:
– הצב x_t בf וקבל את הגרדיאנט ∇xJ(xt, y)
– עדכן את g_t+1 על ידי סכימת וקטור המומנטום בכיוון הגרדיאנט: gt+1 = µ * gt + ∇xJ(xt, y)/||∇xJ(xt, y)||_1
– עדכן את x_t+1 על ידי החלת הסימן: xt+1 = x*t + α * sign(gt+1)
החזר x* = x*T
קוד: (יש לינק בסוף)
class FGM():
def __init__(self, model , emb_name , epsilon):
self.backup = {}
self.model = model
self.epsilon = epsilon
self.emb_name = emb_name
def attack(self):
for name, param in self.model.named_parameters():
if param.requires_grad and self.emb_name in name:
self.backup[name] = param.data.clone()
norm = torch.norm(param.grad)
if norm != 0 and not torch.isnan(norm):
r_at = self.epsilon * param.grad / norm
param.data.add_(r_at)
def restore(self):
for name, param in self.model.named_parameters():
if param.requires_grad and self.emb_name in name:
assert name in self.backup
param.data = self.backup[name]
self.backup = {}
כדי להשתמש בו צריך פשוט ליצור אינסטנס:
fgm = FGM(model, emb_name , 1.0)
ולהפעיל אותו בכל צעד עדכון של המודל:
fgm.attack()
# use your model here
loss.backwards()
fgm.restore()

למי שמעדיף, כאן יש שימוש בו: https://www.kaggle.com/…/lastof…/roberta-large-fold0-fgm

אלגוריתם Adversarial Weight Perturbation (AWP)

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

(לא לדוגמאות האימון)

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

הקוד כאן הוא ארוך אז לא אעתיק אותו, אפשר למצוא אותו כאן: https://www.kaggle.com/code/wht1996/feedback-nn-train (פתרון מנצח לתחרות בקאגל: הטריק הזה באמת עובד)

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

אלגוריתם SiFT: Scale Invariant – Fine Tuning

(הגיע אלינו מהמאמר של דיברטה)

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

את הקוד ניתן למצוא כאן: https://www.kaggle.com/…/feedback3-eda-hf-custom&#8230;

אז במה להשתמש?

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

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

עוד בנושא: