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

Отказ от ответственности: пример, который необходимо объяснить, был взят из: TensorFlor Tutorials/Regression только для образовательных целей.

В этом примере мы создадим модель (используя классическую Auto MPG) для прогнозирования топливной экономичности автомобилей конца 1970-х и начала 1980-х годов.

В этом примере используется Keras API. (Посетите руководства и руководства от Keras, чтобы узнать больше.)

Прежде чем мы начнем

Что такое регрессия?. Как вы, возможно, уже знаете, для того, чтобы применить регрессию к модели, нам потребуется немного математики, но, говоря простыми словами, посмотрите на это так. . Представьте, что вы хотите купить часы Х, но понятия не имеете, сколько они стоят сегодня, и где искать тоже не знаете, поэтому идете в дом к дедушке (у которого есть такие же часы Х, которые он купил 20 лет назад). назад) и спросите у него журнал, который он использовал для их покупки (тоже 20 лет назад), в журнале вы обнаружите, что стоимость часов тогда составляла 100 долларов, и, к счастью, ваш дедушка, большой поклонник часов X , имеет журнальную коллекцию часов до прошлого года, поэтому вы начинаете сравнивать цены и видите, что 19 лет назад часы стоили 110 долларов, год спустя (18 лет назад) они стоили 120 долларов, и каждый год они дорожали на 10 долларов. , так что занимаясь математикой, Вы понимаете, что если 20 лет назад они стоили 100 долларов, и каждый год они увеличиваются на 10 долларов, то этот год наверняка не будет исключением, и они будут расти так же, так что ваши часы будут стоить 100 долларов от 20 лет назад + 10 долларов за каждый прошедший год или 100 долларов + 20 * 10 долларов → 300 долларов.

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

Мы уже проходили через это раньше, но это важная концепция, которую мы должны четко понимать.

В науке о данных каждый раз, когда мы начинаем новый проект и у нас есть набор данных для построения модели, мы создаем раздел, мы делим все наши данные на 2 группы:

Обучающий набор:это работает как входные данные для модели, с этими данными наша модель поймет правила и характеристики, которые определяют, к какой группе принадлежит каждая запись. Давайте подумаем об этом так: нейронная сеть работает подобно новому человеческому мозгу, и самый эффективный способ научить ее отличать брюки от футболки — это взять много футболок и показать им: «Смотрите, это футболка, это тоже, это другое тоже», и мозг создаст правила, с которыми он сможет идентифицировать, когда мы покажем ему предмет одежды и спросим «что это?», так что именно это мы и будем делать, мы возьмем часть наших данных из изображений с их рейтингами и покажем их модели.

Тестовый набор:это работает как вторая часть обучения, когда вы показываете своему новому мозгу стопку футболок и штанов, вы должны проверить, действительно ли он понял, как отличить одну вещь от другой. другой, поэтому вы возвращаетесь к своему шкафу и берете джинсы, показываете их ему и на этот раз спрашиваете: «Это рубашка или брюки?» теперь будет недостаточно спросить его только один раз, мы будем спрашивать его много раз в разной одежде, это нормально, что у него есть что-то правильное и что-то неправильное, это даст нам измерение, называемое «точность», которое скажет нам, как насколько мы можем доверять нашей модели, может быть, из 10 предметов одежды, которые мы вам показываем, вы получите только 8 правильных. наша цель как специалистов по данным состоит в том, чтобы сделать наши модели максимально точными.

Для набора данных рекомендуется соотношение 80–20 или 70–30, при котором наибольшее количество данных передается модели в качестве обучения, а наименьшее — для обучения. оставил для тестирования, но эти значения могут измениться, если того требует ситуация.

Шаг 1. Импортируйте библиотеку и API, с которыми мы будем работать.

# Use seaborn for pairplot.
pip install -q seaborn
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

# Make NumPy printouts easier to read.
np.set_printoptions(precision=3, suppress=True)
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

print(tf.__version__)

Шаг 2. Давайте принесем данные, которые мы будем использовать.

Набор данных Auto MPG

Набор данных доступен в Хранилище машинного обучения UCI.

Сначала мы загружаем и импортируем набор данных с помощью pandas:

url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
                'Acceleration', 'Model Year', 'Origin']

raw_dataset = pd.read_csv(url, names=column_names,
                          na_values='?', comment='\t',
                          sep=' ', skipinitialspace=True)
dataset = raw_dataset.copy()
dataset.tail()

Шаг 3. Очистите набор данных

dataset.isna().sum()

dataset = dataset.dropna()

Столбец "Origin" является категориальным, а не числовым. Итак, следующим шагом будет горячее кодирование значений в столбце с помощью pd.get_dummies.

dataset['Origin'] = dataset['Origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
dataset = pd.get_dummies(dataset, columns=['Origin'], prefix='', prefix_sep='')
dataset.tail()

Что мы только что сделали, так это создали столбец для каждого возможного значения, которое может принимать столбец "Origin", что делает теперь вопрос о двоичных переменных, поэтому каждая запись может иметь столбец страны, из которой она исходит, в «1». и, исключительно, остальные будут равны 0, это оставляет нам только числовые переменные во всех полях.

Шаг 4. Разделите данные на наборы для обучения и тестирования.

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

train_dataset = dataset.sample(frac=0.8, random_state=0)
test_dataset = dataset.drop(train_dataset.index)

Шаг 5. Проверьте данные (необязательно).

Давайте рассмотрим совместное распределение нескольких пар столбцов из обучающей выборки.

Верхний ряд предполагает, что эффективность использования топлива (MPG) является функцией всех других параметров. В других строках указано, что они являются функциями друг друга.

sns.pairplot(train_dataset[['MPG', 'Cylinders', 'Displacement', 'Weight']], diag_kind='kde')

Также проверим общую статистику. Обратите внимание, что каждая функция охватывает очень разные диапазоны:

train_dataset.describe().transpose()

Шаг 6. Проверьте данные.

Мы отделим целевое значение — «метку» — от характеристик. Эта метка является значением, которое мы будем обучать модели предсказывать.

train_features = train_dataset.copy()
test_features = test_dataset.copy()

train_labels = train_features.pop('MPG')
test_labels = test_features.pop('MPG')

Нормализация

Рекомендуется нормализовать функции, использующие разные масштабы и диапазоны.

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

Хотя модель может сойтись без нормализации признаков, нормализация делает обучение более стабильным.

tf.keras.layers.Normalization — это чистый и простой способ добавить нормализацию признаков в нашу модель.

Первым шагом является создание слоя:

normalizer = tf.keras.layers.Normalization(axis=-1)

Затем подгоните состояние слоя предварительной обработки к данным, вызвав Normalization.adapt:

normalizer.adapt(np.array(train_features))

Вычислите среднее значение и дисперсию и сохраните их в слое:

print(normalizer.mean.numpy())

Когда слой вызывается, он возвращает входные данные, причем каждая функция нормализована независимо:

first = np.array(train_features[:1])

with np.printoptions(precision=2, suppress=True):
  print('First example:', first)
  print()
  print('Normalized:', normalizer(first).numpy())

Шаг 7. Сначала потренируйтесь в линейной регрессии (необязательно).

Прежде чем мы углубимся в создание глубокой нейронной сети регрессии, было бы неплохо немного попрактиковаться в создании базовой модели линейной регрессии, поскольку эта часть не требуется для обзора учебного пособия, которое мы делаем сегодня, не стесняйтесь проверить его. или пропустите его, если хотите.

Практика линейной регрессии в первую очередь

Шаг 8. Регрессия с помощью глубокой нейронной сети (DNN).

В предыдущем разделе мы реализовали две линейные модели для одного и нескольких входов.

Здесь мы будем реализовывать модели DNN с одним и несколькими входами.

Код в основном такой же, за исключением того, что модель расширена за счет включения некоторых «скрытых» нелинейных слоев. Название «скрытый» здесь просто означает, что он не подключен напрямую к входам или выходам.

Эти модели будут содержать на несколько слоев больше, чем линейная модель:

  • Слой нормализации, как и раньше (с horsepower_normalizer для модели с одним входом и normalizer для модели с несколькими входами).
  • Два скрытых нелинейных Dense слоя с нелинейностью функции активации ReLU (relu).
  • Линейный Dense слой с одним выходом.

Обе модели будут использовать одну и ту же процедуру обучения, поэтому метод compile включен в функцию build_and_compile_model ниже.

def build_and_compile_model(norm):
  model = keras.Sequential([
      norm,
      layers.Dense(64, activation='relu'),
      layers.Dense(64, activation='relu'),
      layers.Dense(1)
  ])

  model.compile(loss='mean_absolute_error',
                optimizer=tf.keras.optimizers.Adam(0.001))
  return model

Регрессия с использованием DNN и одного входа

Создайте модель DNN только с 'Horsepower' в качестве входных данных и horsepower_normalizer (определенным ранее) в качестве слоя нормализации:

dnn_horsepower_model = build_and_compile_model(horsepower_normalizer)

Обучите модель с помощью Keras Model.fit:

%%time
history = dnn_horsepower_model.fit(
    train_features['Horsepower'],
    train_labels,
    validation_split=0.2,
    verbose=0, epochs=100)

Эта модель работает немного лучше, чем линейная модель с одним входом horsepower_model:

plot_loss(history)

Соберите результаты на тестовом наборе на потом:

test_results['dnn_horsepower_model'] = dnn_horsepower_model.evaluate(
    test_features['Horsepower'], test_labels,
    verbose=0)

Регрессия с использованием DNN и нескольких входных данных

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

dnn_model = build_and_compile_model(normalizer)
dnn_model.summary()
%%time
history = dnn_model.fit(
    train_features,
    train_labels,
    validation_split=0.2,
    verbose=0, epochs=100)
plot_loss(history)

Соберите результаты на тестовом наборе:

test_results['dnn_model'] = dnn_model.evaluate(test_features, test_labels, verbose=0)

Шаг 9. Оценим эффективность.

Поскольку все модели были обучены, мы можем проверить их производительность набора тестов (для этого обзора мы включим результаты необязательных моделей простой линейной регрессии, вы можете проверить их по ссылке шага 7):

pd.DataFrame(test_results, index=['Mean absolute error [MPG]']).T

Шаг 10. Делайте прогнозы.

Наконец, самое интересное, заставить этого плохого парня работать.

теперь мы можем делать прогнозы с dnn_model на тестовом наборе с помощью Keras Model.predict и просматривать потери:

test_predictions = dnn_model.predict(test_features).flatten()

a = plt.axes(aspect='equal')
plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
lims = [0, 50]
plt.xlim(lims)
plt.ylim(lims)
_ = plt.plot(lims, lims)

Теперь проверьте распределение ошибок:

error = test_predictions - test_labels
plt.hist(error, bins=25)
plt.xlabel('Prediction Error [MPG]')
_ = plt.ylabel('Count')

Теперь, когда мы довольны моделью, давайте сохраним ее для последующего использования с Model.save:

dnn_model.save('dnn_model')

Если мы перезагрузим модель, она даст идентичный результат:

reloaded = tf.keras.models.load_model('dnn_model')

test_results['reloaded'] = reloaded.evaluate(
    test_features, test_labels, verbose=0)
pd.DataFrame(test_results, index=['Mean absolute error [MPG]']).T

Спасибо, что прочитали

И вот оно, из этого мы можем создать гораздо больше приложений, а также более сложные прогнозы для большего количества применений. Регрессия — один из наиболее широко используемых методов для всех типов приложений, и его можно найти во многих моделях прогнозирования.

Большое спасибо за чтение, для получения дополнительной информации об этом примере вы можете обратиться: TensorFlor Tutorials/Regression

Надеюсь, вам понравилось.