Канал в ТГ: Kogut Ivan Tutoring

Этот пост в ТГ: https://t.me/KogutIvanTutoring/187

Ликбез про нейросети

Если вы совсем не знакомы с нейросетями, то советаю почитать учебник Яндекса: ссылка. Я лишь вкратце напомню ключевые моменты.

Базовым примером нейросети часто приводят классический алгоритм машинного обучения - логистическую регрессию. Можно считать, что это один маленький слой (блок), а значит можно сделать цепочку из таких блоков и получить уже более сложную нейросеть. Блоки бывают разных типов, но здесь нам это не важно. А вот что важно - из этих блоков можно составить сложную нейросеть, которая даже не обязательно выглядит как цепочка (см. Рис. 1). Поэтому будем говорить, что это вычислительный граф, а про его свойства поговорим в 2 блоке

Рис. 1 Пример сложной нейросети - GoogLeNet

Рис. 1 Пример сложной нейросети - GoogLeNet

Далее напомню, что по нейросети можно пройтись в двух направлениях: вперед (forward) и назад (backward). Кратко про каждый из проходов.

Forward pass

Нужен для получения ответа нейросети по входным данным (текст, картинка и т.п.). Используется и во время инференса модели, и во время ее обучения.

Прямой проход обычно всегда явно прописывается программистом. Пример такого кода:

import torch
import torch.nn as nn

class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.l_1 = nn.Linear(780, 100)
        self.act_1 = nn.ReLU()
        self.l_2 = nn.Linear(100, 10)

		# Именно здесь мы описываем, что делаем с входными данными
    def forward(self, x):
        x = self.l_1(x)
        x = self.act_1(x)
        x = self.l_2(x)
        return x

Backward pass

Подробно можно прочитать тоже в учебнике Яндекса: ссылка

Используется для обучения нейросети. Его еще называют “механизм обратного распространения ошибки”.

Нейросети оптимизируются с помощью градиентного спуска, и это значит, что нам нужно для каждого параметра понимать антиградиент функции потерь относительно этого параметра. Так как нейросеть это сложная функция, то и при дифференцировании применяется правило сложной функции или же chain rule:

$$ \frac{dz}{dx} = \frac{dz}{df(x)} \frac{df(x)}{dx} $$

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

В отличие от forward pass обратный проход обычно специально не прописывают и в том же PyTorch он делается автоматически. Давайте как раз подумаем и сделаем backward pass своими руками

Формулировка задачи backward propagation как алго задачи