You are on page 1of 29

Багатошаровий персептрон

• Одним з найпростіших типів нейронних мереж є персептрон.


• Реалізація багатошарового персептрона на Python з
використанням надбудови для глибокого навчання Keras.
Keras - відкрита бібліотека, написана на
мові Python і викликає взаємодія з
штучними нейронними мережами. Вона
являє собою надбудову над фреймворком
TensorFlow.

TensorFlow - відкрита програмна бібліотека


для машинного навчання, розроблена
компанією Google для вирішення завдань
побудови і тренування нейронної мережі з
метою автоматичного знаходження та
класифікації образів, досягаючи якості
людського сприйняття.
• Найпростішим прикладом нейронної мережі є багатошаровий (в
окремому випадку, одношаровий) персептрон.
• Розглянемо, що собою являє така модель.
• Одношаровий (багатошаровий) персептрон складається з:
• вхідного вектора (вхідні дані),
• вихідного вектора (вихідні дані),
• вектора (ів) проміжного представлення (прихований (і) шар).
• Елементи векторів прийнято ще називати нейронами.
• Обчислення в такій моделі поширюються від входу до виходу.
• Зв'язкам між нейронами на різних шарах відповідають деякі ваги.
Тому така мережа є повнозв'язною.
Що відбувається в
одному нейроні

У нейрон надходять вхідні значення, наприклад, 𝑥1, 𝑥2, 𝑥3 (елементи вхідного вектора) з відповідними
вагами 𝑤1, 𝑤2, 𝑤3.
Далі, всередині нейрона відбувається обчислення: обчислюємо зважену суму вхідних значень і додаємо
деякий параметр зміщення 𝑏, від отриманих на попередньому кроці значень, беремо нелінійну функцію 𝑓,
яку прийнято називати функцією активації.

Функція активації визначає вихідне значення нейрона в залежності від результату зваженої суми
входів і порогового значення.

Що вважати кордоном активації для функції активації?


Якщо значення Y більше деякого порогового значення, вважаємо нейрон активованим. В іншому випадку
говоримо, що нейрон неактивний.

Таким чином, вихідне значення ℎ з одного нейрона обчислюємо за формулою

Разом ці нейрони утворюють нейронну мережу.


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

• Обчислення в такій мережі можна представити у вигляді наступного рекурентного


співвідношення:

де 𝑮𝒘 – функція, що залежить від параметрів моделі (від ваг, що зв'язують нейрони і


зсувів).
Чим більше шарів в нейронної мережі, тим складніше проміжне представлення вона
має і тим складніші залежності між вхідними та вихідними даними вона здатна описати.
Яку функцію активації
використовувати
• Основна властивість функції активації - її нелінійність.
• Якби ми використовували лінійну функцію, то, по-перше, ми могли б вирішувати
тільки вузький клас задач, де залежність між вхідними та вихідними даними
описується лінійною функцією, а, по-друге, збільшення числа прихованих шарів не
підвищувало б ефективність нашої моделі, оскільки композиція лінійних функцій -
це все ще лінійна функція.
• Завдання функції активації - допомогти прийняти локальне рішення в кожному з
нейронів.
Наприклад, функція типу sigmoid відображає значення на виході з нейрона в щось
більше чи менше нуля.
Функція ReLU зануляє значення менші нуля, а значення быльші нуля, залишає як є. У
цій функції дуже проста похідна, а саме похідна цієї функції буде брати участь в
процесі навчання і в алгоритмі зворотного поширення помилки.
Як навчити нейронну мережу
• Нейронні мережі навчаються за допомогою, так званого навчання з
вчителем.
• Для цього необхідна навчальна вибірка - розмічені дані, які
складаються з пар «вхідний об'єкт - вихідний об'єкт».
• Ми подаємо цю навчальну вибірку в процес навчання, який полягає
в тому, щоб знайти такі параметри (ваги) моделі 𝑾, щоб наша
нейронна мережа передбачала правильно ті відповіді, які ми вже
знаємо.
• Таким чином, процес навчання зводиться до вирішення завдання
мінімізації або оптимізації функції помилки на тих прикладах, що є в
нашій навчальній вибірці.
Функцію помилки можна записувати по-різному. наприклад,

де (𝑫−𝑮𝒘(𝒁)) є різниця між правильною відповіддю 𝑫 і пророкуванням мережі 𝑮𝒘 (𝒁).

Від цієї різниці ми беремо норму, яку хочемо мінімізувати по всій навчальній вибірці. Потім ми шукаємо
такі параметри моделі 𝑾 *, які мінімізують цю помилку. Спочатку ваги моделі инициализируются
випадковими значеннями.
Задача оптимізації
• Можна застосувати добре відомий в теорії оптимізації метод градієнтного
спуску. Уявімо, що у нас є деяка функція, і ми хочемо знайти її мінімум. Ми
починаємо з деякою точки і нам необхідно зрозуміти, куди нам потрібно
рухатися, щоб наблизитися до мінімуму. Є вектор, який називається
градієнт. І цей вектор спрямований в бік зростання функції. Тому
антіградіент - це градієнт зі знаком мінус спрямований в бік зменшення
функції. Даний алгоритм пропонує рухатися в бік антіградіента і таким
чином наближатися до локального мінімуму.
• У разі нейронних мереж використовується модифікація - стохастичний
градієнтний спуск. Відмінність від попереднього градієнтного спуску в
тому, що ми не обчислюємо градієнт відразу на всіх зразках нашої вибірки,
а тільки на одному зразку за одну ітерацію або на групі зразків (міні батч).
Застосування багатошарового
персептрона до задачі класифікації
Розглянемо приклад використання двошарового персептрона для задач класифікації.

Припустимо, у нас є об'єкти, задані в тривимірному просторі ознак.


Це означає, що кожен об'єкт представляється вектором з трьох компонент.
Побудуємо нейронну мережу, у якій є три вхідних нейрона, як раз пропорційно нашому вхідному
об'єкту.
Припустимо, що вирішується задача бінарної класифікації, в якій необхідно визначити, до якого класу
(рожевому або фіолетового належить наш об'єкт).
Тому на виході ми маємо два вихідних нейрона. Припустимо, що ми вже навчили мережу.
Розглянемо, яким чином її тепер використовувати.
• Подаємо на вхід наш тривимірний вектор, що характеризує об'єкт
• виконуємо пряме поширення відповідно до формул, описаним вище,
• на виході отримуємо два числа.
Ці числа вже відповідають за приналежність вхідного об'єкта до того чи
іншого класу, але після спеціального перетворення ми отримуємо інші
два числа 𝑝1 і 𝑝2.
Ці числа явно характеризують ймовірність приналежності об'єкта до
одного або другого класу.
Таким чином, виходом з нейронної мережі в разі завдання класифікації
є розподіл ймовірностей приналежності до того чи іншого класу.
Визначимо багатошарову модель персептрона для бінарної
класифікації.
Модель має 10 входів, 3 прихованих шару з 10, 20 і 10
нейронами і вихідний шар з 1 виходом. Функції лінійної
активації використовуються в кожному прихованому шарі, а
функція активації сигмоїда використовується в вихідному
шарі для двійковій класифікації.

dense1 = Dense(32)(input) # create layer


dense1 = Dense(32)
# connect layer to previous layer
dense1(input)
Реалізація багатошарового персептрона
Розглянемо, як реалізувати модель багатошарового персептрона з використанням фреймворку для глибокого
навчання Keras.
Даний фреймворк є надбудовою над TensorFlow.
Будемо вирішувати задачу класифікації одягу на датасета Fashion MNIST.
Всі дані (зображення одягу) в Fashion MNIST поділяються на 10 класів
• 0 T-shirt / top (футболка / топ)
• 1 Trouser (брюки)
• 2 Pullover (пуловер)
• 3 Dress (плаття)
• 4 Coat (пальто)
• 5 Sandal (сандалі)
• 6 Shirt (сорочка)
• 7 Sneaker (кеди)
• 8 Bag (сумка)
• 9 Ankle boot (ботильйони).
Відкритий набір даних
60 тисяч зображень предметів одягу
Два фала
файл з зображеннями
файл з мітками класів (правильні відповіді - номера класів які
відповідають правильному об'єкту на зображенні)
Формат зображень
розмір 28*28 пикселів
відтінки сірого
зображення в бінарному вигляді записані в один файл
Вхідні значення мережі
інтенсивність пікселя в зображені
кількість значень 784 (28*28) .
Кожне число в діапазоні від 0-255

Вхідний шар 800 нейронів


Вихідний шар 10 нейронів
Ймовірність того, що на зображенні предмет одягу (0-1)
Імпортуємо необхідні бібліотеки:
• numpy - бібліотека для роботи c багатовимірними масивами і
матрицями,
• scikit-learn - бібліотека алгоритмів для вирішення задач
класичного машинного навчання,
• tensorflow - бібліотека для вирішення завдань побудови і
тренування нейронної мережі,
• keras - бібліотека для швидкої реалізації нейронних мереж, є
надбудовою над TensorFlow.
Завантажимо датасет Fashion MNIST
x_train і x_val - зображення одягу (28 на 28 пікселів) для навчальної
та валідаційної вибірки
y_train і y_val - правильні відповіді до відповідних зображень

from keras.datasets import mnist


(x_train, y_train), (x_val, y_val) =
tf.keras.datasets.fashion_mnist.load_data()
Перетворимо правильні відповіді y_train і y_val в one-hot encode.
Тобто, уявімо правильну відповідь у вигляді вектора, розмірність
якого дорівнює кількості класів в нашій задачі.
Нехай цей об'єкт належить класу з номером i. Тоді в i-ій позиції у
даного вектора буде стояти 1, а решта значення рівні 0.

y_train_oh = keras.utils.to_categorical(y_train,
10)
y_val_oh = keras.utils.to_categorical(y_val, 10)
Припустимо, що деяка ознака може приймати 10 різних значень. В
цьому випадку One Hot Encoding має на увазі створення 10 ознак,
всі з яких дорівнюють нулю за винятком одного. На позицію,
відповідну чисельним значенням ознаки ми поміщаємо 1.
• Як приклад побудуємо модель багатошарового персептрона з
двома прихованими шарами по 128 нейронів у кожному.
• Функції активації на прихованих шарах використовуватимемо
функцію elu.
• В якості функції помилки візьмемо перехресну ентропію (cross-
entropy):
Оцінити — означає вказати кількісно, добре чи погано мережа
вирішує поставлені їй завдання.
Для цього будується функція оцінки. Вона, як правило, явно
залежить від вихідних сигналів мережі і неявно (через
функціонування) — від всіх її параметрів.
Найпростіший і найпоширеніший приклад оцінки — сума
квадратів відстаней від вихідних сигналів мережі до їх
необхідних значень.
Щоб перетворити вихідні значення нейромережі 𝑧𝑘 в ймовірність
того, що вхідний об'єкт належить до того чи іншого класу
використовуємо функцію soft-max (іншими словами, нормуємо
значення):
Тепер перейдемо до складання моделі. Вхідні картинки витягнемо
в вектор довжини 28 * 28 (= 784) і будемо подавати його на вхід. На
виході маємо 10 вихідних нейронів за кількістю класів в нашій
задачі. Задаємо ці та описані вище параметри.
K.clear_session()
model = M.Sequential()
model.add(L.Dense(output_dim=128, input_dim=784, activation=‘relu'))
model.add(L.Dense(output_dim=128, activation='elu'))
model.add(L.Dense(output_dim=10, activation='softmax'))
• ReLu (Rectified Linear Unit) f(x)= max(0,x) Якщо вхідне значення
меньше 0, то функція повертає 0, а якщо більше 0 , то саме це
значення

• SoftMax - дозволяє отримати сумарне значення всіх нейронів на


виході з шару, що =1. Це дозволяє трактувати вихід з такого шару
як ймовірність.
В якості оптимізатора будемо використовувати не звичайний
стохастический градієнтний спуск, а його модифікацію ADAM - Adaptive
Moment Estimation.
model.compile(
loss='categorical_crossentropy', # минимизируем кросс-энтропию
optimizer='adam',
metrics=['accuracy'] # выводим процент правильных ответов
)

Центруємо і нормуємо вхідні дані, так, щоб значення змінювалися від -


0.5 до +0.5.
x_train_float = x_train.astype(np.float) / 255 - 0.5
x_val_float = x_val.astype(np.float) / 255 - 0.5
Навчимо модель, при цьому розмір міні батча візьмемо рівним 64 і встановимо кількість епох
навчання рівне 10.
model.fit(
x_train_float.reshape(-1, 28*28),
y_train_oh,
batch_size=64, # 64 об'єкти для підрахунку градієнта на кожному кроці
epochs=10, # 10 проходів по датасету
validation_data=(x_val_float.reshape(-1, 28*28), y_val_oh)
)

Точність отриманої моделі становить приблизно 0.8857 (88.57%).

одна епоха (epoch) - весь датасета пройшов через нейронну мережу в прямому і зворотному
напрямку тільки один раз.
Так як одна epoch занадто велика для комп'ютера, датасета ділять на маленькі партії (batches).

You might also like