Нейронная сеть для классификации с помощью Tensorflow

Исходный узел: 1570297

Эта статья была опубликована в рамках Блогатон по Data Science

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

такое нейронная сеть?

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

Что такое Классификация?

Проблема классификации включает в себя предсказание того, принадлежит ли что-то к одному классу или нет. Другими словами, делая это, мы пытаемся увидеть что-то одно или другое.

Типы классификации

  • Предположим, вы хотите предсказать, есть ли у человека диабет или нет. Если вы столкнулись с такой ситуацией, есть две возможности, верно? Это называется Бинарная классификация.
  • Предположим, вы хотите определить, является ли фотография игрушкой, человеком или кошкой, верно? это называется Мультиклассовая классификация потому что вариантов больше двух.
  • Предположим, вы хотите решить, какие категории следует присвоить статье. Если да, то называется Многоуровневая классификация, так как одной статье может быть присвоено более одной категории. Давайте рассмотрим наше объяснение в этой статье. Мы можем назначить этой статье такие категории, как «Глубокое обучение, TensorFlow, Классификация» и т. д.

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

Начнем с импорта библиотек, которые будем использовать:

импортировать numpy как np импортировать pandas как pd импортировать matplotlib.pyplot как plt импортировать тензорный поток как tf print (tf.__version__)

Создание набора данных

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

из sklearn.datasets импортировать образцы make_circles = 1000 X, y = make_circles (образцы, шум = 0.03, random_state = 42)

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

Print (x >> [[0.75424625 0.23148074] [-0.75615888 0.15325888] [-0.81539193 0.17328203] ... [-0.13690036 -0.81001183] [0.67036156 -0.76750154] [0.28105665 0.96382443]]
print(y) >> [1 1 1 1 0 1 1 1 1 0]

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

круг = pd.DataFrame({ 'X0': X[:, 0], 'X1': X[:, 1], 'метка': y}) circle.head()
Нейронная сеть для классификации с головкой данных Tensorflow

Тут возникает один вопрос, с какими ярлыками мы имеем дело?

Circle.label.value_counts() >> 1 500 0 500 Имя: метка, dtype: int64

Похоже, мы имеем дело с проблема бинарной классификации, потому что у нас есть 2 метки (0 и 1).

plt.scatter(X[:,0], X[:,1], c = y, cmap = plt.cm.RdYlBu)
Нейронная сеть для классификации с диаграммой рассеяния Tensorflow

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

Перед построением любой модели нейронной сети мы должны проверить формы наших входных и выходных функций. они должны быть одинаковыми!

print(X.shape, y.shape) print(len(X), len(y)) >> (1000, 2) (1000,) 1000 1000

У нас одинаковое количество значений для каждой функции, но форма X отличается? Почему? Давайте проверим это.

X[0], y[0] >> (массив([0.75424625, 0.23148074]), 1)

Хорошо, у нас есть функции 2 X на 1 год. Таким образом, мы можем двигаться вперед без каких-либо проблем.

Этапы моделирования нейронной сети для классификации с помощью Tensorflow

В TensorFlow есть фиксированные этапы создания модели:

  • Создание модели - собрать воедино слои нейронной сети, используя функциональный или последовательный API
  • Компиляция модели - определение того, как следует измерять производительность модели и как ее следует улучшать (функция потерь и оптимизатор)
  • Установка режимаl — позволять модели находить закономерности в данных

Мы будем использовать Sequential API. Итак, приступим

tf.random.set_seed(42)
model_1 = tf.keras.Sequential([tf.keras.layers.Dense(1)])

model_1.compile(потеря = tf.keras.losses.BinaryCrossentropy(),

# мы используем Binary как функцию потерь, потому что мы работаем с 2 классами

 оптимизатор = tf.keras.optimizers.SGD(), #SGD означает Stochastic Gradient Descent metrics = ['accuracy']) model_1.fit(X, y, epochs = 5)
>> Эпоха 1/5 32/32 [==============================] - 1 с 1 мс/шаг - потери: 2.8544 - точность: 0.4600 Эпоха 2/5 32/32 [==============================] - 0 с 2 мс/шаг - потери : 0.7131 - точность: 0.5430 Эпоха 3/5 32/32 [=============================] - 0 с 2 мс/шаг - потери: 0.6973 - точность: 0.5090 Эпоха 4/5 32/32 [=============================] - 0 с 2 мс /шаг - потеря: 0.6950 - точность: 0.5010 Эпоха 5/5 32/32 [=============================] - 0 с 1 мс/шаг - потери: 0.6942 - точность: 0.4830

Точность модели составляет примерно 50%, что в основном означает, что модель просто угадывает, давайте попробуем тренировать ее дольше

model_1.fit(X, y, epochs = 200, verbose = 0) # мы устанавливаем verbose = 0, чтобы удалить процедуру обучения) model_1.evaluate(X, y)
>> 32/32 [==============================] - 0 с 1 мс/шаг - потери: 0.6935 - точность: 0.5000 [0.6934829950332642, 0.5]

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

tf.random.set_seed(42)
model_2 = tf.keras.Sequential([ tf.keras.layers.Dense(1), tf.keras.layers.Dense(1) ]) model_2.compile(loss = tf.keras.losses.BinaryCrossentropy(), оптимизатор = tf.keras.optimizers.SGD(), metrics = ['точность']) model_2.fit(X, y, epochs = 100, verbose = 0)
 model_2.evaluate(X,y)
>> 32/32 [==============================] - 0 с 1 мс/шаг - потери: 0.6933 - точность: 0.5000 [0.6933314800262451, 0.5]

Тем не менее, нет даже небольшого изменения, кажется, что-то не так.

Улучшение модели нейронной сети для классификации с помощью Tensorflow

Существуют разные способы улучшения модели на разных этапах:

  • Создание модели – добавить больше слоев, увеличить количество скрытых единиц (нейронов), изменить функции активации каждого слоя
  • Составление модели – попробуйте разные функции оптимизации, например, используйте Adam() вместо SGD().
  • Подгонка модели – мы могли бы увеличить количество эпох

Попробуем добавить больше нейронов и попробуйте Адам оптимизатор

tf.random.set_seed(42)
model_3 = tf.keras.Sequential([ tf.keras.layers.Dense(100), # добавляем 100 плотных нейронов tf.keras.layers.Dense(10), # добавляем еще один слой с 10 нейронами tf.keras.layers.Dense (1) ]) model_3.compile(loss=tf.keras.losses.BinaryCrossentropy(), оптимизатор=tf.keras.optimizers.Adam(), metrics=['точность']) model_3.fit(X, y, эпохи =100, подробный=0)
model_3.evaluate(X,y) >> 32/32 [=============================] - 0 с 1 мс/шаг - потери: 0.6980 - точность: 0.5080 [0.6980254650115967, 0.5080000162124634]

Все еще не становится лучше! Давайте визуализируем данные, чтобы увидеть, что происходит не так.

Визуализируйте модель нейронной сети

Чтобы визуализировать прогнозы нашей модели, мы создадим функцию plot_decision_boundary(), которая:

  • Принимает обученную модель, функции и метки
  • Создайте meshgrid различных значений X.
  • Делает прогнозы по ячеистой сетке.
  • Строит прогнозы линией.

Примечание:  Эта функция была адаптирована из двух ресурсов:

CS231n Сделано с основами машинного обучения 

def plot_decision_boundary(model, X, y): # Определяем границы осей графика и создаем сетку x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1 y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np .linspace(y_min, y_max, 100)) # Создаем значения X (мы собираемся прогнозировать все из них) x_in = np.c_[xx.ravel(), yy.ravel()] # Делаем прогнозы, используя обученный model y_pred = model.predict(x_in) # Проверка мультикласса
 if len(y_pred[0]) > 1: print("делаем мультиклассовую классификацию...") # Мы должны изменить наши прогнозы, чтобы подготовить их для построения графика y_pred = np.argmax(y_pred, axis=1).reshape( xx.shape) else: print("выполнение бинарной классификации...") y_pred = np.round(y_pred).reshape(xx.shape) # Граница решения на графике plt.contourf(xx, yy, y_pred, cmap=plt. см.RdYlBu, альфа=0.7) plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlBu) plt.xlim(xx.min( ), xx.max()) plt.ylim(yy.min(), yy.max()) plot_decision_boundary(model_3, X, y)
граница принятия решения

Вот! Снова визуализация показывает нам, что не так и что делать? Наша модель пытается провести прямую линию через данные, но наши данные не могут быть разделены прямой линией. Что-то упущено в нашей задаче классификации? Что это?

Это нелинейность! Нам нужны нелинейные линии. Вы можете запутаться сейчас, если вы думаете, что раньше не видели такой функции, вы ошибаетесь, потому что у вас есть. Давайте посмотрим на них визуально. Визуализация всегда работает лучше!

В нейронной сети есть некоторые функции активации, которые мы можем использовать, например РеЛу, сигмоид. Давайте создадим немного игрушка тензор и проверьте эти функции на нем.

Функции активации для нейронных сетей

A = tf.cast(tf.range(-12,12), tf.float32) print(A) >> tf.Tensor([-12.-11.-10.-9.-8.-7.- 6.-5.-4.-3.-2.-1.], shape=(0,), dtype=поплавок1)

Давайте посмотрим, как выглядит наш игрушечный тензор?

пл.участок(A)
Функции активации для нейронных сетей

Это выглядит так, прямая линия! 

Теперь давайте воссоздадим функции активации, чтобы посмотреть, что они делают с нашим тензором?

сигмовидной:

def sigmoid(x): return 1 / (1 + tf.exp(-x)) sigmoid(A) plt.plot(sigmoid(A))
сигмовидная функция

Непрямая линия!

РеЛу:

Теперь давайте проверим, что делает ReLu? Relu превращает все отрицательные значения в 0, а положительные значения остаются прежними.

def relu(x): вернуть tf.maximum(0,x) plt.plot(relu(A))
РеЛу

Еще одна непрямая линия!

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

X_train, y_train = X[:800], y[:800] X_test, y_test = X[800:], y[800:] X_train.shape, X_test.shape >>((800, 2), (200, 2 ))

 

Отлично, теперь у нас есть тренировочный и тестовый наборы, давайте смоделируем обучающие данные и оценим, чему научилась наша модель на тестовом наборе.

tf.random.set_seed(42)
model_4 = tf.keras.Sequential([ tf.keras.layers.Dense(4, активация = 'relu'), # мы также можем исправить "tf.keras.activations.relu" tf.keras.layers.Dense(4 , активация = 'relu'), tf.keras.layers.Dense (1, активация = 'сигмоид') ]) model_4.compile (потеря = tf.keras.losses.binary_crossentropy, оптимизатор = tf.keras.optimizers.Adam ( lr = 0.01), metrics = ['точность']) model_4.fit(X_train, y_train, epochs = 25, verbose = 0)

Оцените модель

потери, точность = model_4.evaluate(X_test, y_test) print(f' Потери модели на тестовом наборе: {потеря}') print(f' Точность модели на тестовом наборе: {100*точность}')
>> 7/7 [==============================] - 0 с 2 мс/шаг - потери: 0.1247 - точность: 1.0000 Потеря модели на тестовом наборе: 0.1246885135769844 Точность модели на тестовом наборе: 100.0

Вуаля! 100% точность! давайте посмотрим на этот результат визуально

plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.title("Поезд") plot_decision_boundary(model_4, X=X_train, y=y_train) plt.subplot(1, 2, 2) plt.title("Тест") plot_decision_boundary(model_4, X=X_test, y=y_test) plt.show()
бинарная нейронная сеть для классификации с помощью Tensorflow

С помощью всего лишь нескольких настроек наша модель теперь почти идеально предсказывает синие и красные круги.

Заключение

Давайте кратко рассмотрим, о чем мы говорим в этой статье. Вместе мы рассмотрели, как подойти к задаче классификации в нейронной сети с помощью TensorFlow. Первым пришедшим в голову способом мы создали 3 модели, а с помощью визуализации поняли, где были не правы, исследовали линейность, нелинейность и, наконец, нам удалось построить обобщенную модель. Всеми этими кодами и шагами, которые я выполнял, я пытался показать, что ничто не является точным или фиксированным на 100%, все продолжает меняться каждый день. Чтобы угадать, с какой проблемой вы, скорее всего, столкнетесь и с какими данными, и увидеть, какие комбинации приводят к лучшему результату, все, что вам нужно, — это написать намного больше кода и набраться опыта.

Я надеюсь, что статья была немного полезной для вас и внесла свой вклад.

Медиа, показанные в этой статье, не принадлежат Analytics Vidhya и используются по усмотрению автора.

Источник: https://www.analyticsvidhya.com/blog/2021/11/neural-network-for-classification-with-tensorflow/

Отметка времени:

Больше от Аналитика Видхья