کمک به حفاظت از دیواره بزرگ مرجانی با TensorFlow در Kaggle اضافه کردن چالش

طبقه بندی داده های ساخت یافته با استفاده از لایه های پیش پردازش Keras

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در 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.7.0'

مجموعه داده را بارگیری کنید و آن را در یک DataFrame پاندا بخوانید

پانداها یک کتابخانه پایتون با بسیاری از تاسیسات مفید برای بارگیری و کار با داده های ساخت یافته است. استفاده از 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()

یک متغیر هدف ایجاد کنید

وظیفه اصلی در Kaggle است PetFinder.my رقابت تصویب پیش بینی بود برای پیش بینی سرعت که در آن یک حیوان خانگی تصویب خواهد شد (به عنوان مثال در هفته اول، ماه اول، در سه ماه اول، و غیره).

در این آموزش، کار را با تبدیل آن به یک مسئله طبقه‌بندی باینری ساده می‌کنید، جایی که به سادگی باید پیش‌بینی کنید که آیا حیوان خانگی به فرزندی پذیرفته شده است یا خیر.

پس از اصلاح 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 را به مجموعه های آموزشی، اعتبارسنجی و تست تقسیم کنید

مجموعه داده در یک DataFrame پاندا است. به ترتیب با استفاده از نسبت 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 ، سپس shuffles و دسته داده ها.

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(
[[ 4]
 [ 1]
 [15]
 [ 3]
 [ 1]], shape=(5, 1), dtype=int64)
A batch of targets: tf.Tensor([0 1 1 0 1], shape=(5,), dtype=int64)

همانطور که خروجی نشان می دهد، مجموعه آموزشی یک فرهنگ لغت از نام ستون ها (از DataFrame) را برمی گرداند که مقادیر ستون ها را از ردیف ها نشان می دهد.

لایه های پیش پردازش Keras را اعمال کنید

لایه‌های پیش‌پردازش Keras به شما امکان می‌دهند خطوط لوله پردازش ورودی Keras را بسازید، که می‌تواند به عنوان کد پیش‌پردازش مستقل در جریان‌های کاری غیر Keras، ترکیب شده و مستقیماً با مدل‌های Keras استفاده شود و به عنوان بخشی از Keras SavedModel صادر شود.

در این آموزش، شما از چهار لایه پیش پردازش زیر برای نشان دادن نحوه انجام پیش پردازش، رمزگذاری داده های ساخت یافته و مهندسی ویژگی استفاده خواهید کرد:

شما می توانید اطلاعات بیشتر در مورد لایه های موجود در یاد کار با پیش پردازش لایه های راهنمای.

  • برای ویژگی های عددی از مجموعه داده های PetFinder.my مینی، شما یک استفاده tf.keras.layers.Normalization لایه برای استاندارد توزیع داده ها.
  • برای ویژگی های قطعی، مانند حیوان خانگی Type S ( 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.8390221 ],
       [ 2.3774517 ],
       [ 0.12592004],
       [-0.5173747 ],
       [-0.19572733]], dtype=float32)>

ستون های طبقه بندی شده

حیوان خانگی Type در مجموعه داده به عنوان strings- نمایندگی 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., 0., 1.],
       [0., 1., 0.],
       [0., 0., 1.],
       [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([[0., 0., 0., 0., 1.],
       [0., 0., 0., 1., 0.],
       [1., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 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)

مدل را ایجاد، کامپایل و آموزش دهید

گام بعدی این است برای ایجاد یک مدل با استفاده از API کاربردی Keras . برای اولین لایه در مدل خود، ادغام لیست ویژگی inputs- encoded_features -into یک بردار از طریق الحاق با 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")

png

سپس، مدل را آموزش و آزمایش کنید:

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 18ms/step - loss: 0.6231 - accuracy: 0.5496 - val_loss: 0.5638 - val_accuracy: 0.7409
Epoch 2/10
37/37 [==============================] - 0s 7ms/step - loss: 0.5758 - accuracy: 0.6770 - val_loss: 0.5473 - val_accuracy: 0.7400
Epoch 3/10
37/37 [==============================] - 0s 7ms/step - loss: 0.5544 - accuracy: 0.7043 - val_loss: 0.5377 - val_accuracy: 0.7383
Epoch 4/10
37/37 [==============================] - 0s 8ms/step - loss: 0.5482 - accuracy: 0.7098 - val_loss: 0.5309 - val_accuracy: 0.7348
Epoch 5/10
37/37 [==============================] - 0s 8ms/step - loss: 0.5424 - accuracy: 0.7100 - val_loss: 0.5268 - val_accuracy: 0.7253
Epoch 6/10
37/37 [==============================] - 0s 8ms/step - loss: 0.5336 - accuracy: 0.7130 - val_loss: 0.5221 - val_accuracy: 0.7331
Epoch 7/10
37/37 [==============================] - 0s 7ms/step - loss: 0.5289 - accuracy: 0.7258 - val_loss: 0.5189 - val_accuracy: 0.7357
Epoch 8/10
37/37 [==============================] - 0s 8ms/step - loss: 0.5280 - accuracy: 0.7146 - val_loss: 0.5165 - val_accuracy: 0.7374
Epoch 9/10
37/37 [==============================] - 0s 8ms/step - loss: 0.5221 - accuracy: 0.7264 - val_loss: 0.5142 - val_accuracy: 0.7331
Epoch 10/10
37/37 [==============================] - 0s 7ms/step - loss: 0.5200 - accuracy: 0.7235 - val_loss: 0.5128 - val_accuracy: 0.7357
<keras.callbacks.History at 0x7f1667fe7790>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
5/5 [==============================] - 0s 6ms/step - loss: 0.5032 - accuracy: 0.7513
Accuracy 0.7512997984886169

انجام استنباط

مدلی که شما توسعه داده اید اکنون می تواند یک ردیف از یک فایل CSV را مستقیماً پس از اینکه لایه های پیش پردازش را در خود مدل قرار دادید طبقه بندی کند.

شما هم اکنون می توانید ذخیره و بارگذاری مجدد مدل Keras با Model.save و Model.load_model قبل از انجام استنتاج بر داده های جدید:

model.save('my_pet_classifier')
reloaded_model = tf.keras.models.load_model('my_pet_classifier')
2021-11-06 01:29:25.921254: 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

برای به دست آوردن یک پیش بینی برای یک نمونه جدید، شما به سادگی می توانید Keras پاسخ Model.predict روش. فقط دو کار وجود دارد که باید انجام دهید:

  1. بندی بسته بندی را به یک لیست تا به عنوان به یک بعد دسته ای ( Model فقط دسته پردازش داده ها، نمونه تک نیست).
  2. پاسخ 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 74.4 percent probability of getting adopted.

مراحل بعدی

برای کسب اطلاعات بیشتر در مورد طبقه بندی داده های ساخت یافته، سعی کنید با مجموعه داده های دیگر کار کنید. برای بهبود دقت در طول آموزش و آزمایش مدل های خود، به دقت فکر کنید که کدام ویژگی ها را در مدل خود بگنجانید و چگونه باید آنها را نشان دهید.

در زیر چند پیشنهاد برای مجموعه داده ها آورده شده است: