Нейронна мережа для класифікації з Tensorflow

Вихідний вузол: 1570297

Ця стаття була опублікована як частина Блогатон науки про дані

У цій статті я буду будувати моделі нейронної мережі за допомогою TensorFlow, щоб вирішити проблему класифікації. Давайте разом дослідимо, як ми можемо підійти до проблеми класифікації в Tensorflow. Але спочатку я хотів би переконатися, що ми можемо відповісти на ці запитання:

це нейронна мережа?

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

Що таке класифікація?

Проблема класифікації передбачає передбачення того, чи належить щось до одного класу чи ні. Іншими словами, роблячи це, ми намагаємося побачити щось те чи інше.

Види класифікації

  • Припустімо, ви хочете передбачити, чи є у людини діабет чи ні. Якщо ви зіткнулися з такою ситуацією, є дві можливості, чи не так? Це називається Бінарна класифікація.
  • Припустімо, що ви хочете визначити, чи є на фотографії іграшка, людина чи кіт, вірно? це називається Багатокласова класифікація тому що є більше двох варіантів.
  • Припустімо, ви хочете вирішити, які категорії слід призначити статті. Якщо так, то називається Класифікація з кількома мітками, тому що одній статті може бути призначено більше однієї категорії. Давайте розглянемо наше пояснення в цій статті. Ми можемо призначити цій статті такі категорії, як «Глибоке навчання, TensorFlow, класифікація» тощо.

Тепер ми можемо рухатися вперед, тому що у нас є спільне розуміння проблеми, над якою будемо працювати. Отже, настав час кодування. Я сподіваюся, що ви записуєте їх разом зі мною, тому що єдиний спосіб стати кращим, робити менше помилок – це написати більше коду.

Ми починаємо з імпорту бібліотек, які будемо використовувати:

import numpy as np import pandas as pd import matplotlib.pyplot as plt import tensorflow as tf print(tf.__version__)

Створення набору даних

Настав час створити набір даних для роботи:

із sklearn.datasets імпортувати make_circles samples = 1000 X, y = make_circles (зразки, noise = 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 XNUMX]]
print(y) >> [1 1 1 1 0 1 1 1 1 0]

Гаразд, ми бачили наш набір даних більш детально, але ми все ще нічого про нього не знаємо, чи не так? Тому тут один важливий крок — стати єдиним цілим з даними, а візуалізація — найкращий спосіб це зробити.

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

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

circle.label.value_counts() >> 1 500 0 500 Назва: label, 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)
модель_1 = tf.keras.Sequential([tf.keras.layers.Dense(1)])

model_1.compile(loss = tf.keras.losses.BinaryCrossentropy(),

#ми використовуємо Binary як функцію втрати, тому що ми працюємо з 2 класами

 optimizer = 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(), optimizer = tf.keras.optimizers.SGD(), metrics = ['accuracy']) 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(), optimizer=tf.keras.optimizers.Adam(), metrics=['accuracy']) 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(), яка:

  • Бере навчену модель, функції та мітки
  • Створіть сітку різних значень X.
  • Робить прогнози по сітці.
  • Наносить прогнози лінією.

Примітка:  Цю функцію було адаптовано з двох ресурсів:

CS231n Створено на основі ML 

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. cm.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)
межа рішення

Ось! Знову візуалізація показує нам, що не так і що робити? Наша модель намагається провести пряму лінію через дані, але наші дані не можна розділити прямою лінією. У нашій проблемі класифікації щось не вистачає? Що це?

Це нелінійність! Нам потрібні нелінійні лінії. Зараз ви можете заплутатися, якщо ви думаєте, що раніше не бачили такої функції, ви помиляєтеся, тому що ви бачили таку функцію. Розглянемо їх візуально. Візуалізація завжди працює краще!

У нейронній мережі є деякі функції активації, якими ми можемо скористатися, наприклад ReLu, Сигмоїдний. Давайте трошки творити іграшковий тензор і перевірте ці функції на ньому.

Функції активації для нейронних мереж

A = tf.cast(tf.range(-12,12), tf.float32) print(A) >> tf.Tensor( [-12. -11. -10. -9. -8. -7. - 6. -5. dtype=float4)

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

plt.plot(A)
Функції активації для нейронних мереж

Виглядає так, пряма лінія! 

Тепер давайте відтворимо функції активації, щоб побачити, що вони роблять з нашим тензором?

сигмоподібний:

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

Непряма!

ReLu:

Тепер давайте перевіримо, що робить ReLu? Relu перетворює всі негативні значення на 0, а позитивні значення залишаються незмінними.

def relu(x): повертає tf.maximum(0,x) plt.plot(relu(A))
ReLu

Ще одна непряма!

Тепер ви побачили нелінійні функції активації, і це те, що нам підійде, модель не може нічого дізнатися на нелінійному наборі даних із лінійними функціями активації! Якщо ви дізналися про це, настав час розділити наші дані на навчальні та тестові набори та створити надійні моделі.

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, activation = 'relu'), #ми також можемо виправити "tf.keras.activations.relu" tf.keras.layers.Dense(4 , activation = 'relu'), tf.keras.layers.Dense(1, activation = 'sigmoid') ]) model_4.compile( loss= tf.keras.losses.binary_crossentropy, optimizer = tf.keras.optimizers.Adam( lr = 0.01), metrics = ['accuracy']) model_4.fit(X_train, y_train, epochs = 25, verbose = 0)

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

loss, accuracy = model_4.evaluate(X_test, y_test) print(f' Втрата моделі на тестовому наборі: {loss}') print(f' Точність моделі на тестовому наборі: {100*accuracy}')
>> 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/

Часова мітка:

Більше від Аналітика Vidhya