בלמידת מכונה, מודל הוא פונקציה עם פרמטרים ניתנים ללמידה הממפה קלט לפלט. הפרמטרים האופטימליים מתקבלים על ידי אימון המודל על נתונים. מודל מאומן היטב יספק מיפוי מדויק מהקלט לפלט הרצוי.
ב-TensorFlow.js יש שתי דרכים ליצור מודל למידת מכונה:
- באמצעות Layers API שבו אתה בונה מודל באמצעות שכבות .
- שימוש ב-Core API עם פעולות ברמה נמוכה יותר כגון
tf.matMul()
,tf.add()
וכו'.
ראשית, נבחן את Layers API, שהוא API ברמה גבוהה יותר לבניית מודלים. לאחר מכן, נראה כיצד לבנות את אותו מודל באמצעות Core API.
יצירת מודלים עם Layers API
ישנן שתי דרכים ליצור מודל באמצעות Layers API: מודל רציף ומודל פונקציונלי . שני הסעיפים הבאים בוחנים כל סוג מקרוב יותר.
המודל הרציף
הסוג הנפוץ ביותר של מודל הוא מודל Sequential
, שהוא ערימה לינארית של שכבות. אתה יכול ליצור מודל Sequential
על ידי העברת רשימה של שכבות לפונקציה sequential()
:
const model = tf.sequential({
layers: [
tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
tf.layers.dense({units: 10, activation: 'softmax'}),
]
});
או באמצעות שיטת add()
:
const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
חשוב: השכבה הראשונה במודל צריכה
inputShape
. ודא שאתה לא כולל את גודל האצווה בעת מתן ה-inputShape
. לדוגמה, אם אתה מתכנן להזין את טנסור המודל של הצורה[B, 784]
, כאשרB
יכול להיות כל גודל אצווה, צייןinputShape
כ-[784]
בעת יצירת המודל.
אתה יכול לגשת לשכבות של המודל דרך model.layers
, וליתר דיוק model.inputLayers
ו- model.outputLayers
.
המודל הפונקציונלי
דרך נוספת ליצור LayersModel
היא באמצעות הפונקציה tf.model()
. ההבדל העיקרי בין tf.model()
ל- tf.sequential()
הוא ש- tf.model()
מאפשר לך ליצור גרף שרירותי של שכבות, כל עוד אין להן מחזורים.
הנה קטע קוד שמגדיר את אותו מודל כמו לעיל באמצעות ה-API של tf.model()
:
// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});
אנו קוראים apply()
בכל שכבה על מנת לחבר אותה לפלט של שכבה אחרת. התוצאה של apply()
במקרה זה היא SymbolicTensor
, שמתנהג כמו Tensor
אך ללא ערכים קונקרטיים.
שימו לב שבניגוד למודל הרציף, אנו יוצרים SymbolicTensor
דרך tf.input()
במקום לספק inputShape
לשכבה הראשונה.
apply()
יכול גם לתת לך Tensor
בטון, אם תעביר אליו Tensor
בטון:
const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]
זה יכול להיות שימושי בעת בדיקת שכבות בבידוד וראיית הפלט שלהן.
בדיוק כמו במודל רציף, אתה יכול לגשת לשכבות של המודל דרך model.layers
, וליתר דיוק model.inputLayers
ו- model.outputLayers
.
מַתַן תוֹקֵף
גם המודל הרציף וגם המודל הפונקציונלי הם מופעים של המחלקה LayersModel
. אחד היתרונות העיקריים של עבודה עם LayersModel
הוא אימות: הוא מאלץ אותך לציין את צורת הקלט וישתמש בה מאוחר יותר כדי לאמת את הקלט שלך. LayersModel
גם עושה הסקת צורה אוטומטית כאשר הנתונים זורמים דרך השכבות. הכרת הצורה מראש מאפשרת לדגם ליצור אוטומטית את הפרמטרים שלו, ויכולה לומר לך אם שתי שכבות עוקבות אינן תואמות זו לזו.
תקציר הדגם
קרא model.summary()
כדי להדפיס סיכום שימושי של המודל, הכולל:
- שם וסוג של כל השכבות בדגם.
- צורת פלט עבור כל שכבה.
- מספר פרמטרי משקל של כל שכבה.
- אם למודל יש טופולוגיה כללית (נדון להלן), הכניסות שכל שכבה מקבלת
- המספר הכולל של הפרמטרים הניתנים לאימון ולא ניתנים לאימון של הדגם.
עבור הדגם שהגדרנו למעלה, נקבל את הפלט הבא בקונסולה:
שכבה (סוג) | צורת פלט | פראם מס' |
צפוף_צפוף1 (צפוף) | [null,32] | 25120 |
dense_Dense2 (צפוף) | [null,10] | 330 |
סה"כ פרמים: 25450 פרמטרים ניתנים לאימון: 25450 פרמטרים שאינם ניתנים לאימון: 0 |
שימו לב לערכי null
בצורות הפלט של השכבות: תזכורת שהמודל מצפה שלקלט יהיה גודל אצווה כממד החיצוני ביותר, שבמקרה זה יכול להיות גמיש בגלל הערך null
.
סדרה
אחד היתרונות העיקריים של שימוש ב- LayersModel
על פני ה-API ברמה נמוכה יותר הוא היכולת לשמור ולטעון מודל. LayersModel
יודע על:
- הארכיטקטורה של המודל, המאפשרת לך ליצור מחדש את המודל.
- המשקלים של הדגם
- תצורת האימון (הפסד, מייעל, מדדים).
- מצב האופטימיזציה, המאפשר לך לחדש את האימון.
כדי לשמור או לטעון מודל זה רק שורת קוד אחת:
const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');
הדוגמה למעלה שומרת את הדגם לאחסון מקומי בדפדפן. עיין model.save() documentation
ובמדריך השמירה והטעינה כיצד לשמור במדיומים שונים (למשל אחסון קבצים, IndexedDB
, הפעלת הורדת דפדפן וכו')
שכבות מותאמות אישית
שכבות הן אבני הבניין של מודל. אם המודל שלך מבצע חישוב מותאם אישית, אתה יכול להגדיר שכבה מותאמת אישית, שמקיימת אינטראקציה טובה עם שאר השכבות. להלן נגדיר שכבה מותאמת אישית המחשבת את סכום הריבועים:
class SquaredSumLayer extends tf.layers.Layer {
constructor() {
super({});
}
// In this case, the output is a scalar.
computeOutputShape(inputShape) { return []; }
// call() is where we do the computation.
call(input, kwargs) { return input.square().sum();}
// Every layer needs a unique name.
getClassName() { return 'SquaredSum'; }
}
כדי לבדוק זאת, אנו יכולים לקרוא לשיטת apply()
עם טנזור בטון:
const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30
חשוב: אם אתה מוסיף שכבה מותאמת אישית, אתה מאבד את היכולת להרכיב מודל בסידרה.
יצירת מודלים עם Core API
בתחילת המדריך הזה, הזכרנו שיש שתי דרכים ליצור מודל למידת מכונה ב-TensorFlow.js.
כלל האצבע הכללי הוא לנסות תמיד להשתמש קודם כל ב-Layers API, מכיוון שהוא מעוצב לפי ה-Keras API המאומץ היטב, שעוקב אחר שיטות עבודה מומלצות ומפחית עומס קוגניטיבי . ה-API של Layers מציע גם פתרונות מדף שונים כמו אתחול משקל, סדרת מודלים, הדרכות ניטור, ניידות ובדיקת בטיחות.
ייתכן שתרצה להשתמש ב-Core API בכל פעם:
- אתה צריך גמישות או שליטה מקסימלית.
- אינך זקוק לסידרה, או שאתה יכול ליישם את היגיון ההסדרה שלך.
מודלים ב-Core API הם רק פונקציות שלוקחות Tensors
אחד או יותר ומחזירות Tensor
. אותו דגם כמו לעיל שנכתב באמצעות Core API נראה כך:
// The weights and biases for the two dense layers.
const w1 = tf.variable(tf.randomNormal([784, 32]));
const b1 = tf.variable(tf.randomNormal([32]));
const w2 = tf.variable(tf.randomNormal([32, 10]));
const b2 = tf.variable(tf.randomNormal([10]));
function model(x) {
return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
}
שימו לב שב-Core API אנחנו אחראים על יצירה ואתחול של משקלי המודל. כל משקל מגובה Variable
שמאותת ל-TensorFlow.js שהטנסורים הללו ניתנים ללמידה. אתה יכול ליצור Variable
באמצעות tf.variable() ומעבר ב- Tensor
קיים.
במדריך זה הכרת את הדרכים השונות ליצירת מודל באמצעות השכבות וה-Core API. לאחר מכן, עיין במדריך דגמי ההדרכה כיצד להכשיר דוגמנית.