Тема 8. Нейронные сети и глубокое обучение
В темах 4–7 мы рассмотрели «классические» алгоритмы машинного обучения: логистическую регрессию, деревья решений, ансамбли, методы кластеризации. Все они исходят из того, что признаки уже подготовлены человеком, а сам алгоритм лишь подбирает решающее правило в относительно компактном пространстве. На неструктурированных данных — изображениях, звуковых сигналах, длинных текстах — эта схема пробуксовывает: подбор хороших признаков вручную сам становится трудоёмкой инженерной задачей, а итоговая модель работает не лучше посредственного человеческого эксперта.
Нейронные сети предлагают другой подход: признаки извлекаются не отдельно, а совместно с решающим правилом — как часть одной оптимизируемой системы. Когда таких слоёв извлечения становится много, говорят о глубоком обучении (англ. deep learning). За последние пятнадцать лет именно глубокие сети сместили классические модели в задачах распознавания изображений, машинного перевода, синтеза речи и стали инженерной основой современных больших языковых моделей, упомянутых в теме 1.
Тема ставит три цели. Во-первых, разобрать, что такое искусственный нейрон и как из нейронов собирается многослойный перцептрон. Во-вторых, понять, как такая сеть обучается — что считается «ошибкой» и как её градиент проходит через слои. В-третьих, познакомиться с двумя ключевыми семействами архитектур — свёрточными и рекуррентными сетями, — а также с практическими приёмами, без которых глубокое обучение в реальных проектах не работает.
Основы нейронных сетей
Биологическая метафора и математическая модель
Историческая отправная точка — модель нейрона Маккаллока–Питтса (1943), которая упрощает биологический нейрон до бинарного логического элемента: входы умножаются на веса , суммируются и сравниваются с порогом ; выход равен единице, если сумма превзошла порог, и нулю иначе. В этой модели уже видны три ключевых компонента: взвешенная агрегация сигналов, нелинейное преобразование результата и обучаемые параметры — веса. Биологические оговорки — что реальный нейрон сложнее, что синаптические задержки переменны, что обработка частично аналоговая — для математического объекта вторичны; модель ценна именно как абстракция.
Следующий шаг сделал Фрэнк Розенблатт в 1958 году, предложив перцептрон (англ. perceptron) — нейрон Маккаллока–Питтса, веса которого подбираются по примерам, а не задаются вручную 1. Если объекты двух классов линейно разделимы в пространстве признаков, правило обновления весов гарантированно сходится к разделяющей гиперплоскости за конечное число шагов. Это была первая обучаемая модель распознавания образов, и в конце 1950-х она породила волну энтузиазма, сопоставимую с современным AI-хайпом.
Эту волну во многом обнулила книга Минского и Пейперта 1969 года 2: одиночный перцептрон неспособен реализовать функцию «исключающего или» (XOR), потому что её таблица истинности линейно неразделима. Авторы строго показали, что для таких функций требуется промежуточный слой нейронов, а методов их обучения тогда не существовало. Содержательно вывод был справедлив, но истолкован он был шире, чем заслуживал: финансирование коннекционистских исследований резко сократилось, наступила первая «зима ИИ», о которой мы говорили в теме 1. Из этой истории полезно вынести два урока: ограничение модели стоит понимать буквально, не распространяя на её естественные обобщения; и инструмент, у которого «нет алгоритма обучения», не равен «инструменту, у которого его никогда не будет».
Многослойный перцептрон
Снять ограничение перцептрона позволяет сложение нескольких слоёв нейронов. Многослойный перцептрон (англ. multilayer perceptron, MLP) состоит из входного слоя признаков, одного или нескольких скрытых слоёв и выходного слоя, дающего предсказание. Каждый слой реализует аффинное преобразование с последующей нелинейной активацией: где — вход, и — обучаемые параметры слоя, — поэлементная активация. Нелинейность принципиальна: композиция чисто линейных слоёв снова даёт линейную функцию, никаких новых возможностей не появляется. Именно нелинейная активация делает MLP универсальным аппроксиматором — теорема Цыбенко 1989 года утверждает, что MLP с одним скрытым слоем достаточной ширины способен приблизить любую непрерывную функцию на компакте с произвольной точностью. Это теоретический результат: на практике глубокие сети с многими узкими слоями оказываются эффективнее по числу параметров, чем «плоские» с одним широким, — и именно эта эмпирика стоит за термином «глубокое обучение».
Выбор функции активации влияет на свойства обучения сильнее, чем кажется. Исторически использовались сигмоида и гиперболический тангенс : обе гладкие, ограниченные, биологически правдоподобные. Однако обе насыщаются при больших по модулю аргументах — их производная стремится к нулю, и обучение глубоких сетей через них замирает. С 2010-х доминирует ReLU (англ. Rectified Linear Unit): . У ReLU кусочно-линейная форма, постоянная единичная производная при и нулевая при . Простота преобразования и неисчезающий градиент в положительной полуоси резко ускорили обучение глубоких архитектур; именно с переходом на ReLU связан прорыв AlexNet 2012 года, о котором мы вспоминали в теме 1.
Для выходного слоя выбор активации диктуется типом задачи. В бинарной классификации ставят сигмоиду — её выход интерпретируется как вероятность положительного класса. В многоклассовой — softmax: которая отображает вектор логитов в распределение вероятностей по классам. В регрессии выходной слой обычно линейный — без активации.
Вычисление предсказания по входу — прямое распространение (англ. forward pass) — сводится к последовательному применению для . Для одного объекта это последовательность матрично-векторных умножений; для батча — последовательность матрично-матричных, и именно на этой операции современные графические процессоры показывают свою силу.
Обучение нейронных сетей
Обучение сети формулируется как задача минимизации функции потерь по параметрам. В классификации стандартный выбор — кросс-энтропия (англ. cross-entropy): где — индикатор истинного класса, — предсказанная вероятность. Эта потеря выводится из принципа максимума правдоподобия для категориального распределения и устроена так, что чем увереннее ошибочное предсказание, тем сильнее штраф. В регрессии аналог — средняя квадратичная ошибка (MSE): . Конкретная функция потерь — не деталь реализации, а отражение модели шума: квадратичная соответствует гауссовскому шуму, кросс-энтропия — категориальному, и подмена их «удобным» вариантом меняет, какую именно модель мы оптимизируем.
Параметров в MLP — миллионы, перебирать их по сетке бессмысленно; ключ — градиентная оптимизация. Производная показывает, в каком направлении функция потерь растёт быстрее всего; шаг в противоположном направлении уменьшает ошибку. Алгоритм обратного распространения ошибки (англ. backpropagation), переоткрытый и систематизированный Румельхартом, Хинтоном и Уильямсом в 1986 году 3, даёт способ эффективно вычислить этот градиент через цепное правило.
Идея в следующем. Вычислим прямой проход и сохраним промежуточные активации . Тогда — производная по последнему слою — выражается через ошибку на выходе и активацию предпоследнего слоя. Производная по предпоследнему слою получается умножением выходного градиента на и производную активации; и так дальше — рекурсивно от последнего слоя к первому. Сложность одного шага градиента — порядка сложности прямого прохода, что и сделало обучение многослойных сетей вычислительно возможным.
Имея градиент, простейший оптимизатор — градиентный спуск (англ. gradient descent) — обновляет параметры по правилу , где — скорость обучения. На реальных датасетах вычислять полный градиент по всем объектам сразу слишком дорого, поэтому используется стохастический градиентный спуск (англ. stochastic gradient descent, SGD): на каждом шаге градиент оценивается по случайной подвыборке — мини-батчу (англ. mini-batch) фиксированного размера (обычно от 32 до 512 объектов). Один полный проход по всем обучающим данным — это эпоха (англ. epoch); типичное обучение длится десятки или сотни эпох.
Скорость обучения — один из самых чувствительных гиперпараметров. Слишком большая заставляет оптимизатор «прыгать» через минимум, обучение расходится. Слишком маленькая — даёт стабильную, но мучительно медленную сходимость. Стандартный приём — расписание скорости обучения: начать с относительно большой и уменьшать её по мере приближения к минимуму. В практической работе чаще всего применяется Adam 4 — адаптивный оптимизатор, который автоматически масштабирует шаг по каждой координате параметра на основании скользящих средних градиента и его квадрата. Adam менее чувствителен к выбору исходной скорости обучения и хорошо себя ведёт на разнородных задачах, поэтому именно он стал «опцией по умолчанию» для большинства новых архитектур; SGD с моментом сохраняет преимущество там, где важна тонкая настройка обобщения, — в частности, в свёрточных сетях для зрения.
Глубокое обучение
Свёрточные нейронные сети
MLP плохо приспособлен к изображениям. Картинка пикселей — это вектор из примерно 150 тысяч признаков; даже скромный скрытый слой из 1000 нейронов потребует более 150 миллионов весов на одной матрице. Хуже того, такая сеть не «знает», что соседние пиксели связаны больше, чем удалённые: для неё все 150 тысяч входов равноправны, и сдвиг изображения на один пиксель формально означает совершенно другой вектор.
Свёрточная нейронная сеть (англ. convolutional neural network, CNN) опирается на два структурных соображения. Во-первых, локальные паттерны — края, углы, текстуры — обнаруживаются в маленьких окрестностях пикселя; нет нужды связывать каждый нейрон со всем изображением. Во-вторых, искомый паттерн (скажем, вертикальная граница) ведёт себя одинаково в любом месте картинки — параметры детектора этого паттерна можно разделять между всеми позициями. Эти соображения формализуются в операции свёртки (англ. convolution): к изображению применяется небольшое (обычно или ) обучаемое ядро, скользящее по всем позициям и выдающее в каждой точке отклик; результат — карта признаков (англ. feature map).
Один свёрточный слой типично содержит десятки таких ядер, каждое из которых обучается реагировать на свой паттерн. После свёртки применяется поэлементная активация (обычно ReLU) и пулинг (англ. pooling) — операция понижения разрешения, чаще всего max-pooling: окно заменяется максимальным значением внутри него. Пулинг даёт частичную инвариантность к сдвигу и сокращает вычислительные затраты в следующих слоях. По мере углубления сети размер карт признаков уменьшается, а их число — растёт: сеть переходит от низкоуровневых паттернов (края, цвета) к высокоуровневым (части объектов, текстуры) и, наконец, к семантике класса. Последние слои обычно полносвязные, и заключительный слой даёт распределение по классам через softmax.
Первая практически успешная CNN — LeNet-5 Янна Лекуна 1998 года 5 — распознавала рукописные цифры на чеках американских банков; она содержала пять обучаемых слоёв и около 60 тысяч параметров. Дальнейшее развитие архитектуры — VGG, GoogLeNet, ResNet — связано в основном с увеличением глубины: от десятка слоёв в LeNet до сотен в ResNet-152. Обучение очень глубоких сетей долго упиралось в проблему деградации градиента; решение, предложенное в ResNet 6, — добавить «обходные» соединения, прибавляющие вход слоя к его выходу. Такая остаточная структура устраняет затухание градиента и позволила обучать сети глубиной более ста слоёв. Победа AlexNet 7 на ImageNet в 2012 году считается датой рождения современного глубокого обучения; именно после неё CNN стали индустриальным стандартом распознавания изображений и легли в основу систем компьютерного зрения от автономного вождения до медицинской диагностики.
Рекуррентные нейронные сети
Для последовательностей — текстов, звуковых сигналов, временных рядов — нужен принципиально иной механизм: модель должна не только смотреть на текущий вход, но и помнить, что было раньше. Рекуррентная нейронная сеть (англ. recurrent neural network, RNN) поддерживает скрытое состояние , которое обновляется на каждом шаге: Это уравнение можно «развернуть» по времени и увидеть структуру очень глубокой сети, в которой одни и те же веса повторяются на каждом шаге. Соответственно, к ней применим обычный backpropagation, только распространение градиента идёт не по слоям статической архитектуры, а по временным шагам — отсюда название обратное распространение по времени (англ. backpropagation through time, BPTT).
Эта же структура порождает фундаментальную проблему: при длинных последовательностях градиент, проходящий через десятки временных шагов, либо экспоненциально затухает (модель не учится зависеть от далёкого прошлого), либо экспоненциально растёт (обучение становится численно нестабильным). Это проблема исчезающих и взрывающихся градиентов, идентифицированная в 1991 году Зеппом Хохрайтером.
Принципиальное решение — архитектура LSTM (англ. Long Short-Term Memory), предложенная Хохрайтером и Шмидхубером в 1997 году 8. LSTM добавляет к скрытому состоянию отдельный «канал памяти» и три обучаемых затвора (англ. gates): забывания, входной и выходной. Затвор забывания решает, какую часть прошлой памяти стереть; входной — какую новую информацию записать; выходной — что выдать наружу. Структура с аддитивным обновлением памяти и сигмоидными затворами устроена так, что градиент по каналу может распространяться через многие временные шаги почти без затухания. Более компактный вариант с двумя затворами вместо трёх — GRU (англ. Gated Recurrent Unit) — предложен Чо и соавторами в 2014 году 9; в большинстве практических задач он показывает сопоставимое с LSTM качество при меньшем числе параметров.
RNN и LSTM применялись в машинном переводе, синтезе и распознавании речи, анализе временных рядов в финансах и промышленности. В обработке естественного языка они доминировали примерно до 2017 года, когда были вытеснены архитектурой трансформер (англ. transformer), упомянутой в теме 1. Трансформеры избавились от последовательной зависимости вычислений по времени, заменив рекурренцию механизмом внимания, и оказались гораздо лучше распараллеливаемы на современных GPU. На длинных последовательностях с временной структурой LSTM и GRU всё ещё остаются разумным выбором, особенно когда объём данных умеренный, а задержки критичны; но во flagship-моделях обработки языка их время прошло.
Практические аспекты
Борьба с переобучением в нейронных сетях
Глубокие сети с миллионами параметров — это семейства с почти неограниченной выразительной силой. Без специальных мер они быстро запоминают обучающие данные, включая шум и случайные особенности; проблема переобучения, обсуждавшаяся в теме 7 в контексте классических моделей, в глубоком обучении проявляется острее и принимает специфические формы.
Dropout 10 — простой и неожиданно эффективный приём, который в 2014 году стал стандартом. На каждом шаге обучения часть нейронов скрытых слоёв (обычно 20–50%) случайно «выключается» — их выход обнуляется. Сеть вынуждена обучать представления, в которых ни один отдельный нейрон не критичен; формально dropout эквивалентен обучению ансамбля экспоненциально большого числа подсетей, разделяющих параметры. На стадии предсказания dropout отключается, и используются все нейроны. Этот метод снижает переобучение, не увеличивая вычислительных затрат на обучение и не требуя ручной настройки сложности модели.
Batch Normalization 11 решает другую задачу — стабилизацию обучения. После каждого слоя авторы предлагают нормировать активации по статистикам мини-батча: вычесть среднее, разделить на стандартное отклонение, а затем применить обучаемые сдвиг и масштаб. Это сглаживает поверхность функции потерь, позволяет использовать большие скорости обучения и сильно сокращает время сходимости. Побочный эффект — лёгкая регуляризация: статистики батча содержат случайную компоненту, и каждый раз активации возмущаются по-разному. В современных архитектурах batch normalization (и его варианты — layer norm, group norm) практически обязательны.
Ранняя остановка — простейший приём из всех трёх. В процессе обучения регулярно (например, после каждой эпохи) измеряется метрика на валидационной выборке. Если она не улучшалась последние эпох, обучение прекращается и сохраняются веса, дававшие лучшее значение. По сути, ранняя остановка превращает число эпох обучения в гиперпараметр, подбираемый по валидации, — что напрямую отражает компромисс смещения и разброса, обсуждавшийся в теме 3: больше эпох сокращают смещение, но увеличивают разброс. Сочетание dropout, batch norm и ранней остановки покрывает большинство практических случаев; в специфических задачах добавляются weight decay (L2-регуляризация весов), аугментация данных и более сложные стратегии расписаний скорости обучения.
Фреймворки глубокого обучения
Реализовать прямой проход, backpropagation, оптимизатор и нужные слои с нуля — упражнение полезное, но в реальной работе это делается с помощью специализированных фреймворков. Их история — это история удачных архитектурных решений: ранний Theano задал идею автоматического дифференцирования вычислительного графа; TensorFlow от Google популяризовал статические графы и индустриальное развёртывание; PyTorch предложил динамические графы и удобный отладочный опыт, чем выиграл основную долю исследовательских проектов. Современная картина — PyTorch доминирует в исследованиях, TensorFlow удерживает позиции в продакшен-инфраструктуре, JAX занимает нишу высокопроизводительных научных вычислений.
В учебных целях нас будет интересовать Keras — высокоуровневый API, исходно созданный как обёртка над несколькими бэкендами, а с 2019 года официально интегрированный в TensorFlow в качестве основного интерфейса. Keras сокращает дистанцию между описанием архитектуры и работающей моделью: типичный «Hello, MLP» занимает десяток строк кода. Базовые абстракции три: модель (последовательность или граф слоёв), слой (Dense, Conv2D, LSTM, Dropout, BatchNormalization и так далее), и связка компиляция/обучение — на компиляции задаются оптимизатор, функция потерь и метрики, на обучении вызывается model.fit(...) с обучающими данными и числом эпох.
Достоинство такого API — низкий порог входа и единообразие интерфейса для разных типов сетей: переход от MLP к CNN или RNN сводится к замене типов слоёв. Ограничение — некоторые специфические архитектуры с нестандартными петлями обратной связи или динамическим графом удобнее писать на низкоуровневом PyTorch. В лабораторной работе мы воспользуемся Keras для обучения сети на классическом датасете MNIST: будем менять количество слоёв, функции активации, регуляризацию и оптимизаторы, чтобы пронаблюдать, как описанные в этой теме элементы влияют на кривые обучения и итоговое качество.
Систематическое изложение глубокого обучения как дисциплины собрано в монографии Гудфеллоу, Бенжио и Курвилль 12 — это основной учебник по теме, дополняющий классический Бишоп 13 на стороне нейронных сетей. Курс ориентируется на эти источники как на расширенное чтение.
Литература
- Rosenblatt F. The Perceptron: A Probabilistic Model for Information Storage and Organization in the Brain. — Psychological Review, 1958, С. 386–408, DOI: 10.1037/h0042519.
- Minsky M., Papert S. Perceptrons: An Introduction to Computational Geometry. — MIT Press, 1969.
- Rumelhart D. E., Hinton G. E., Williams R. J. Learning Representations by Back-Propagating Errors. — Nature, 1986, С. 533–536, DOI: 10.1038/323533a0.
- Kingma D. P., Ba J. Adam: A Method for Stochastic Optimization. — Proceedings of the 3rd International Conference on Learning Representations (ICLR), 2015, https://arxiv.org/abs/1412.6980.
- LeCun Y., Bottou L., Bengio Y., Haffner P. Gradient-Based Learning Applied to Document Recognition. — Proceedings of the IEEE, 1998, С. 2278–2324, DOI: 10.1109/5.726791.
- He K., Zhang X., Ren S., Sun J. Deep Residual Learning for Image Recognition. — Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2016, С. 770–778, DOI: 10.1109/CVPR.2016.90.
- Krizhevsky A., Sutskever I., Hinton G. E. ImageNet Classification with Deep Convolutional Neural Networks. — Advances in Neural Information Processing Systems (NeurIPS), 2012, С. 1097–1105, https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.
- Hochreiter S., Schmidhuber J. Long Short-Term Memory. — Neural Computation, 1997, С. 1735–1780, DOI: 10.1162/neco.1997.9.8.1735.
- Cho K., van Merriënboer B., Gulcehre C., Bahdanau D., Bougares F., Schwenk H., Bengio Y. Learning Phrase Representations Using RNN Encoder–Decoder for Statistical Machine Translation. — Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing (EMNLP), 2014, С. 1724–1734, DOI: 10.3115/v1/D14-1179.
- Srivastava N., Hinton G., Krizhevsky A., Sutskever I., Salakhutdinov R. Dropout: A Simple Way to Prevent Neural Networks from Overfitting. — Journal of Machine Learning Research, 2014, С. 1929–1958, https://jmlr.org/papers/v15/srivastava14a.html.
- Ioffe S., Szegedy C. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. — Proceedings of the 32nd International Conference on Machine Learning (ICML), 2015, С. 448–456, https://proceedings.mlr.press/v37/ioffe15.html.
- Goodfellow I., Bengio Y., Courville A. Deep Learning. — MIT Press, 2016, https://www.deeplearningbook.org/.
- Bishop C. M. Pattern Recognition and Machine Learning. — Springer, 2006.