От линейной модели к нейросети
ЧерновикМатериалы дорабатываются и будут дополняться.
Чему научимся
В этом параграфе разберём, как из линейной модели получается нейронная сеть. Вы сможете:
- объяснить, зачем нейрону нелинейная функция активации;
- выполнить прямой проход маленькой сети вручную и в Python;
- проверить формы входа, весов, скрытого слоя и выхода;
- показать на примере, почему один скрытый слой решает задачу, недоступную прямой.
Когда одной прямой мало
Начнём с учебной задачи о двух признаках. Ответ равен 1, если ровно один из признаков равен 1, и равен 0 во всех остальных случаях. Такую операцию называют исключающим ИЛИ, или XOR.
| Класс |
||
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Посмотрим на четыре точки на плоскости (рисунок 1). Точки класса 1 стоят в противоположных углах квадрата, а точки класса 0 — в двух других углах. Отрезок между точками
Линейная модель из занятия 1.3 и логистическая регрессия из занятия 1.6 проводят именно прямую границу. На этих четырёх примерах любая такая граница верно ответит не более чем на три вопроса, то есть даст accuracy не выше
Нейрон: взвешенная сумма и активация
Нейрон получает несколько чисел, умножает каждое на свой вес, складывает результаты и прибавляет смещение:
Полученное число
Без функции активации нейрон остаётся линейной моделью: он умеет только взвешивать входы и сдвигать результат. Две такие операции подряд снова дают линейное преобразование, поэтому глубокая сеть без нелинейности не стала бы выразительнее одного слоя.
В скрытых слоях часто используют ReLU:
Она пропускает положительные значения без изменений, а отрицательные заменяет нулём. На выходе для вероятности класса применяют сигмоиду:
Сигмоида принимает любое число и возвращает значение от 0 до 1. Если вероятность не меньше
Слой и формы данных
Нейроны объединяют в полносвязный слой: каждый его нейрон получает все входы предыдущего слоя. Если на вход подать вектор
Матрица
| Величина | Форма | Что означает |
|---|---|---|
| пакет из |
||
| веса двух скрытых нейронов | ||
| смещения двух скрытых нейронов | ||
| выходы скрытого слоя для всех объектов | ||
| веса выходного нейрона | ||
| смещение выходного нейрона | ||
| взвешенная сумма и вероятность для каждого объекта |
На рисунке 2 данные идут слева направо: каждый вход связан с обоими скрытыми нейронами, а их выходы собираются в один ответ. Прямой проход — это последовательное применение таких слоёв. Веса при этом не меняются: мы только вычисляем ответ. Число нейронов в слое называют его шириной, а число слоёв — глубиной. Сеть из таблицы имеет один скрытый слой и часто называется многослойным перцептроном, или MLP.
Разбираем сеть для XOR
Зададим конкретные веса. Пока это не результат обучения, а специально подобранный пример, на котором удобно считать вручную:
Скрытые нейроны вычисляют
Первый нейрон становится активным, когда среди входов есть хотя бы одна единица. Второй — только когда обе единицы присутствуют одновременно. Выход собирает эти два признака:
Проверим два случая. Для входа
| Ответ | ||||||
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | −0,25 | 0,44 | 0 |
| 0 | 1 | 0,5 | 0 | 0,25 | 0,56 | 1 |
| 1 | 0 | 0,5 | 0 | 0,25 | 0,56 | 1 |
| 1 | 1 | 1,5 | 0,5 | −0,25 | 0,44 | 0 |
Сеть решила задачу не потому, что стала «умнее» прямой, а потому, что скрытый слой построил новые признаки: «есть хотя бы одна единица» и «есть обе единицы». Выходной нейрон сравнивает их и даёт высокий ответ только в двух средних строках. Вероятности здесь близки к
Тот же расчёт в Python
Повторим вычисления без внешних библиотек. Функции relu и sigmoid принимают одно число, а forward выполняет весь прямой проход.
import math
def relu(z):
return max(0.0, z)
def sigmoid(z):
return 1 / (1 + math.exp(-z))
def forward(x1, x2):
h1 = relu(x1 + x2 - 0.5)
h2 = relu(x1 + x2 - 1.5)
z = h1 - 3 * h2 - 0.25
return h1, h2, z, sigmoid(z)
for x1, x2 in [(0, 0), (0, 1), (1, 0), (1, 1)]:
h1, h2, z, p = forward(x1, x2)
answer = int(p >= 0.5)
print(f"{x1} {x2} | {h1:.1f} {h2:.1f} | {z:+.2f} | {p:.3f} | {answer}")
Программа напечатает:
0 0 | 0.0 0.0 | -0.25 | 0.438 | 0
0 1 | 0.5 0.0 | +0.25 | 0.562 | 1
1 0 | 0.5 0.0 | +0.25 | 0.562 | 1
1 1 | 1.5 0.5 | -0.25 | 0.438 | 0
Результат совпадает с таблицей. В библиотеках для нейросетей те же действия выполняются сразу для пакета объектов: вход получает форму (n, 2), после первого слоя — (n, 2), после выходного — (n, 1). Если форма не совпала, чаще всего перепутаны число признаков и число объектов.
Попробуйте сами
-
Вычислите вручную прямой проход для входа
: найдите , , , вероятность и ответ. Затем проверьте себя программой. Для самопроверки: , , , , ответ 1. -
Замените в программе смещение
на . Пересчитайте все четыре строки и объясните, почему сеть перестала решать XOR. Для самопроверки: все вероятности окажутся больше , поэтому сеть ответит 1 всем объектам и угадает только два ответа из четырёх. -
Для сети, которая получает пять объектов с четырьмя признаками и имеет скрытый слой из трёх нейронов, выпишите формы
, , , , и . Проверьте, что число столбцов каждой матрицы совпадает с размером входа следующей операции. -
Уберите ReLU из сети и оставьте только линейные преобразования. Покажите, что два слоя можно заменить одним линейным преобразованием. Объясните, почему после этого задача XOR снова становится нерешаемой.
Что стоит унести с собой
Нейрон вычисляет взвешенную сумму входов и применяет к ней функцию активации. Слой объединяет несколько таких нейронов, а прямой проход последовательно передаёт данные от входа к выходу. Нелинейная активация нужна, чтобы сеть могла строить границы сложнее прямой. На примере XOR мы увидели, как скрытый слой создаёт новые признаки, а выходной слой принимает по ним решение.
В следующем параграфе мы не будем задавать веса вручную: покажем, как сеть измеряет ошибку и постепенно подстраивает параметры на учебных примерах.
Самопроверка
Проверено 0 из 6
Подсказка
Что произойдёт, если оставить только взвешенные суммы и смещения?
Решение
B. Без нелинейной активации несколько слоёв сводятся к одному линейному преобразованию, поэтому граница остаётся прямой.
Подсказка
Строка матрицы соответствует одному нейрону, столбец — одному входу.
Решение
A. Три нейрона дают три строки, четыре признака — четыре столбца. Смещений при этом три, а не четыре.
Подсказка
ReLU заменяет отрицательное значение нулём, а положительное оставляет как есть.
Решение
B.
Подсказка
Нарисуйте четыре точки квадрата и соедините точки класса 1.
Решение
B. Точки классов расположены через одну, и отрезки, соединяющие пары, пересекаются. Прямая не может развести концы пересекающихся отрезков по разные стороны.
Подсказка
Сначала вычислите взвешенную сумму второго нейрона, затем примените ReLU.
Решение
A.
Подсказка
Подставьте выход первого слоя во второй и раскройте скобки.
Решение
B. Если