פלטפורמה וסביבה

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

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

ב-Node.js, TensorFlow.js תומך בקישור ישירות לממשק ה-API של TensorFlow או בריצה עם יישומי מעבד וניל איטיים יותר.

סביבות

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

קצוות אחוריים

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

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

console.log(tf.getBackend());

אם ברצונך לשנות ידנית את הקצה האחורי:

tf.setBackend('cpu');
console.log(tf.getBackend());

WebGL backend

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

הימנע מחסימת שרשור ממשק המשתמש

כאשר קוראים לפעולה, כמו tf.matMul(a,b), ה-tf.Tensor המתקבל מוחזר באופן סינכרוני, אולם ייתכן שהחישוב של הכפל המטריצה ​​לא באמת מוכן עדיין. המשמעות היא שה-tf.Tensor שהוחזר הוא רק ידית לחישוב. כאשר אתה קורא x.data() או x.array() , הערכים יפתרו כאשר החישוב השלים למעשה. זה עושה את זה חשוב להשתמש אסינכרוני x.data() ו x.array() שיטות פני עמיתיהם סינכרוני שלהם x.dataSync() ו x.arraySync() כדי למנוע חסימת חוט UI בעוד משלים החישוב.

ניהול זיכרון

אזהרה אחת בעת שימוש ב-WebGL backend היא הצורך בניהול זיכרון מפורש. WebGLTextures, שם בסופו של דבר מאוחסנים נתוני Tensor, אינם אשפה אוטומטית שנאספת על ידי הדפדפן.

כדי להרוס את הזיכרון של tf.Tensor , אתה יכול להשתמש dispose() שיטה:

const a = tf.tensor([[1, 2], [3, 4]]);
a.dispose();

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

const a = tf.tensor([[1, 2], [3, 4]]);
const y = tf.tidy(() => {
  const result = a.square().log().neg();
  return result;
});
דיוק

במכשירים ניידים, WebGL עשוי לתמוך רק בטקסטורות של נקודה צפה של 16 סיביות. עם זאת, רוב דגמי למידת המכונה מאומנים עם משקולות והפעלה של נקודה צפה של 32 סיביות. זה יכול לגרום לבעיות דיוק כאשר porting מודל מכשיר נייד כמו 16 מספרים צפים קצת יכול לייצג מספרים בלבד בטווח [0.000000059605, 65504] . זה אומר שאתה צריך להקפיד שהמשקלים וההפעלה בדגם שלך לא יחרגו מטווח זה. כדי לבדוק אם טקסטורות קצת המכשיר תומך 32, לבדוק את הערך של tf.ENV.getBool('WEBGL_RENDER_FLOAT32_CAPABLE') , אם זו היא שקרית אז המכשיר תומך רק 16 טקסטורות נקודה צפה ביט. אתה יכול להשתמש tf.ENV.getBool('WEBGL_RENDER_FLOAT32_ENABLED') כדי לבדוק אם TensorFlow.js משתמש כרגע 32 טקסטורות קצת.

אוסף הצללה והעלאות טקסטורות

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

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

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

לדוגמה:

const model = await tf.loadLayersModel(modelUrl);

// Warmup the model before using real data.
const warmupResult = model.predict(tf.zeros(inputShape));
warmupResult.dataSync();
warmupResult.dispose();

// The second predict() will be much faster
const result = model.predict(userData);

Node.js TensorFlow backend

בקצה האחורי של TensorFlow Node.js, 'node', משתמשים ב-API של TensorFlow C כדי להאיץ פעולות. זה ישתמש בהאצת החומרה הזמינה של המכונה, כמו CUDA, אם זמינה.

בשנת רקע זו, בדיוק כמו backend WebGL, פעולות לחזור tf.Tensor s סינכרוני. עם זאת, בניגוד ל-WebGL backend, הפעולה הושלמה לפני שמחזירים את הטנזור. אמצעי זה כי קריאת tf.matMul(a, b) תחסם את חוט UI.

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

למידע נוסף על Node.js, עיין במדריך זה.

אחורי WASM

TensorFlow.js מספק backend WebAssembly ( wasm ), האצת מעבד הצעות אשר יכול לשמש כחלופת מעבד JavaScript וניל ( cpu ) ו- WebGL מואץ ( webgl ) Backends. להשתמש בזה:

// Set the backend to WASM and wait for the module to be ready.
tf.setBackend('wasm');
tf.ready().then(() => {...});

אם השרת שלך משרת את .wasm קובץ על נתיב אחר או שם אחר, השימוש setWasmPath לפני שאתה לאתחל את backend. ראה "Bundlers שימוש" בסעיף ב README לפרטים נוספים:

import {setWasmPath} from '@tensorflow/tfjs-backend-wasm';
setWasmPath(yourCustomPath);
tf.setBackend('wasm');
tf.ready().then(() => {...});
למה WASM?

WASM הוצג בשנת 2015 בתור פורמט בינארי מבוסס אינטרנט חדש, מתן תוכניות כתוב JavaScript, C, C ++, וכו 'יעד הידור להפעלה באינטרנט. WASM כבר נתמך על ידי כרום, ספארי, פיירפוקס, ואת אדג מאז 2017, והוא נתמך על ידי 90% של מכשירים ברחבי העולם.

ביצועים

Backend WASM ממנף את הספרייה XNNPACK ליישום אופטימיזציה של מפעילי רשתות עצביות.

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

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

ניידות ויציבות

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

כמו WebGL, WASM נתמך רשמית על ידי כל הדפדפנים הגדולים. בניגוד ל-WebGL, WASM יכול לרוץ ב-Node.js ולשמש בצד השרת ללא כל צורך להדר ספריות מקוריות.

מתי עלי להשתמש ב-WASM?

גודל דגם וביקוש חישובי

באופן כללי, WASM היא בחירה טובה כאשר מודלים קטנים או שאכפת לך התקנים התחתונה סוף נעדרי תמיכה ב- WebGL ( OES_texture_float הארכה) או שיש פחות GPUs עוצמה. הטבלה למטה מראה היקש פעמים (נכון TensorFlow.js 1.5.2) ב- Chrome 2018 MacBook Pro עבור 5 של שלנו נתמך באופן רשמי דגמים ברחבי WebGL, WASM, ו Backends CPU:

דגמים קטנים יותר

דֶגֶם WebGL WASM מעבד זיכרון
BlazeFace 22.5 אלפיות השנייה 15.6 אלפיות השנייה 315.2 אלפיות השנייה .4 MB
FaceMesh 19.3 אלפיות השנייה 19.2 אלפיות השנייה 335 אלפיות השנייה 2.8 מגה-בייט

דגמים גדולים יותר

דֶגֶם WebGL WASM מעבד זיכרון
PoseNet 42.5 אלפיות השנייה 173.9 אלפיות השנייה 1514.7 אלפיות השנייה 4.5 מגה-בייט
BodyPix 77 אלפיות השנייה 188.4 אלפיות השנייה 2683 אלפיות השנייה 4.6 מגה-בייט
MobileNet v2 37 אלפיות השנייה 94 אלפיות השנייה 923.6 אלפיות השנייה 13 מגה-בייט

מהטבלה לעיל עולה כי WASM היא 10-30x מהר יותר backend CPU JS רגיל בין המודלים השונים של, ותחרותי עם WebGL עבור דגמים קטנים כמו BlazeFace , אשר הוא קל משקל (400KB), עדיין יש מספר מכובד של חיילים מיחידות (~ 140). בהתחשב בכך שלתוכניות WebGL יש עלות תקורה קבועה לכל ביצוע פעולה, זה מסביר מדוע מודלים כמו BlazeFace מהירים יותר ב-WASM.

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

הסקה מול אימון

כדי לטפל לשימוש במקרה העיקרי ויישום של מודלים מאומנים מראש, בפיתוח backend WASM יהיה לתעדף היקש מעל אימון ותמיכה. ראה רשימה עַדכָּנִי של חיילים מיחידות נתמך WASM ו יידע אותנו אם המודל שלך יש אופ נתמך. עבור מודלים לאימון, אנו ממליצים להשתמש ב-Node (TensorFlow C++) או ב-WebGL backend.

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

ה-CPU, 'cpu', הוא הקצה האחורי הכי פחות בעל ביצועים, אולם הוא הפשוט ביותר. כל הפעולות מיושמות ב-vanilla JavaScript, מה שהופך אותן פחות ניתנות להקבילה. הם גם חוסמים את שרשור ה-UI.

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

דגלים

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

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