הצג באתר TensorFlow.org | הפעל בגוגל קולאב | צפה במקור ב-GitHub | הורד מחברת |
מדריך זה מדגים כיצד לסווג נתונים מובנים, כגון נתונים טבלאיים, באמצעות גרסה פשוטה של מערך הנתונים של PetFinder מתחרות Kaggle המאוחסנת בקובץ CSV.
אתה תשתמש ב- Keras כדי להגדיר את המודל, ובשכבות עיבוד מוקדם של Keras כגשר למיפוי מעמודות בקובץ CSV לתכונות המשמשות לאימון המודל. המטרה היא לחזות אם חיית מחמד תאומץ.
מדריך זה מכיל קוד מלא עבור:
- טעינת קובץ CSV לתוך DataFrame באמצעות פנדות .
- בניית צינור קלט כדי לקבץ ולערבב את השורות באמצעות
tf.data
. (בקר ב-tf.data: בניית צינורות קלט של TensorFlow לפרטים נוספים.) - מיפוי מעמודות בקובץ ה-CSV לתכונות המשמשות לאימון המודל עם שכבות העיבוד המקדים של Keras.
- בנייה, הדרכה והערכת מודל בשיטות המובנות של Keras.
מערך הנתונים המיני של PetFinder.my
יש כמה אלפי שורות בקובץ הנתונים CSV של PetFinder.my mini, כאשר כל שורה מתארת חיית מחמד (כלב או חתול) וכל עמודה מתארת תכונה, כגון גיל, גזע, צבע וכן הלאה.
בסיכום מערך הנתונים למטה, שימו לב שיש בעיקר עמודות מספריות וקטגוריות. במדריך זה, אתה תעסוק רק בשני סוגי התכונות הללו, ביטול Description
(תכונת טקסט חופשי) ו- AdoptionSpeed
(תכונת סיווג) במהלך עיבוד מוקדם של נתונים.
טור | תיאור חיית המחמד | סוג תכונה | סוג מידע |
---|---|---|---|
Type | סוג בעל חיים ( Dog , Cat ) | קָטֵגוֹרִי | חוּט |
Age | גיל | מִספָּרִי | מספר שלם |
Breed1 | גזע ראשוני | קָטֵגוֹרִי | חוּט |
Color1 | צבע 1 | קָטֵגוֹרִי | חוּט |
Color2 | צבע 2 | קָטֵגוֹרִי | חוּט |
MaturitySize | גודל בבגרות | קָטֵגוֹרִי | חוּט |
FurLength | אורך פרווה | קָטֵגוֹרִי | חוּט |
Vaccinated | חיית המחמד חוסנה | קָטֵגוֹרִי | חוּט |
Sterilized | חיית המחמד עברה עיקור | קָטֵגוֹרִי | חוּט |
Health | מצב בריאותי | קָטֵגוֹרִי | חוּט |
Fee | דמי אימוץ | מִספָּרִי | מספר שלם |
Description | כתיבת פרופיל | טֶקסט | חוּט |
PhotoAmt | סך התמונות שהועלו | מִספָּרִי | מספר שלם |
AdoptionSpeed | מהירות אימוץ קטגורית | מִיוּן | מספר שלם |
ייבוא TensorFlow וספריות אחרות
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
tf.__version__
'2.8.0-rc1'
טען את מערך הנתונים וקרא אותו לתוך DataFrame של pandas
pandas היא ספריית Python עם הרבה כלי עזר מועילים לטעינה ועבודה עם נתונים מובנים. השתמש tf.keras.utils.get_file
כדי להוריד ולחלץ את קובץ ה-CSV עם מערך הנתונים המיני של PetFinder.my, ולטעון אותו לתוך DataFrame עם pandas.read_csv
:
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 1679360/1668792 [==============================] - 0s 0us/step
בדוק את מערך הנתונים על ידי בדיקת חמש השורות הראשונות של DataFrame:
dataframe.head()
צור משתנה יעד
המשימה המקורית בתחרות חיזוי אימוץ PetFinder.my של Kaggle הייתה לחזות את המהירות שבה חיית מחמד תאומץ (למשל בשבוע הראשון, החודש הראשון, שלושת החודשים הראשונים וכן הלאה).
במדריך זה תפשט את המשימה על ידי הפיכתה לבעיית סיווג בינארי, שבה אתה פשוט צריך לחזות אם חיית מחמד אומצה או לא.
לאחר שינוי העמודה AdoptionSpeed
, 0
יציין שחיית המחמד לא אומצה, ו 1
יציין שכן.
# In the original dataset, `'AdoptionSpeed'` of `4` indicates
# a pet was not adopted.
dataframe['target'] = np.where(dataframe['AdoptionSpeed']==4, 0, 1)
# Drop unused features.
dataframe = dataframe.drop(columns=['AdoptionSpeed', 'Description'])
פצל את ה-DataFrame למערכות הדרכה, אימות ובדיקות
מערך הנתונים נמצא ב-PandaFrame יחיד. חלקו אותו לקבוצות אימון, אימות ומבחנים תוך שימוש, לדוגמה, ביחס של 80:10:10, בהתאמה:
train, val, test = np.split(dataframe.sample(frac=1), [int(0.8*len(dataframe)), int(0.9*len(dataframe))])
print(len(train), 'training examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')
9229 training examples 1154 validation examples 1154 test examples
צור צינור קלט באמצעות tf.data
לאחר מכן, צור פונקציית עזר הממירה כל אימון, אימות ו-DataFrame של ערכת מבחנים ל- tf.data.Dataset
, ולאחר מכן מערבבת ומקבצת את הנתונים.
def df_to_dataset(dataframe, shuffle=True, batch_size=32):
df = dataframe.copy()
labels = df.pop('target')
df = {key: value[:,tf.newaxis] for key, value in dataframe.items()}
ds = tf.data.Dataset.from_tensor_slices((dict(df), labels))
if shuffle:
ds = ds.shuffle(buffer_size=len(dataframe))
ds = ds.batch(batch_size)
ds = ds.prefetch(batch_size)
return ds
כעת, השתמש בפונקציה החדשה שנוצרה ( df_to_dataset
) כדי לבדוק את פורמט הנתונים שפונקציית העזר של צינור הקלט מחזירה על ידי קריאה לנתוני האימון, והשתמש בגודל אצווה קטן כדי לשמור על הפלט קריא:
batch_size = 5
train_ds = df_to_dataset(train, batch_size=batch_size)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:4: FutureWarning: Support for multi-dimensional indexing (e.g. `obj[:, None]`) is deprecated and will be removed in a future version. Convert to a numpy array before indexing instead. after removing the cwd from sys.path.
[(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', 'target'] A batch of ages: tf.Tensor( [[84] [ 1] [ 5] [ 1] [12]], shape=(5, 1), dtype=int64) A batch of targets: tf.Tensor([1 1 0 1 0], shape=(5,), dtype=int64)
כפי שהפלט מדגים, ערכת ההדרכה מחזירה מילון של שמות עמודות (מה-DataFrame) הממפים ערכי עמודות משורות.
החל את שכבות העיבוד המקדים של Keras
שכבות העיבוד המקדים של Keras מאפשרות לך לבנות צינורות עיבוד קלט מקוריים של Keras, שיכולים לשמש כקוד עיבוד מוקדם עצמאי בזרימות עבודה שאינן של Keras, בשילוב ישירות עם דגמי Keras, ולייצא כחלק מ-Keras SavedModel.
במדריך זה, תשתמש בארבע שכבות העיבוד המקדים הבאות כדי להדגים כיצד לבצע עיבוד מקדים, קידוד נתונים מובנים והנדסת תכונות:
-
tf.keras.layers.Normalization
.נורמליזציה: מבצע נורמליזציה של תכונות קלט מבחינה תכונה. -
tf.keras.layers.CategoryEncoding
: הופך תכונות קטגוריות של מספר שלם לייצוגים צפופים חד-חמים, מרובי-חמים או tf-idf . -
tf.keras.layers.StringLookup
: הופך ערכים קטגוריים של מחרוזת למדדים שלמים. -
tf.keras.layers.IntegerLookup
: הופך ערכים קטגוריים של מספרים שלמים למדדים שלמים.
תוכל ללמוד עוד על השכבות הזמינות במדריך עבודה עם שכבות עיבוד מקדים .
- עבור מאפיינים מספריים של מערך הנתונים המיני של PetFinder.my, תשתמש בשכבת
tf.keras.layers.Normalization
לסטנדרטיזציה של הפצת הנתונים. - עבור תכונות קטגוריות , כגון
Type
חיות מחמד (מחרוזותDog
Cat
), תמיר אותן לטנזורים מקודדים מרובים-חמים עםtf.keras.layers.CategoryEncoding
.
עמודות מספריות
עבור כל תכונה מספרית במערך הנתונים המיני של PetFinder.my, תשתמש בשכבת tf.keras.layers.Normalization
לסטנדרטיזציה של הפצת הנתונים.
הגדר פונקציית עזר חדשה שמחזירה שכבה המחילה נורמליזציה מבחינה תכונה על תכונות מספריות באמצעות אותה שכבת עיבוד מקדים של Keras:
def get_normalization_layer(name, dataset):
# Create a Normalization layer for the feature.
normalizer = layers.Normalization(axis=None)
# Prepare a Dataset that only yields the feature.
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the statistics of the data.
normalizer.adapt(feature_ds)
return normalizer
לאחר מכן, בדוק את הפונקציה החדשה על ידי קריאה לכל תכונות תמונת חיית המחמד שהועלו כדי לנרמל 'PhotoAmt'
:
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.8272058 ], [-0.19125296], [ 1.3986291 ], [-0.19125296], [-0.50922936]], dtype=float32)>
עמודות קטגוריות
Type
חיות מחמד במערך הנתונים מיוצגים כמחרוזות - Dog
Cat
- אשר צריך להיות מקודד מרובות חם לפני הזנה למודל. תכונת Age
הגדר פונקציית שירות חדשה נוספת המחזירה שכבה אשר ממפה ערכים מאוצר מילים למדדים שלמים ומקודדת את התכונות מרובה-חם באמצעות העיבוד המקדים tf.keras.layers.StringLookup
, tf.keras.layers.IntegerLookup
ו- tf.keras.CategoryEncoding
שכבות:
def get_category_encoding_layer(name, dataset, dtype, max_tokens=None):
# Create a layer that turns strings into integer indices.
if dtype == 'string':
index = layers.StringLookup(max_tokens=max_tokens)
# Otherwise, create a layer that turns integer values into integer indices.
else:
index = layers.IntegerLookup(max_tokens=max_tokens)
# Prepare a `tf.data.Dataset` that only yields the 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)
# Encode the integer indices.
encoder = layers.CategoryEncoding(num_tokens=index.vocabulary_size())
# Apply multi-hot encoding to the indices. The lambda function captures the
# layer, so you can use them, or include them in the Keras Functional model later.
return lambda feature: encoder(index(feature))
בדוק את הפונקציה get_category_encoding_layer
על ידי קריאתה לתכונות 'Type'
לחיות מחמד כדי להפוך אותן לטנזורים מקודדים מרובים חמים:
test_type_col = train_features['Type']
test_type_layer = get_category_encoding_layer(name='Type',
dataset=train_ds,
dtype='string')
test_type_layer(test_type_col)
<tf.Tensor: shape=(5, 3), dtype=float32, numpy= array([[0., 1., 0.], [0., 1., 0.], [0., 1., 0.], [0., 1., 0.], [0., 1., 0.]], dtype=float32)>
חזור על התהליך בתכונות 'Age'
חיית המחמד:
test_age_col = train_features['Age']
test_age_layer = get_category_encoding_layer(name='Age',
dataset=train_ds,
dtype='int64',
max_tokens=5)
test_age_layer(test_age_col)
<tf.Tensor: shape=(5, 5), dtype=float32, numpy= array([[1., 0., 0., 0., 0.], [0., 0., 0., 1., 0.], [1., 0., 0., 0., 0.], [0., 0., 0., 1., 0.], [1., 0., 0., 0., 0.]], dtype=float32)>
עבד מראש תכונות נבחרות כדי לאמן את הדגם
למדת כיצד להשתמש במספר סוגים של שכבות עיבוד מקדים של Keras. לאחר מכן, תעשה:
- החל את פונקציות השירות לעיבוד מוקדם שהוגדרו קודם לכן על 13 תכונות מספריות וקטגוריות ממערך הנתונים המיני של PetFinder.my.
- הוסף את כל כניסות התכונות לרשימה.
כפי שצוין בהתחלה, כדי להכשיר את המודל, תשתמש במערך הנתונים המיני של PetFinder.my המספריים ( 'PhotoAmt'
, 'Fee'
) וקטגוריים ( 'Age'
, 'Type'
, 'Color1'
, 'Color2'
, 'Gender'
, 'MaturitySize'
, 'FurLength'
, 'מחוסן 'Vaccinated'
, 'Sterilized'
, 'Health'
, 'Breed1'
).
קודם לכן, השתמשת בגודל אצווה קטן כדי להדגים את צינור הקלט. כעת ניצור צינור קלט חדש עם גודל אצווה גדול יותר של 256:
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)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:4: FutureWarning: Support for multi-dimensional indexing (e.g. `obj[:, None]`) is deprecated and will be removed in a future version. Convert to a numpy array before indexing instead. after removing the cwd from sys.path.
נרמל את התכונות המספריות (מספר תמונות חיית המחמד ודמי האימוץ), והוסיפו אותן לרשימה אחת של כניסות בשם encoded_features
:
all_inputs = []
encoded_features = []
# Numerical 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)
הפוך את הערכים הקטגוריים של מספרים שלמים ממערך הנתונים (גיל חיית המחמד) למדדים שלמים, בצע קידוד רב-חם, והוסף את כניסות התכונות המתקבלות ל- encoded_features
:
age_col = tf.keras.Input(shape=(1,), name='Age', dtype='int64')
encoding_layer = get_category_encoding_layer(name='Age',
dataset=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_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(name=header,
dataset=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)
צור, הידור והכשרת המודל
השלב הבא הוא יצירת מודל באמצעות ה- Keras Functional API . עבור השכבה הראשונה במודל שלך, מיזוג את רשימת כניסות התכונות - encoded_features
- לוקטור אחד באמצעות שרשור עם tf.keras.layers.concatenate
.
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)
הגדר את הדגם עם Keras Model.compile
:
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=["accuracy"])
בואו נדמיין את גרף הקישוריות:
# Use `rankdir='LR'` to make the graph horizontal.
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")
לאחר מכן, אמן ובדוק את המודל:
model.fit(train_ds, epochs=10, validation_data=val_ds)
Epoch 1/10 /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/engine/functional.py:559: UserWarning: Input dict contained keys ['target'] which did not match any model input. They will be ignored by the model. inputs = self._flatten_to_reference_inputs(inputs) 37/37 [==============================] - 2s 19ms/step - loss: 0.6524 - accuracy: 0.5034 - val_loss: 0.5887 - val_accuracy: 0.6941 Epoch 2/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5906 - accuracy: 0.6648 - val_loss: 0.5627 - val_accuracy: 0.7218 Epoch 3/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5697 - accuracy: 0.6924 - val_loss: 0.5463 - val_accuracy: 0.7504 Epoch 4/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5558 - accuracy: 0.6978 - val_loss: 0.5346 - val_accuracy: 0.7504 Epoch 5/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5502 - accuracy: 0.7105 - val_loss: 0.5272 - val_accuracy: 0.7487 Epoch 6/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5415 - accuracy: 0.7123 - val_loss: 0.5210 - val_accuracy: 0.7608 Epoch 7/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5354 - accuracy: 0.7171 - val_loss: 0.5152 - val_accuracy: 0.7435 Epoch 8/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5301 - accuracy: 0.7214 - val_loss: 0.5113 - val_accuracy: 0.7513 Epoch 9/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5286 - accuracy: 0.7189 - val_loss: 0.5087 - val_accuracy: 0.7574 Epoch 10/10 37/37 [==============================] - 0s 8ms/step - loss: 0.5252 - accuracy: 0.7260 - val_loss: 0.5058 - val_accuracy: 0.7539 <keras.callbacks.History at 0x7f5f9fa91c50>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
5/5 [==============================] - 0s 6ms/step - loss: 0.5012 - accuracy: 0.7626 Accuracy 0.762565016746521
בצע מסקנות
המודל שפיתחת יכול כעת לסווג שורה מקובץ CSV ישירות לאחר שכללת את שכבות העיבוד המקדים בתוך המודל עצמו.
כעת אתה יכול לשמור ולטעון מחדש את מודל Keras עם Model.save
ו- Model.load_model
לפני ביצוע הסקה על נתונים חדשים:
model.save('my_pet_classifier')
reloaded_model = tf.keras.models.load_model('my_pet_classifier')
2022-01-26 06:20:08.013613: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. WARNING:absl:Function `_wrapped_model` contains input name(s) PhotoAmt, Fee, Age, Type, Color1, Color2, Gender, MaturitySize, FurLength, Vaccinated, Sterilized, Health, Breed1 with unsupported characters which will be renamed to photoamt, fee, age, type, color1, color2, gender, maturitysize, furlength, vaccinated, sterilized, health, breed1 in the SavedModel. INFO:tensorflow:Assets written to: my_pet_classifier/assets INFO:tensorflow:Assets written to: my_pet_classifier/assets
כדי לקבל חיזוי למדגם חדש, אתה יכול פשוט לקרוא לשיטת Model.predict
. יש רק שני דברים שאתה צריך לעשות:
- עטפו סקלרים לרשימה כך שתהיה ממד אצווה (
Model
מעבד רק קבוצות של נתונים, לא דוגמאות בודדות). - התקשר
tf.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 77.7 percent probability of getting adopted.
הצעדים הבאים
למידע נוסף על סיווג נתונים מובנים, נסה לעבוד עם מערכי נתונים אחרים. כדי לשפר את הדיוק במהלך אימון ובדיקת המודלים שלך, חשוב היטב אילו תכונות לכלול במודל שלך וכיצד יש לייצג אותם.
להלן כמה הצעות למערך נתונים:
- מערכי נתונים של TensorFlow: MovieLens : קבוצה של דירוגי סרטים משירות המלצות לסרטים.
- מערכי נתונים של TensorFlow: איכות יין : שני מערכי נתונים הקשורים לגרסאות אדומות ולבנות של היין הפורטוגזי "Vinho Verde". אתה יכול גם למצוא את מערך הנתונים של איכות היין האדום ב- Kaggle .
- Kaggle: arXiv Dataset: קורפוס של 1.7 מיליון מאמרים אקדמיים מ-arXiv, המכסים פיזיקה, מדעי המחשב, מתמטיקה, סטטיסטיקה, הנדסת חשמל, ביולוגיה כמותית וכלכלה.