לשמור את התאריך! קלט / פלט של Google חוזר 18-20 במאי הירשם עכשיו
דף זה תורגם על ידי Cloud Translation API.
Switch to English

סיווג נתונים מובנים באמצעות Keras Preprocessing Layers

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה במקור ב- GitHub הורד מחברת

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

  • טען קובץ CSV באמצעות פנדה .
  • בנה צינור קלט לאצווה ולערבב את השורות באמצעות tf.data .
  • ממפה מעמודות ב- CSV לתכונות המשמשות לאימון המודל באמצעות שכבות Keras Preprocessing.
  • בנה, התאמן והעריך מודל באמצעות Keras.

מערך הנתונים

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

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

טור תיאור סוג תכונה סוג מידע
סוּג סוג החיה (כלב, חתול) קָטֵגוֹרִי חוּט
גיל גיל חיית המחמד מִספָּרִי מספר שלם
גזע 1 גזע ראשוני של חיית המחמד קָטֵגוֹרִי חוּט
צבע 1 צבע 1 של חיית המחמד קָטֵגוֹרִי חוּט
צבע 2 צבע 2 של חיית המחמד קָטֵגוֹרִי חוּט
MaturitySize גודל בבגרות קָטֵגוֹרִי חוּט
FurLength אורך הפרווה קָטֵגוֹרִי חוּט
מחוסן חיית מחמד חוסנה קָטֵגוֹרִי חוּט
מְעוּקָר חיית המחמד עוקרה קָטֵגוֹרִי חוּט
בְּרִיאוּת מצב בריאותי קָטֵגוֹרִי חוּט
תַשְׁלוּם דמי אימוץ מִספָּרִי מספר שלם
תיאור רישום פרופיל לחיית המחמד הזו טֶקסט חוּט
PhotoAmt סה"כ תמונות שהועלו לחיית המחמד הזו מִספָּרִי מספר שלם
אימוץ מהירות מהירות האימוץ מִיוּן מספר שלם

ייבא את TensorFlow וספריות אחרות

pip install -q sklearn
import numpy as np
import pandas as pd
import tensorflow as tf

from sklearn.model_selection import train_test_split
from tensorflow.keras import layers
from tensorflow.keras.layers.experimental import preprocessing

השתמש בפנדה כדי ליצור מסגרת נתונים

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

import pathlib

dataset_url = 'http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip'
csv_file = 'datasets/petfinder-mini/petfinder-mini.csv'

tf.keras.utils.get_file('petfinder_mini.zip', dataset_url,
                        extract=True, cache_dir='.')
dataframe = pd.read_csv(csv_file)
Downloading data from http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip
1671168/1668792 [==============================] - 0s 0us/step
dataframe.head()

צור משתנה יעד

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

לאחר שינוי עמודת התווית, 0 יציין כי חיית המחמד לא אומצה, ו- 1 יציין שהיא הייתה.

# In the original dataset "4" indicates the pet was not adopted.
dataframe['target'] = np.where(dataframe['AdoptionSpeed']==4, 0, 1)

# Drop un-used columns.
dataframe = dataframe.drop(columns=['AdoptionSpeed', 'Description'])

פצל את מסגרת הנתונים לרכבת, אימות ובדיקה

מערך הנתונים שהורדת היה קובץ CSV יחיד. אתה תחלק את זה למערכות רכבת, אימות ומבחנים.

train, test = train_test_split(dataframe, test_size=0.2)
train, val = train_test_split(train, test_size=0.2)
print(len(train), 'train examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')
7383 train examples
1846 validation examples
2308 test examples

צור צינור קלט באמצעות tf.data

לאחר מכן, תעטוף את מסגרות הנתונים עם tf.data , על מנת לדשדש את הנתונים ולצוות אותם. אם עבדת עם קובץ CSV גדול מאוד (כל כך גדול שהוא לא נכנס לזיכרון), היית משתמש ב- tf.data כדי לקרוא אותו ישירות מהדיסק. זה לא מכוסה במדריך זה.

# A utility method to create a tf.data dataset from a Pandas Dataframe
def df_to_dataset(dataframe, shuffle=True, batch_size=32):
  dataframe = dataframe.copy()
  labels = dataframe.pop('target')
  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=len(dataframe))
  ds = ds.batch(batch_size)
  ds = ds.prefetch(batch_size)
  return ds

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

batch_size = 5
train_ds = df_to_dataset(train, batch_size=batch_size)
[(train_features, label_batch)] = train_ds.take(1)
print('Every feature:', list(train_features.keys()))
print('A batch of ages:', train_features['Age'])
print('A batch of targets:', label_batch )
Every feature: ['Type', 'Age', 'Breed1', 'Gender', 'Color1', 'Color2', 'MaturitySize', 'FurLength', 'Vaccinated', 'Sterilized', 'Health', 'Fee', 'PhotoAmt']
A batch of ages: tf.Tensor([24 24  5 24 12], shape=(5,), dtype=int64)
A batch of targets: tf.Tensor([1 0 1 0 1], shape=(5,), dtype=int64)

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

הדגים שימוש בשכבות עיבוד מקדים.

ממשק ה- API של שכבות העיבוד המוקדם של Keras מאפשר לבנות צינורות עיבוד קלט מקוריים של Keras. תוכלו להשתמש בשלוש שכבות עיבוד מקדים כדי להדגים את קוד העיבוד המקדים לתכונות.

תוכל למצוא רשימה של שכבות זמין לעיבוד מקדים כאן .

עמודות מספריות

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

הפונקציה get_normalization_layer מחזירה שכבה המתאימה לנורמליזציה תכונתית לתכונות מספריות.

def get_normalization_layer(name, dataset):
  # Create a Normalization layer for our feature.
  normalizer = preprocessing.Normalization()

  # Prepare a Dataset that only yields our feature.
  feature_ds = dataset.map(lambda x, y: x[name])

  # Learn the statistics of the data.
  normalizer.adapt(feature_ds)

  return normalizer
photo_count_col = train_features['PhotoAmt']
layer = get_normalization_layer('PhotoAmt', train_ds)
layer(photo_count_col)
<tf.Tensor: shape=(5, 1), dtype=float32, numpy=
array([[-0.19863252],
       [-0.84310806],
       [ 3.0237453 ],
       [-0.84310806],
       [ 0.44584304]], dtype=float32)>

עמודות קטגוריות

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

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

def get_category_encoding_layer(name, dataset, dtype, max_tokens=None):
  # Create a StringLookup layer which will turn strings into integer indices
  if dtype == 'string':
    index = preprocessing.StringLookup(max_tokens=max_tokens)
  else:
    index = preprocessing.IntegerLookup(max_values=max_tokens)

  # Prepare a Dataset that only yields our feature
  feature_ds = dataset.map(lambda x, y: x[name])

  # Learn the set of possible values and assign them a fixed integer index.
  index.adapt(feature_ds)

  # Create a Discretization for our integer indices.
  encoder = preprocessing.CategoryEncoding(max_tokens=index.vocab_size())

  # Apply one-hot encoding to our indices. The lambda function captures the
  # layer so we can use them, or include them in the functional model later.
  return lambda feature: encoder(index(feature))
type_col = train_features['Type']
layer = get_category_encoding_layer('Type', train_ds, 'string')
layer(type_col)
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[0., 0., 1., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]], dtype=float32)>

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

type_col = train_features['Age']
category_encoding_layer = get_category_encoding_layer('Age', train_ds,
                                                      'int64', 5)
category_encoding_layer(type_col)
<tf.Tensor: shape=(5, 5), dtype=float32, numpy=
array([[0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.]], dtype=float32)>

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

ראית כיצד להשתמש בכמה סוגים של שכבות עיבוד מראש. עכשיו תשתמש בהם לאימון מודל. תוכלו להשתמש ב- API של Keras פונקציונלי לבניית המודל. ה- API הפונקציונלי של Keras הוא דרך ליצור מודלים גמישים יותר מאשר ה- API של tf.keras.Sequential .

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

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

batch_size = 256
train_ds = df_to_dataset(train, batch_size=batch_size)
val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size)
test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
all_inputs = []
encoded_features = []

# Numeric features.
for header in ['PhotoAmt', 'Fee']:
  numeric_col = tf.keras.Input(shape=(1,), name=header)
  normalization_layer = get_normalization_layer(header, train_ds)
  encoded_numeric_col = normalization_layer(numeric_col)
  all_inputs.append(numeric_col)
  encoded_features.append(encoded_numeric_col)
# Categorical features encoded as integers.
age_col = tf.keras.Input(shape=(1,), name='Age', dtype='int64')
encoding_layer = get_category_encoding_layer('Age', train_ds, dtype='int64',
                                             max_tokens=5)
encoded_age_col = encoding_layer(age_col)
all_inputs.append(age_col)
encoded_features.append(encoded_age_col)
# Categorical features encoded as string.
categorical_cols = ['Type', 'Color1', 'Color2', 'Gender', 'MaturitySize',
                    'FurLength', 'Vaccinated', 'Sterilized', 'Health', 'Breed1']
for header in categorical_cols:
  categorical_col = tf.keras.Input(shape=(1,), name=header, dtype='string')
  encoding_layer = get_category_encoding_layer(header, train_ds, dtype='string',
                                               max_tokens=5)
  encoded_categorical_col = encoding_layer(categorical_col)
  all_inputs.append(categorical_col)
  encoded_features.append(encoded_categorical_col)

צור, הידור והכשר את המודל

עכשיו אתה יכול ליצור את המודל שלנו מקצה לקצה.

all_features = tf.keras.layers.concatenate(encoded_features)
x = tf.keras.layers.Dense(32, activation="relu")(all_features)
x = tf.keras.layers.Dropout(0.5)(x)
output = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(all_inputs, output)
model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=["accuracy"])

בואו נתאר לעצמנו את גרף הקישוריות שלנו:

# rankdir='LR' is used to make the graph horizontal.
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")

png

תאמן את המודל

model.fit(train_ds, epochs=10, validation_data=val_ds)
Epoch 1/10
29/29 [==============================] - 2s 28ms/step - loss: 0.6997 - accuracy: 0.4213 - val_loss: 0.5835 - val_accuracy: 0.6912
Epoch 2/10
29/29 [==============================] - 0s 8ms/step - loss: 0.6126 - accuracy: 0.6236 - val_loss: 0.5601 - val_accuracy: 0.7264
Epoch 3/10
29/29 [==============================] - 0s 9ms/step - loss: 0.5875 - accuracy: 0.6599 - val_loss: 0.5470 - val_accuracy: 0.7140
Epoch 4/10
29/29 [==============================] - 0s 8ms/step - loss: 0.5703 - accuracy: 0.6682 - val_loss: 0.5362 - val_accuracy: 0.7221
Epoch 5/10
29/29 [==============================] - 0s 8ms/step - loss: 0.5749 - accuracy: 0.6744 - val_loss: 0.5291 - val_accuracy: 0.7226
Epoch 6/10
29/29 [==============================] - 0s 15ms/step - loss: 0.5588 - accuracy: 0.6914 - val_loss: 0.5232 - val_accuracy: 0.7259
Epoch 7/10
29/29 [==============================] - 0s 8ms/step - loss: 0.5469 - accuracy: 0.7053 - val_loss: 0.5200 - val_accuracy: 0.7281
Epoch 8/10
29/29 [==============================] - 0s 8ms/step - loss: 0.5387 - accuracy: 0.7078 - val_loss: 0.5158 - val_accuracy: 0.7313
Epoch 9/10
29/29 [==============================] - 0s 8ms/step - loss: 0.5278 - accuracy: 0.7150 - val_loss: 0.5124 - val_accuracy: 0.7394
Epoch 10/10
29/29 [==============================] - 0s 8ms/step - loss: 0.5295 - accuracy: 0.7225 - val_loss: 0.5104 - val_accuracy: 0.7367
<tensorflow.python.keras.callbacks.History at 0x7fade2095cf8>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
10/10 [==============================] - 0s 5ms/step - loss: 0.5196 - accuracy: 0.7357
Accuracy 0.7357019186019897

הסקה על נתונים חדשים

עכשיו אתה יכול לשמור לטעון מחדש את מודל Keras. עקוב אחר ההדרכה כאן למידע נוסף על דגמי TensorFlow.

model.save('my_pet_classifier')
reloaded_model = tf.keras.models.load_model('my_pet_classifier')
INFO:tensorflow:Assets written to: my_pet_classifier/assets
WARNING:tensorflow:5 out of the last 5 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5ac88598> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:6 out of the last 6 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5b19d400> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:7 out of the last 7 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5b19da60> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:8 out of the last 8 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5b1aa9d8> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:9 out of the last 9 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5ac848c8> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:10 out of the last 10 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5b192158> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:11 out of the last 11 calls to <function recreate_function.<locals>.restored_function_body at 0x7fad5b192e18> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

כדי לקבל חיזוי לדוגמא חדשה, אתה יכול להתקשר model.predict() . יש רק שני דברים שאתה צריך לעשות:

  1. עטוף את הסקלרים לרשימה כדי לקבל ממד אצווה (דגמים מעבדים רק קבוצות נתונים, ולא דוגמאות בודדות)
  2. התקשר ל- convert_to_tensor בכל תכונה
sample = {
    'Type': 'Cat',
    'Age': 3,
    'Breed1': 'Tabby',
    'Gender': 'Male',
    'Color1': 'Black',
    'Color2': 'White',
    'MaturitySize': 'Small',
    'FurLength': 'Short',
    'Vaccinated': 'No',
    'Sterilized': 'No',
    'Health': 'Healthy',
    'Fee': 100,
    'PhotoAmt': 2,
}

input_dict = {name: tf.convert_to_tensor([value]) for name, value in sample.items()}
predictions = reloaded_model.predict(input_dict)
prob = tf.nn.sigmoid(predictions[0])

print(
    "This particular pet had a %.1f percent probability "
    "of getting adopted." % (100 * prob)
)
This particular pet had a 80.5 percent probability of getting adopted.

הצעדים הבאים

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