Помогают защитить Большой Барьерный Риф с 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'

Загрузите набор данных и прочтите его в фрейм данных 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()

Создайте целевую переменную

Исходная задача в 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 на наборы для обучения, проверки и тестирования

Набор данных находится в одном фрейме данных pandas. Разделите его на наборы для обучения, проверки и тестирования, используя, например, соотношение 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(
[[ 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.

В этом руководстве вы будете использовать следующие четыре уровня предварительной обработки, чтобы продемонстрировать, как выполнять предварительную обработку, кодирование структурированных данных и проектирование функций:

  • 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 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 s в наборе данных представлены как 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)

Turn значений целочисленной категоричных из набора данных (животное возраста) в целочисленные индексы, выполнение мульти-горячее кодирования, и добавить полученные входы функции для 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 . Для первого слоя в вашей модели, объединить список функции ВВОДА 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")

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. Wrap скаляров в список так, чтобы иметь пакетный размер ( Model только процесс S партии данных, а не единичные образцы).
  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.

Следующие шаги

Чтобы узнать больше о классификации структурированных данных, попробуйте работать с другими наборами данных. Чтобы повысить точность во время обучения и тестирования ваших моделей, тщательно подумайте, какие функции включить в вашу модель и как они должны быть представлены.

Ниже приведены некоторые предложения для наборов данных:

  • TensorFlow Наборы данные: MovieLens : Набор рейтингов фильмов из службы рекомендации фильма.
  • TensorFlow Datasets: Вино Качество : Два набора данных , связанные с красными и белыми вариантами португальского «Vinho Верде» вино. Вы также можете найти набор данных красного вина качества на Kaggle .
  • Kaggle: Arxiv Dataset : В корпусе 1,7 млн научных статей из Arxiv, охватывающая физика, информатика, математика, статистика, электротехника, количественная биологии и экономика.