הגירה מרשתות עצביות

TensorFlow Decision Forests ( TF-DF ) הוא אוסף של אלגוריתמים של Decision Forest ( DF ) הזמינים ב-TensorFlow. יערות החלטה פועלים בצורה שונה מרשתות עצביות ( NN ): DFs בדרך כלל לא מתאמנים עם התפשטות לאחור, או במיני-אצות. לכן, לצינורות TF-DF יש כמה הבדלים מצינורות TensorFlow אחרים.

מסמך זה הוא רשימה של ההבדלים הללו, ומדריך לעדכון צינורות TF לשימוש ב-TF-DF

מסמך זה מניח היכרות עם קולב למתחילים .

מערך נתונים ותכונות

מערך נתונים לאימות

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

- model.fit(train_ds, validation_data=val_ds)
+ model.fit(train_ds.concatenate(val_ds))

# Or just don't create a validation dataset

נימוק: מסגרת TF-DF מורכבת ממספר אלגוריתמים. חלקם אינם משתמשים במערך אימות (למשל יער אקראי) בעוד שאחרים עושים זאת (למשל Gradient Boosted Trees). אלגוריתמים שכן עשויים להפיק תועלת מסוגים וגודל שונים של מערכי נתונים לאימות. לכן, אם יש צורך במערך נתונים אימות, הוא ייחלץ אוטומטית ממערך ההדרכה.

ערכת נתונים קלט/פלט

התאמן בדיוק לתקופה אחת

# Number of epochs in Keras
- model.fit(train_ds, num_epochs=5)

# Number of epochs in the dataset
- train_ds = train_ds.repeat(5)
- model.fit(train_ds)
+ model.fit(train_ds)

רציונל: משתמשים ברשתות עצביות מאמנים לעתים קרובות מודל עבור N שלבים (שעשויים לכלול לולאה על מערך הנתונים > פעם אחת), בגלל אופי SGD . TF-DF מתאמן על ידי קריאת כל מערך הנתונים ולאחר מכן הפעלת האימון בסוף. נדרשת תקופה אחת כדי לקרוא את מערך הנתונים המלא, וכל צעד נוסף יביא ל-I/O מיותר של נתונים, כמו גם לאימון איטי יותר.

אל תערב את מערך הנתונים

אין צורך לערבב מערכי נתונים (אלא אם ה-input_fn קורא רק מדגם של מערך הנתונים).

- train_ds = train_ds.shuffle(5)
- model.fit(train_ds)
+ model.fit(train_ds)

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

אל תכוון את גודל האצווה

גודל האצווה לא ישפיע על איכות הדגם

- train_ds = train_ds.batch(hyper_parameter_batch_size())
- model.fit(train_ds)
# The batch size does not matter.
+ train_ds = train_ds.batch(64)
+ model.fit(train_ds)

רציונל: מכיוון ש-TF-DF מאומן תמיד על מערך הנתונים המלא לאחר קריאתו, איכות המודל לא תשתנה בהתאם לגודל האצווה (בניגוד לאלגוריתמי אימון מיני-אצווה כמו SGD שבהם פרמטרים כמו קצב למידה צריכים להיות מכוונים במשותף). לפיכך יש להסיר אותו ממטאטא היפרפרמטרים. לגודל האצווה תהיה השפעה רק על מהירות הקלט/פלט של מערך הנתונים.

מערכי נתונים גדולים

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

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

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

כמה דוגמאות להשתמש

זה אמור להתאים לזיכרון במכונה שעליה מתאמן הדגם :

  • שימו לב שזה לא זהה לגודל הדוגמאות בדיסק.

  • ככלל אצבע ערך מספרי או קטגורי אחד משתמש ב-4 בתים של זיכרון. אז, מערך נתונים עם 100 תכונות ו-25 מיליון דוגמאות ייקח ~10GB (= 100 * 25 *10^6 * 4 בתים) של זיכרון.

  • תכונות מוגדרות קטגוריות (למשל טקסט עם אסימון) תופסות יותר זיכרון (4 בתים לכל אסימון + 12 בתים לכל תכונה).

שקול את תקציב זמן האימון שלך

  • למרות שבדרך כלל מהיר יותר מ-NN עבור מערכי נתונים קטנים יותר (למשל <100,000 דוגמאות), אלגוריתמי אימון DF אינם מותאמים באופן ליניארי עם גודל מערך הנתונים; במקום זאת, ~O(features x num_examples x log(num_examples)) ברוב המקרים.

  • זמן האימון תלוי בפרמטרים ההיפר. הפרמטרים המשפיעים ביותר הם: (1) מספר העצים ( num_trees ), (2) קצב הדגימה לדוגמה ( subsample עבור GBT), ו- (3) קצב דגימת המאפיינים ( num_candidate_attributes_ratio )

  • תכונות קטגוריות יקרות יותר מתכונות אחרות. העלות נשלטת על ידי הפרמטר categorical_set_split_greedy_sampling .

  • תכונות Oblique דלילות (מושבתות כברירת מחדל) נותנות תוצאות טובות אך יקרות לחישוב.

כללי אצבע להגדלת הנתונים

אנו מציעים להתחיל עם נתח קטן מהנתונים (פחות מ-10 אלף דוגמאות), שאמור לאפשר לך לאמן מודל TF-DF בשניות או מספר דקות ברוב המקרים. לאחר מכן תוכל להגדיל את הנתונים בקצב קבוע (למשל 40% יותר בכל פעם), להפסיק כאשר ביצועי ערכת האימות לא משתפרים או מערך הנתונים אינו מתאים יותר לזיכרון.

נורמליזציה / עיבוד מקדים של תכונה

אל תשנה נתונים עם עמודות תכונה

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

# Estimator code
- feature_columns = [
-   tf.feature_column.numeric_column(feature_1),
-   tf.feature_column.categorical_column_with_vocabulary_list(feature_2, ['First', 'Second', 'Third'])
-   ]
- model = tf.estimator.LinearClassifier(feature_columns=feature_columnes)
# Use all the available features. Detect the type automatically.
+ model = tfdf.keras.GradientBoostedTreesModel()

אתה יכול גם לציין תת-קבוצה של תכונות קלט:

+ features = [
+   tfdf.keras.FeatureUsage(name="feature_1"),
+   tfdf.keras.FeatureUsage(name="feature_2")
+   ]
+ model = tfdf.keras.GradientBoostedTreesModel(features=features, exclude_non_specified_features=True)

במידת הצורך, תוכל לאלץ את הסמנטיקה של תכונה.

+ forced_features = [
+   tfdf.keras.FeatureUsage(name="feature_1", semantic=tfdf.keras.FeatureSemantic.CATEGORICAL),
+   ]
+ model = tfdf.keras.GradientBoostedTreesModel(features=features)

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

אל תעבדו מראש את התכונות

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

אל תנרמל תכונות מספריות

- def zscore(value):
-   return (value-mean) / sd

- feature_columns = [tf.feature_column.numeric_column("feature_1",normalizer_fn=zscore)]

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

אין לקודד תכונות קטגוריות (למשל hashing, one-hot או הטמעה)

- integerized_column = tf.feature_column.categorical_column_with_hash_bucket("feature_1",hash_bucket_size=100)
- feature_columns = [tf.feature_column.indicator_column(integerized_column)]
- integerized_column = tf.feature_column.categorical_column_with_vocabulary_list('feature_1', ['bob', 'george', 'wanda'])
- feature_columns = [tf.feature_column.indicator_column(integerized_column)]

רציונל: ל-TF-DF יש תמיכה מקורית בתכונות קטגוריות, והוא יתייחס לפריט אוצר מילים "משונה" כאל עוד פריט באוצר המילים הפנימי שלו (שניתן להגדיר אותו באמצעות היפרפרמטרים של המודל). טרנספורמציות מסוימות (כמו hashing) עשויות להיות אובדניות. הטמעות אינן נתמכות אלא אם כן הן מאומנות מראש, שכן דגמי Decision Forest אינם ניתנים להבדלה (ראה קולב ביניים ). שים לב שאסטרטגיות אוצר מילים ספציפיות לתחום (למשל הסרת מילת עצור, נורמליזציה של טקסט) עדיין עשויות להיות מועילות.

כיצד לטפל בתכונות טקסט

TF-DF תומך בתכונות מוגדרות קטגוריות באופן מקורי. לכן, ניתן לצרוך שקיות של n-גרם אסימונים באופן טבעי.

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

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

אל תחליף תכונות חסרות בערכי קסם

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

- feature_columns = [
- tf.feature_column.numeric_column("feature_1", default_value=0),
- tf.feature_column.numeric_column("feature_1_is_missing"),
- ]

טיפול בתמונות וסדרות זמן

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

נימוק: Convolution, LSTM, תשומת לב ואלגוריתמים אחרים לעיבוד רצף הם ארכיטקטורות ספציפיות לרשתות עצביות.

ניתן לטפל בתכונות אלו באמצעות האסטרטגיות הבאות:

  • הנדסת תכונה

    • תמונות: השימוש בתמונה עם Random Forest היה פופולרי בשלב מסוים (למשל

      Microsoft Kinect , אבל כיום, רשתות עצבים הן עדכניות.

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

    • הטמעת מודולים: מודולי הטבעת רשת עצבית יכולים לספק תכונות עשירות עבור אלגוריתם יער החלטות. קולב הביניים מראה כיצד לשלב הטבעת tf-hub ודגם TF-DF.

צינור הדרכה

אל תשתמש במאיצי חומרה כגון GPU, TPU

אימון TF-DF אינו תומך (עדיין) במאיצי חומרה. כל האימון וההסקת מסקנות נעשים על המעבד (לפעמים באמצעות SIMD).

שימו לב שהסקת TF-DF על מעבד (במיוחד כאשר מוגש באמצעות ספריות Yggdrasil C++) יכולה להיות מהירה באופן מפתיע (תת-מיקרו-שנייה לכל דוגמה לכל ליבת מעבד).

אל תשתמש בקרסים למחסום או באמצע האימון

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

קרסים של קרס המסתמכים על שלב האימון גם הם לא יעבדו - בגלל אופי אימון TF-DF, הדגם מתאמן בסוף העידן הראשון, ויהיה קבוע לאחר אותה תקופה. השלב מתאים רק ל-I/O של מערך הנתונים.

דטרמיניזם מודל

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

תצורת אימון

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

- model = tf_keras.Sequential()
- model.add(Dense(64, activation=relu))
- model.add(Dense(1)) # One output for binary classification

- model.compile(loss=tf_keras.losses.BinaryCrossentropy(from_logits=True),
-               optimizer='adam',
-               metrics=['accuracy'])
# The loss is automatically determined from the task.
+ model = tfdf.keras.GradientBoostedTreesModel(task=tf_keras.Task.CLASSIFICATION)

# Optional if you want to report the accuracy.
+ model.compile(metrics=['accuracy'])

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

היפר-פרמטרים יציבים מבחינה סמנטית

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

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

# Model with default hyper-parameters.
model = tfdf.keras.GradientBoostedTreesModel()

# List the hyper-parameters (with default value) and hyper-parameters templates of the GBT learning algorithm (in colab)
?tfdf.keras.GradientBoostedTreesModel

# Use a hyper-parameter template.
model = tfdf.keras.GradientBoostedTreesModel(hp_template="winner_1")

# Change one of the hyper-parameters.
model = tfdf.keras.GradientBoostedTreesModel(num_trees=500)

# List all the learning algorithms available
tfdf.keras.get_all_models()

איתור באגים בדגם

חלק זה מציג כמה דרכים שבהן אתה יכול להסתכל/לפתור באגים/לפרש את המודל. הקולאב למתחילים מכיל דוגמה מקצה לקצה.

תקציר דגם פשוט

# Text description of the model, training logs, feature importances, etc.
model.summary()

יומני הדרכה וטנסורבורד

# List of metrics
logs = model.make_inspector().training_logs()
print(logs)

או באמצעות TensorBoard:

% load_ext
tensorboard
model.make_inspector().export_to_tensorboard("/tmp/tensorboard_logs")
% tensorboard - -logdir
"/tmp/tensorboard_logs"

חשיבות תכונה

model.make_inspector().variable_importances()

מזימות את העצים

tfdf.model_plotter.plot_model_in_colab(model, tree_idx=0)

גישה למבנה העץ

tree = model.make_inspector().extract_tree(tree_idx=0)
print(tree)

(ראה colab מתקדם )

אל תשתמש באסטרטגיות הפצה של TensorFlow

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

- with tf.distribute.MirroredStrategy():
-    model = ...
+ model = ....

ערימת דגמים

דגמי TF-DF אינם מפיצים שיפועים לאחור. כתוצאה מכך, לא ניתן להרכיב אותם עם דגמי NN אלא אם ה-NNs כבר מאומנים.

העברה מ-tf.estimator.BoostedTrees {מסוגן/רגרסור/מעריך}

למרות שנשמע דומה, העצים המוגברים TF-DF ו- Estimator הם אלגוריתמים שונים. TF-DF מיישם את הניירות הקלאסיים של Random Forest and Gradient Boosted Machine (באמצעות עצים) . tf.estimator.BoostedTreesEstimator הוא אלגוריתם משוער של Gradient Boosted Trees עם הליך אימון מיני-אצווה המתואר במאמר זה

לחלק מהפרמטרים ההיפר יש סמנטיקה דומה (למשל num_trees), אך יש להם השלכות איכות שונות. אם כיוונת את הפרמטרים ההיפר ב-tf.estimator.BoostedTreesEstimator שלך, תצטרך לכוונן מחדש את הפרמטרים ההיפר-פרמטרים שלך בתוך TF-DF כדי להשיג את התוצאות האופטימליות.

למשתמשי Yggdrasil

Yggdrasil Decision Forest הוא ספריית האימונים וההסקות המרכזיות המשמשת את TF-DF. תצורת ההדרכה והדגמים תואמים (כלומר ניתן להשתמש בדגמים שאומנו עם TF-DF עם מסקנות Yggdrasil).

עם זאת, חלק מהאלגוריתמים של Yggdrasil אינם זמינים (עדיין) ב-TF-DF.

  • Gradient Boosted Tree עם דגימה מפורקת.