TensorFlow.js שכבות API עבור משתמשי Keras

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

# Python:
import keras
import numpy as np

# Build and compile model.
model = keras.Sequential()
model.add(keras.layers.Dense(units=1, input_shape=[1]))
model.compile(optimizer='sgd', loss='mean_squared_error')

# Generate some synthetic data for training.
xs = np.array([[1], [2], [3], [4]])
ys = np.array([[1], [3], [5], [7]])

# Train model with fit().
model.fit(xs, ys, epochs=1000)

# Run inference with predict().
print(model.predict(np.array([[5]])))
// JavaScript:
import * as tf from '@tensorlowjs/tfjs';

// Build and compile model.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

// Generate some synthetic data for training.
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);
const ys = tf.tensor2d([[1], [3], [5], [7]], [4, 1]);

// Train model with fit().
await model.fit(xs, ys, {epochs: 1000});

// Run inference with predict().
model.predict(tf.tensor2d([[5]], [1, 1])).print();

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

בנאים לוקחים אובייקטי JavaScript כתצורות

השווה את קווי Python ו- JavaScript הבאים מדוגמה לעיל: שניהם ליצור צפופה שכבה.

# Python:
keras.layers.Dense(units=1, inputShape=[1])
// JavaScript:
tf.layers.dense({units: 1, inputShape: [1]});

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

כמה שיטות של מעמד הדגם, למשל, Model.compile() , גם לקחת אובייקט תצורת JavaScript כקלט. עם זאת, יש לזכור כי Model.fit() , Model.evaluate() ו Model.predict() שונים במקצת. מכיוון שאמצעי אלה לקחת חובה x (תכונות) ו y (תוויות או מטרות) נתונים כתשומות; x ו- y הם טיעונים מיקומית להפריד בין אובייקט התצורה שהתפתח כי משחק את התפקיד של הטיעונים של מילות המפתח. לדוגמה:

// JavaScript:
await model.fit(xs, ys, {epochs: 1000});

Model.fit() אינו מסונכרן

Model.fit() הוא השיטה העיקרית שבה משתמש לבצע אימוני מודל TensorFlow.js. שיטה זו יכולה להיות ארוכת טווח, ונמשכת שניות או דקות. לכן, אנו מנצלים את async התכונה של שפת JavaScript, כך פונקציה זו יכולה לשמש בצורה לא לחסום את חוט UI העיקרי בעת ההפעלה בדפדפן. זה דומה פונקציות מתמשכות אפשרי אחרות ב- JavaScript, כגון async להביא . הערה כי async הוא מבנה שאינו קיים ב Python. בעוד fit() השיטה Keras מחזירה אובייקט היסטוריה, המקביל של fit() השיטה ב JavaScript מחזיר Promise להיסטוריה, אשר יכולה להיות מחכה ed (כמו בדוגמה לעיל) או להשתמש בשיטה אז ().

אין NumPy עבור TensorFlow.js

משתמשי Python Keras מרבים להשתמש numpy לבצע פעולות מספריות מערך בסיסיות, כגון יצירת tensors 2D בדוגמא לעיל.

# Python:
xs = np.array([[1], [2], [3], [4]])

ב-TensorFlow.js, סוג זה של פעולות מספריות בסיסיות מתבצעות עם החבילה עצמה. לדוגמה:

// JavaScript:
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);

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

השתמש בשיטות המפעל, לא בנאים

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

# Python:
model = keras.Sequential()

אם תתורגם אך ורק ל-JavaScript, קריאת הבנאי המקבילה תיראה כך:

// JavaScript:
const model = new tf.Sequential();  // !!! DON'T DO THIS !!!

עם זאת, החלטנו לא להשתמש בבנאים ה"חדשים" מכיוון ש-1) מילת המפתח "החדשה" תגרום לקוד להיות מנופח יותר ו-2) הבנאי "החדש" נחשב ל"חלק רע" של JavaScript: מלכודת פוטנציאלית, כמו הוא טען JavaScript: החלקים הטובים . כדי ליצור מודלים ושכבות ב-TensorFlow.js, אתה קורא לשיטות המפעל, שיש להן שמות LowCamelCase, למשל:

// JavaScript:
const model = tf.sequential();

const layer = tf.layers.batchNormalization({axis: 1});

ערכי מחרוזת אפשרויות הם lowerCamelCase, לא snake_case

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

  • DataFormat, למשל, channelsFirst במקום channels_first
  • מאתחל, למשל, glorotNormal במקום glorot_normal
  • הפסד ומדדים, למשל, meanSquaredError במקום mean_squared_error , categoricalCrossentropy במקום categorical_crossentropy .

לדוגמה, כמו בדוגמה למעלה:

// JavaScript:
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

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

הפעל אובייקטים של Layer עם application(), לא על ידי קריאה אליהם כפונקציות

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

# Python:
my_input = keras.Input(shape=[2, 4])
flatten = keras.layers.Flatten()

print(flatten(my_input).shape)

סוכר תחביר פייתון זה מיושם כשיטת ה-apply() ב-TensorFlow.js:

// JavaScript:
const myInput = tf.input({shape: [2, 4]});
const flatten = tf.layers.flatten();

console.log(flatten.apply(myInput).shape);

Layer.apply() תומך בהערכה הכרחית (להוטה) על טנסור בטון

נכון לעכשיו, ב Keras, שיטת השיחה יכול לפעול רק על (Python) TensorFlow של tf.Tensor אובייקטים (בהנחה backend TensorFlow), אשר הינם סמליים אינם מחזיקים ערכים מספריים בפועל. זה מה שמוצג בדוגמה בסעיף הקודם. עם זאת, ב-TensorFlow.js, שיטת ה-apply() של שכבות יכולה לפעול הן במצב סימבולי והן במצב ציווי. אם apply() מופעלת עם SymbolicTensor (אנלוגיה קרובה של tf.Tensor), הערך המוחזר יהיה SymbolicTensor. זה קורה בדרך כלל במהלך בניית מודל. אבל אם apply() מופעלת עם ערך מותח בטון בפועל, היא תחזיר בטון מותח. לדוגמה:

// JavaScript:
const flatten = tf.layers.flatten();

flatten.apply(tf.ones([2, 3, 4])).print();

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

כלי האופטימיזציה נמצאים בהרכבה. , לא מייעלים.

בשנת Keras, בנאים עבור אובייקטים ייעול הם תחת keras.optimizers.* מרחב. בשכבות TensorFlow.js, שיטות המפעל עבור שירותי אופטימיזציה הם תחת tf.train.* מרחב. לדוגמה:

# Python:
my_sgd = keras.optimizers.sgd(lr=0.2)
// JavaScript:
const mySGD = tf.train.sgd({lr: 0.2});

loadLayersModel() נטען מכתובת URL, לא מקובץ HDF5

בשנת Keras, מודלים בדרך כלל נשמר כקובץ HDF5 (.h5), אשר ניתן לטעון מאוחר יותר באמצעות keras.models.load_model() שיטה. השיטה לוקחת נתיב לקובץ .h5. עמיתו של load_model() ב TensorFlow.js הוא tf.loadLayersModel() . מאז HDF5 אינו פורמט קובץ ידידותי דפדפן, tf.loadLayersModel() לוקח בפורמט TensorFlow.js ספציפי. tf.loadLayersModel() לוקח קובץ model.json כארגומנט הקלט שלה. ניתן להמיר את model.json מקובץ Keras HDF5 באמצעות חבילת tensorflowjs pip.

// JavaScript:
const model = await tf.loadLayersModel('https://foo.bar/model.json');

כמו כן שימו לב tf.loadLayersModel() מחזיר Promise של tf.Model .

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

השתמש fitDataset() למודלים הרכבת באמצעות tf.data.Dataset עצמים

בשנת tf.keras של פיתון TensorFlow, מודל ניתן לאמן באמצעות מערך נתונים אובייקט. של המודל fit() שיטה מקבלת אובייקט כזה ישירות. דגם A TensorFlow.js ניתן לאמן את שוויים JavaScript של מערך הנתונים אובייקטים וכן (ראה בתיעוד של ה- API tf.data ב TensorFlow.js ). עם זאת, בניגוד Python, אימונים מבוססי בסיס נתון נעשו באמצעות שיטה ייעודית, כלומר fitDataset . בכושר () שיטה היא רק לאימונים מודל המבוסס מותח.

ניהול זיכרון של אובייקטי שכבה ומודל

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