Google I/O הוא עטיפה! התעדכן בהפעלות של TensorFlow. צפה בהפעלות

ליבה מאוחדת

מסמך זה מציג את שכבת הליבה של TFF המשמשת כבסיס Federated הלמידה , ועתיד אפשרי אלגוריתמי Federated הלא-למידה.

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

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

סקירה כללית

מטרות, שימושים מיועדים והיקף

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

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

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

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

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

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

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

כתוצאה מכך, בעוד מסגרות מופצות למטרות כלליות עשוי להציע פעולות כגון שליחה וקבלה כאבני בניין, FC מספק אובניים בניין כגון tff.federated_sum , tff.federated_reduce , או tff.federated_broadcast כך פשוט לתמצת מופץ בפרוטוקולים.

שפה

ממשק פייתון

TFF משתמשת בשפה פנימית לייצג חישובים Federated, התחביר של אשר מוגדר על ידי ייצוג serializable ב computation.proto . עם זאת, משתמשי FC API בדרך כלל לא יצטרכו ליצור אינטראקציה ישירה עם השפה הזו. במקום זאת, אנו מספקים API Python (את tff המרחב) כי עוטף כמו עקיפה בו כדרך להגדיר חישובים.

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

הנה רק דוגמה אחת; ניתן למצוא דוגמאות נוספות אלגוריתמים מנהג הדרכות.

@tff.federated_computation(tff.type_at_clients(tf.float32))
def get_average_temperature(sensor_readings):
  return tff.federated_mean(sensor_readings)

קוראים המכירים TensorFlow שאינם להוטים תמצאו מקביל בגישה זו כדי כתיבת קוד בשפת Python פונקציות שימושים כגון tf.add או tf.reduce_sum בקטע של קוד פיתון המגדירה גרף TensorFlow. אמנם את הקוד מתבטא טכני בפייתון, ומטרתו לבנות ייצוג serializable של tf.Graph מתחת, וזה הגרף, לא בקוד Python, כי מבוצע באופן פנימי על ידי ריצת TensorFlow. כמו כן, אפשר לחשוב tff.federated_mean כמו החדרת אופ Federated לתוך החישוב Federated מיוצג על ידי get_average_temperature .

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

זה מצריך שפה ומערכת טיפוסים שתופסים את רעיון ההפצה.

הקלד מערכת

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

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

  • סוגים מותחים ( tff.TensorType ). בדיוק כמו TensorFlow, יש אלה dtype ואת shape . ההבדל היחיד הוא כי עצמים מסוג זה איננו מוגבל tf.Tensor מקרי Python מייצגי תפוקות של חיילי מיחידות TensorFlow בגרף TensorFlow, אך גם על יחידות של נתונים שניתן להפיק, למשל, כפלט של מופץ פרוטוקול צבירה. לפיכך, סוג הטנזור TFF הוא פשוט גרסה מופשטת של ייצוג פיזיקלי קונקרטי מסוג כזה ב- Python או TensorFlow.

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

    בסימון הקומפקטי עבור סוגים מותחים הוא dtype או dtype[shape] . לדוגמה, int32 ו int32[10] הם הסוגים של מספרים שלמים ואת וקטורי int, בהתאמה.

  • סוגי רצף ( tff.SequenceType ). אלה הם שווים הערך המופשט של TFF של המושג הקונקרטי של TensorFlow של tf.data.Dataset ים. ניתן לצרוך אלמנטים של רצפים באופן רציף, ויכולים לכלול סוגים מורכבים.

    הייצוג הקומפקטי של סוגי רצף הוא T* , שבו T הוא הסוג של אלמנטים. לדוגמא int32* מייצג רצף שלם.

  • סוגי tuple בשם ( tff.StructType ). אלה הם בדרך של TFF של בניית tuples ואת המילון דמוי מבנים שיש מספר מוגדר מראש של אלמנטים עם סוגים ספציפיים, בשם או ללא שם. חשוב לציין, המושג tuple הנקרא של TFF מקיף את המקבילה המופשטת של tuples הטיעונים של Python, כלומר, אוספים של אלמנטים שחלקם, אך לא כולם נקראים, וחלקם מיקומיים.

    בסימון קומפקטי עבור tuples בשם הוא <n_1=T_1, ..., n_k=T_k> , שבו n_k הם שמות אלמנט אופציונלי, ו T_k סוגים אלמנט. לדוגמה, <int32,int32> הוא סימון קומפקטי עבור זוג מספרים שלמים ללא שם, ו <X=float32,Y=float32> הוא סימון קומפקטי עבור זוג צף בשם X ו- Y שעשויים לייצג נקודה על מטוס . Tuples יכול להיות מקונן וכן מעורב עם סוגים אחרים, למשל, <X=float32,Y=float32>* יהיה סימון קומפקטי עבור רצף של נקודות.

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

    בסימון הקומפקטי עבור פונקציות הוא (T -> U) , שבו T הוא הסוג של ויכוח, ו U הוא הסוג של התוצאה, או ( -> U) אם אין ויכוח (למרות פונקציות ללא ויכוח הם מנוונים מושג שקיים בעיקר רק ברמת Python). לדוגמא (int32* -> int32) הוא סימון עבור סוג מסוים של פונקציות מפחיתי רצף שלם לערך שלם בודד.

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

  • סוג המיקום. סוג זה אינו חשוף עדיין ב- API הציבורי למעט בצורת 2 ליטרלים tff.SERVER ו tff.CLIENTS שאתה יכול לחשוב כקבועים מסוג זה. עם זאת, הוא נמצא בשימוש פנימי ויוצג ב-API הציבורי במהדורות עתידיות. הייצוג הקומפקטי מסוג זה הוא placement .

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

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

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

    בסימון קומפקטי עבור סוג Federated של ערכים הכוללים פריטים (המרכיבים חבר) מסוג T , כל בהנחיית קבוצות (מיקום) G הוא T@G או {T}@G עם all_equal סט קצת או לא מוגדר, בהתאמה.

    לדוגמה:

    • {int32}@CLIENTS מייצג ערך פדרלי, אשר מורכב מסידרה של מספרים שלמים ברורים בפוטנציה, אחת לכל מכשיר הלקוח. שים לב שאנחנו מדברים על ערך Federated יחיד כפי המקיף פריטים מרובים של הנתונים המופיעים במקומות רבים על פני הרשת. דרך אחת לחשוב על זה היא כמעין מותח עם מימד "רשת", אם כי האנלוגיה הזו אינה מושלמת משום TFF אינו מאפשר גישה אקראית לבוחרים חבר ערך Federated.

    • {<X=float32,Y=float32>*}@CLIENTS מייצג קבוצת נתונים Federated, ערך מורכב רצפים מרובים של XY הקואורדינטות, רצף אחד לכל מכשיר הלקוח.

    • <weights=float32[10,5],bias=float32[5]>@SERVER מייצג tuple בשם משקל הטיה tensors בשרת. מאז שעברנו שמט את סוגריים מסולסלים, זה מצביע על all_equal קצת מוגדר, כלומר, רק שיש tuple יחיד (לא משנה כמה שרתים העתקים ייתכן שיש באשכול אירוח ערך זה).

אבני בניין

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

הוא מספק את הפשטות התכנות הבאות הנחשפות כעת ב-API הציבורי:

  • TensorFlow חישובים ( tff.tf_computation ). אלה הם קטעי קוד TensorFlow עטוף כמו רכיבים לשימוש חוזר ב TFF באמצעות tff.tf_computation מעצב. תמיד יש להם טיפוסים פונקציונליים, ובניגוד לפונקציות ב-TensorFlow, הם יכולים לקחת פרמטרים מובנים או להחזיר תוצאות מובנות מסוג רצף.

    הנה אחד לדוגמה, חישוב TF מסוג (int32* -> int) המשתמשת tf.data.Dataset.reduce מפעיל לחשב סכום של מספרים שלמים:

    @tff.tf_computation(tff.SequenceType(tf.int32))
    def add_up_integers(x):
      return x.reduce(np.int32(0), lambda x, y: x + y)
    
  • Intrinsics או מפעילי Federated ( tff.federated_... ). זוהי הספרייה של פונקציות כגון tff.federated_sum או tff.federated_broadcast המהווים את חלק הארי של API FC, שרובם מייצגים מופץ מפעילי תקשורת לשימוש עם TFF.

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

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

    לדוגמה, tff.federated_broadcast יכול להיחשב מפעיל תבנית מסוג פונקציונלי T@SERVER -> T@CLIENTS .

  • ביטויים למבדא ( tff.federated_computation ). ביטוי למבדה ב TFF הוא המקבילה של lambda או def ב Python; הוא מורכב משם הפרמטר, וגוף (ביטוי) המכיל הפניות לפרמטר זה.

    בקוד Python, יכול להיווצר אלה על ידי לקשט פונקציות Python עם tff.federated_computation והגדרת ויכוח.

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

    @tff.federated_computation(tff.type_at_clients(tf.float32))
    def get_average_temperature(sensor_readings):
      return tff.federated_mean(sensor_readings)
    
  • ליטרלים מיקום. לעת עתה, רק tff.SERVER ו tff.CLIENTS לאפשר להגדרת חישובים שרת לקוח פשוטה.

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

    לדוגמה:

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

    • tff.federated_mean(sensor_readings) מייצג תפילה של מפעיל מיצוע Federated על sensor_readings . סוג של ביטוי זה הוא float32@SERVER (בהנחה בהקשר מהדוגמה לעיל).

  • יצירת tuples ובחירת האלמנטים שלהם. Python ביטויים מהצורה [x, y] , x[y] , או xy המופיעה הגופות של פונקציות מעוטרות tff.federated_computation .