# Введение в нейронные сети. Многослойный перцептрон В предыдущем разделе вы познакомились с самой простой моделью нейронной сети — однослойным перцептроном, который представляет собой линейную модель для двухклассовой классификации. В этом разделе мы расширим эту модель, чтобы создать более гибкую структуру, которая позволит: * выполнять **многоклассовую классификацию** в дополнение к двухклассовой, * решать задачи **регрессии** в дополнение к классификации, * разделять классы, которые не являются линейно разделимыми. Мы также разработаем собственный модульный фреймворк на Python, который позволит нам строить различные архитектуры нейронных сетей. ## [Вопросы перед лекцией](https://ff-quizzes.netlify.app/en/ai/quiz/7) ## Формализация задачи машинного обучения Начнем с формализации задачи машинного обучения. Предположим, у нас есть обучающая выборка **X** с метками **Y**, и нам нужно построить модель *f*, которая будет делать наиболее точные предсказания. Качество предсказаний измеряется с помощью **функции потерь** ℒ. Часто используются следующие функции потерь: * Для задачи регрессии, когда нужно предсказать число, можно использовать **абсолютную ошибку** ∑i|f(x(i))-y(i)| или **квадратичную ошибку** ∑i(f(x(i))-y(i))2. * Для классификации используется **0-1 потеря** (которая по сути эквивалентна **точности** модели) или **логистическая потеря**. Для однослойного перцептрона функция *f* определялась как линейная функция *f(x)=wx+b* (где *w* — это матрица весов, *x* — вектор входных признаков, а *b* — вектор смещений). Для различных архитектур нейронных сетей эта функция может принимать более сложную форму. > В случае классификации часто желательно получить вероятности соответствующих классов на выходе сети. Чтобы преобразовать произвольные числа в вероятности (например, нормализовать выходные данные), часто используется функция **softmax** σ, и функция *f* становится *f(x)=σ(wx+b)*. В определении *f* выше, *w* и *b* называются **параметрами** θ=⟨*w,b*⟩. Имея набор данных ⟨**X**,**Y**⟩, мы можем вычислить общую ошибку на всем наборе данных как функцию параметров θ. > ✅ **Цель обучения нейронной сети — минимизировать ошибку, изменяя параметры θ** ## Оптимизация методом градиентного спуска Существует известный метод оптимизации функций, называемый **градиентным спуском**. Идея заключается в том, что мы можем вычислить производную (в многомерном случае — **градиент**) функции потерь по параметрам и изменять параметры так, чтобы ошибка уменьшалась. Это можно формализовать следующим образом: * Инициализировать параметры случайными значениями w(0), b(0). * Повторять следующие шаги много раз: - w(i+1) = w(i)-η∂ℒ/∂w - b(i+1) = b(i)-η∂ℒ/∂b Во время обучения шаги оптимизации предполагается вычислять с учетом всего набора данных (помните, что функция потерь вычисляется как сумма по всем обучающим примерам). Однако на практике мы берем небольшие части набора данных, называемые **минибатчами**, и вычисляем градиенты на основе подмножества данных. Поскольку подмножество выбирается случайно каждый раз, такой метод называется **стохастическим градиентным спуском** (SGD). ## Многослойные перцептроны и обратное распространение ошибки Однослойная сеть, как мы видели выше, способна классифицировать линейно разделимые классы. Чтобы построить более сложную модель, мы можем объединить несколько слоев сети. Математически это означает, что функция *f* будет иметь более сложную форму и вычисляться в несколько шагов: * z1=w1x+b1 * z2=w2α(z1)+b2 * f = σ(z2) Здесь α — это **нелинейная функция активации**, σ — функция softmax, а параметры θ=<*w1,b1,w2,b2*>. Алгоритм градиентного спуска остается тем же, но вычисление градиентов становится сложнее. Используя правило дифференцирования сложной функции, мы можем вычислить производные следующим образом: * ∂ℒ/∂w2 = (∂ℒ/∂σ)(∂σ/∂z2)(∂z2/∂w2) * ∂ℒ/∂w1 = (∂ℒ/∂σ)(∂σ/∂z2)(∂z2/∂α)(∂α/∂z1)(∂z1/∂w1) > ✅ Правило дифференцирования сложной функции используется для вычисления производных функции потерь по параметрам. Обратите внимание, что левая часть всех этих выражений одинакова, и поэтому мы можем эффективно вычислять производные, начиная с функции потерь и двигаясь "назад" по вычислительному графу. Таким образом, метод обучения многослойного перцептрона называется **обратным распространением ошибки** (backpropagation), или просто 'backprop'. граф вычислений > TODO: ссылка на источник изображения > ✅ Мы рассмотрим обратное распространение ошибки гораздо подробнее в нашем примере с ноутбуком. ## Заключение В этом уроке мы создали собственную библиотеку для работы с нейронными сетями и использовали ее для простой задачи классификации в двумерном пространстве. ## 🚀 Задание В сопровождающем ноутбуке вы реализуете собственный фреймворк для построения и обучения многослойных перцептронов. Вы сможете подробно изучить, как работают современные нейронные сети. Перейдите к ноутбуку [OwnFramework](OwnFramework.ipynb) и выполните задания. ## [Вопросы после лекции](https://ff-quizzes.netlify.app/en/ai/quiz/8) ## Обзор и самостоятельное изучение Обратное распространение ошибки — это распространенный алгоритм в области ИИ и машинного обучения, который стоит изучить [подробнее](https://wikipedia.org/wiki/Backpropagation). ## [Задание](lab/README.md) В этой лабораторной работе вам предстоит использовать фреймворк, который вы создали в этом уроке, для решения задачи классификации рукописных цифр из набора данных MNIST. * [Инструкции](lab/README.md) * [Ноутбук](lab/MyFW_MNIST.ipynb) ---