Читать книгу Гений кода. Истории самых впечатляющих ИИ-проектов, которые уже меняют жизнь - Ар'лан ис'Дрекхэм - Страница 12
Часть 2: Рождение титанов. Истории прорывов, изменивших правила игры
Глава 11. ResNet: Почему «остаточные связи» позволили строить сети толщиной в сотни слоев
ОглавлениеКрючок: Парадокс строителя
Представь, что ты строишь небоскрёб. Ты начинаешь с 10 этажей. Здание стоит крепко. Ты добавляешь ещё 10 – всё хорошо. Ещё 10 – стоит.
Но вдруг, когда ты доходишь до 50 этажей, происходит странное: нижние этажи начинают проседать. Бетон трескается. Здание становится менее устойчивым, чем 40-этажное. Хотя по логике, чем выше здание, тем оно прочнее (если строить правильно), но здесь что-то идёт не так.
Примерно такая же проблема встала перед исследователями нейросетей в 2015 году. Казалось бы, чем больше слоёв в нейросети, тем умнее она должна быть. Ведь больше параметров, больше возможностей для абстракций.
Но практика показывала обратное: сети глубиной более 20—30 слоёв начинали учиться хуже, чем их мелкие собратья. Ошибка на обучении не уменьшалась, а росла. Это было проклятие, которое грозило остановить прогресс.
Герои: Команда из Пекина, которая победила всех
В 2015 году группа исследователей из Microsoft Research Asia (пекинский офис) под руководством Каймина Хэ (Kaiming He) работала над этой проблемой.
Каймин Хэ – фигура легендарная. Позже он уйдёт в Фейс и станет одним из главных людей в мире компьютерного зрения. Но тогда это был просто талантливый учёный, который бился над проклятием глубины.
Команда (Сяньюй Чжан, Шаоцин Жэнь, Цзянь Сунь) задала себе простой вопрос: «Почему глубокие сети работают хуже? Ведь они могут аппроксимировать мелкие, просто обнуляя лишние слои?»
Теоретически, если у тебя есть сеть в 50 слоёв, ты можешь сделать первые 20 слоёв такими же, как в 20-слойной сети, а остальные 30 превратить в тождественное преобразование (то есть они просто передают сигнал дальше, не меняя его). Тогда 50-слойная сеть должна работать не хуже 20-слойной.
Но на практике оптимизация (градиентный спуск) не могла найти такое решение. Сети «забывали», как обнулять лишние слои, и начинали портить уже выученное.
Конфликт: Проклятие градиента
Чтобы понять проблему, нужно вспомнить, как учатся нейросети.
Ошибка (разница между ответом сети и правильным ответом) передаётся от последнего слоя к первому. Это называется обратное распространение ошибки. Градиент (сигнал ошибки) проходит через каждый слой и подсказывает, как менять веса.
Но когда сеть очень глубокая, градиент, проходя через десятки слоёв, начинает вести себя плохо. Он либо затухает (становится почти нулевым – vanishing gradient), либо взрывается (становится бесконечно большим – exploding gradient).
В результате первые слои (которые отвечают за базовые признаки – края, углы, линии) либо вообще не учатся (градиент умер), либо сходят с ума.
Сети просто не могли доставить сигнал ошибки от выхода до входа, не потеряв его по дороге. Это был тупик.
Развязка: Шорткат (Обходной путь)
Решение, которое предложила команда Каймина Хэ, было гениальным в своей простоте. Они придумали Residual Block (Остаточный блок).
Обычный слой нейросети пытается выучить нужное преобразование напрямую. Например: Выход = Функция (Вход).
В Residual Block они изменили формулу. Теперь слой учится не самому выходу, а разнице (остатку) между входом и выходом.
Выход = Вход + Остаток (Вход)
Что это значит на практике?
В блок добавляется прямое соединение (shortcut connection), которое перескакивает через один или несколько слоёв и просто прибавляет исходный вход к результату работы слоя.
Как это работает:
– Есть вход X.
– Он проходит через несколько слоёв, которые вычисляют некое изменение F (X).
– Потом мы берём исходный X и прибавляем к нему это изменение: Выход = F (X) + X.
Зачем это нужно?
Теперь у градиента есть обходной путь. Когда ошибка идёт обратно, она может пройти не через сложные слои, а напрямую по этому «шорткату». Это решает проблему затухания градиента.
Кроме того, сети становится легче учиться. Если дополнительные слои не нужны, сеть может просто сделать F (X) = 0, и тогда Выход = X (тождественное преобразование). Градиентный спуск легко находит такое решение, потому что обнулить изменение проще, чем выучить сложную функцию.
Инсайт: Почему это гениально
Гениальность ResNet в том, что она переопределила задачу обучения.
Вместо того чтобы заставлять каждый новый слой выучивать сложную функцию с нуля, ResNet говорит: «Ты уже знаешь, что у тебя есть. Просто добавь немного улучшений».
Это как если бы ты учился играть на гитаре. Вместо того чтобы каждый раз учить новую песню с нуля, ты берёшь уже известный аккорд и просто добавляешь к нему пару новых нот. Намного проще, правда?
Триумф: Победа на ImageNet 2015
В 2015 году команда Microsoft Research выставила ResNet на тот же конкурс ImageNet, где в 2012 году победила AlexNet.
Результаты были ошеломляющими.
ResNet выиграла с результатом, который считался невозможным. Ошибка распознавания упала до 3,57%. Это лучше, чем у человека (средний человек ошибается примерно в 5% случаев).
Но главное было не в цифрах. Главное было в глубине. ResNet-152 (152 слоя) работала стабильно и показывала лучшие результаты, чем любые мелкие сети. Проклятие глубины было снято.
После этой победы архитектура ResNet стала стандартом де-факто для всего компьютерного зрения. Сегодня, если ты видишь какую-то сложную нейросеть для распознавания, она почти наверняка использует residual connections.
Эволюция: От 152 слоёв до бесконечности
После ResNet началась гонка глубины.
– ResNet-152 – 152 слоя.
– ResNet-1001 – 1001 слой (экспериментально показали, что можно обучать и такие глубины, хотя практической пользы было мало).
– DenseNet – пошли ещё дальше: там каждый слой соединяется со всеми предыдущими напрямую.
– ResNeXt, Wide ResNet – варианты, которые оптимизировали ширину и архитектуру блоков.
Главное было доказано: глубина работает, если правильно организовать обходные пути.
Наследие: ResNet в каждом телефоне
Сегодня ResNet живёт везде.
– Распознавание лиц в телефоне. Когда твой iPhone разблокируется по лицу, внутри работает сеть, основанная на residual-блоках.
– Медицина. Анализ снимков МРТ и КТ – везде ResNet или её наследники.
– Беспилотные автомобили. Распознавание пешеходов, знаков, дорожной разметки – всё это требует глубины, которую дала ResNet.
– Сателлиты. Анализ снимков Земли из космоса.
– Любая задача компьютерного зрения. Если ты видишь современную нейросеть для картинок, в ней почти наверняка есть residual connections.
Твой ход: Четыре урока от ResNet
– Ищи обходные пути. Если задача кажется нерешаемой из-за сложности, попробуй найти «шорткат». Не пытайся выучить всё с нуля – используй то, что уже знаешь, и добавляй небольшие улучшения.
– Учись прибавлять, а не заменять. Иногда проще научиться дополнять существующее, чем создавать новое с нуля. Это работает и в коде, и в жизни.
– Проблема может быть в доставке сигнала. Если ты не видишь прогресса, проверь, доходит ли «сигнал» (обратная связь, информация, мотивация) до первых слоёв твоей системы. Может быть, он затухает по пути.
– Не бойся глубины. Глубокие системы работают, если правильно организовать связи. Строить небоскрёбы можно – главное, не забывать про лифты и лестницы.
P.S.
Знаешь, что сказал Каймин Хэ, когда его спросили, как они додумались до residual connections?
«Мы просто долго смотрели на проблему и думали: „Что самое простое решение, которое может сработать?“ Идея была настолько очевидной, что мы удивлялись, почему никто не сделал этого раньше».
Именно так работают гениальные идеи – они кажутся очевидными после того, как их объяснили.