Я удалил backpropagation из нейросети. Она обучилась методами XIX века |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
МЕНЮ Главная страница Поиск Регистрация на сайте Помощь проекту Архив новостей ТЕМЫ Новости ИИ Голосовой помощник Разработка ИИГородские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Искусственный интеллект Слежка за людьми Угроза ИИ Атаки на ИИ Внедрение ИИИИ теория Компьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Нейронные сети начинающим Психология ИИ Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Промпты. Генеративные запросы Распознавание лиц Распознавание образов Распознавание речи Творчество ИИ Техническое зрение Чат-боты Авторизация |
2026-04-23 14:39 Все началось с того, что я открыл PyTorch и удалил из модели .backward(). Взял и стер как строчку, которая «вроде ничего не делала». Только вот эта строчка делала вообще все. Я хотел понять одну вещь: а что, если забыть, что backpropagation существует? Не как упражнение, чтобы вспомнить основы, а буквально обучить нейросеть, ни разу не посчитав градиент. То есть без всего того математического аппарата, который мы с вами воспринимаем как воздух. И у меня получилось. Правда попутно я обнаружил, что Adam — это, по сути, уравнение движения с трением, записанное на Python. (Лагранж бы такое одобрил, наверное). Шаг нулевой: случайный «тык» вместо градиента Идея максимально примитивная. Берем нейросеть, берем текущий loss, берем случайное возмущение параметров — маленький шум, гауссов, с какой-нибудь сигмой 0,001. Если loss уменьшился — оставляем, а если увеличился — откатываем. И все, это старый-добрый (и ленивый) «random search», он же метод проб и ошибок, он же то, как я в детстве настраивал антенну телевизора. Подождал и на выходе получил вот такие результаты: ![]() Что мы видим? Оно медленно, да, не без мучений, но учится (loss действительно падает). И это без единого вызова .backward(). На XOR — четыре точки, ~50 параметров — 50 000 шагов для loss ~0,09. Обычный SGD решает это за 300 шагов — разница в два порядка. Но разница количественная, а не качественная. А ведь именно так и работал мир до 1986 года — до статьи Румельхарта, Хинтона и Уильямса. Случайный поиск, генетические алгоритмы и любимый многими школьниками (мной в школьные времена, в том числе) перебор. Почему случайный поиск — это больно Тут я хочу остановиться и понять, почему он такой медленный. Есть хорошая аналогия: представьте, что вы в темной комнате. Нужно найти яму в полу — самую низкую точку пола. Случайный поиск: вы хаотично прыгаете в случайные стороны и запоминаете, где пол был ниже. Работает? Вполне. Но по эффективности это как стирать носки в посудомоечной машине — технически возможно. Еще есть проблема в размерности. У нашей игрушечной сети ~50 параметров. Случайный вектор в 50-мерном пространстве с огромной вероятностью будет почти перпендикулярен направлению спуска. Это математика: в высоких размерностях случайные векторы почти ортогональны друг другу. Поэтому каждый шаг — крохотная проекция на правильное направление. К примеру, у GPT-2 параметров 124 млн. Случайный поиск в таком пространстве схлопнется раньше, чем найдет хоть что-то полезное. Нужна направленность, и многие уже догадались — нужна информация о рельефе. Шаг первый: метод конечных разностей Backpropagation мы все еще не берем, но мы можем поступить хитрее — вместо случайного тычка прощупать каждый параметр по отдельности. Двигаем один вес на эпсилон. Смотрим, как изменился loss. Делим изменение на эпсилон. Получаем приближенный градиент. Школьная формула производной, восьмой класс. 2 000 шагов — и loss практически ноль. Без backpropagation. Чистая числовая производная, как в XVIII веке. Но (всегда есть «но») для каждого шага мы делаем N+1 прямых проходов, где N — число параметров. У нас ~50 параметров — терпимо. У ResNet-50 с 25 млн параметров — 25 млн forward pass на один шаг оптимизации. Backpropagation делает это за два прохода — прямой и обратный. Вот за это Румельхарта и цитируют чаще в ИИ-сегменте, чем Эйлера (хотя Эйлеру грех жаловаться на отсутствие признания). Итого: направление мы нашли, но цена — безумная. Backpropagation берет ту же производную за O(N) вместо O(N?). ![]() NVIDIA L4 в облаке Selectel от 22,61 ?/час Для запуска современных языковых и мультимодальных моделей. Шаг второй: когда у весов появляется масса Вот тут мы, наконец, перешли к той части, ради которой я и решил написать об этом статью. Мы уже умеем считать «силу», действующую на каждый вес — это и есть градиент (с точностью до знака). Градиент — направление наискорейшего роста loss, а мы идем в противоположную сторону. А что если вес — не абстрактная точка на графике, а физический объект? С массой, со скоростью, с инерцией. Ньютон, второй закон: F = ma. Роль силы здесь играет отрицательный градиент. Он дает ускорение, ускорение меняет скорость, а скорость меняет положение — сам вес. Заметно быстрее. Потому что скорость накапливается: если градиент несколько шагов подряд тянет в одну сторону, вес разгоняется. Как шарик, катящийся с горки, набирает инерцию и проскакивает мелкие ямки. А трение (friction = 0,95) не дает разогнаться бесконечно. Без него система улетает в бесконечность, как спутник без гравитации. Я проверял — loss становится NaN примерно на 200-м шаге, печальное зрелище. Шаг третий: параллель, которая не случайна Давайте выпишем уравнения рядом. Слева — физика, справа — ML.
Заметили?
SGD с моментом — дословно уравнение движения шарика по ландшафту loss-функции с вязким трением. Буквально одно и то же уравнение, но записанное разными буквами. Борис Поляк опубликовал этот метод в 1964 году. Назвал его «метод тяжелого шарика». Больше 60 лет прошло, а мы все еще обучаем сети методом тяжелого шарика просто стесняемся называть вещи своими именами. Шаг четвертый: Adam Adam — самый популярный оптимизатор в глубоком обучении. Если не считать AdamW, который просто Adam с правильным weight decay. И с ним все еще веселее. А теперь физическая интерпретация. m[t] — скорость (momentum). Экспоненциальное скользящее среднее градиента. Тот самый шарик с инерцией: ?1 = 0,9 означает, что шарик «помнит» 90% своей предыдущей скорости и учитывает 10% новой силы. v[t] — а вот это уже интереснее. Это оценка дисперсии градиента. Физически — представьте, что у поверхности есть «шероховатость». Если градиент скачет (высокая дисперсия) — значит, поверхность рыхлая, и шарик должен двигаться осторожнее. Деление на ?v[t] — адаптивное трение: больше «тряски» — больше демпфирование. ![]() — буфер, чтобы не делить на ноль. Физически — минимальный коэффициент трения. Даже на идеально гладкой поверхности что-то да тормозит. Если записать все это на языке физики: Bias correction (1 - ?^t) — это «прогрев». Физическая аналогия: в начале движения шарик еще не набрал репрезентативную статистику о поверхности. Коррекция компенсирует начальное смещение к нулю. По сути, это как термометр, которому нужно время, чтобы показать реальную температуру. Полная картина: ландшафт loss-функции — это потенциальное поле Вот к чему все это ведет. Loss-функция L(?) — потенциальная энергия системы. Градиент ?L — сила (с точностью до знака). Веса ? — координаты частицы. Оптимизатор — уравнение движения. И тогда все, что делается в ML-оптимизации — частные случаи механики:
Когда копался в этой теме, мне польстило, что это не натянутая аналогия, которые я так люблю, возможно, в силу любви к советской фантастике. В 2017 году Мандт, Хоффман и Блей формально доказали в статье «Stochastic Gradient Descent as Approximate Bayesian Inference», что SGD с маленьким learning rate ведет себя как ланжевеновская динамика — броуновское движение частицы в потенциальном поле. Собственно, это и есть стохастическая механика XIX века. Собираем все: обучение нейросети как физическая симуляция Берем чуть более серьезную задачу — spiral dataset, два класса, закрученных спиралью. И обучаем сеть тремя способами: После 1 000 шагов:
![]() Фзика работает. Медленнее, чем backpropagation, потому что конечные разности — дорого, но неплохо по качеству. А случайный поиск застрял — слишком много параметров, слишком мало информации о рельефе. Зачем все это знать Ну серьезно, зачем? Я же не предлагаю выбросить backpropagation. Это было бы как предлагать отказаться от колеса, потому что «ноги — тоже вариант». Backprop работает, но понимание физической природы оптимизации дает кое-что ценное. Первое, интуицию для гиперпараметров. Learning rate — это шаг по времени, а не рандомное число:
Поменяйте на 0,99 и он станет тяжелее, будет дольше разгоняться и дольше тормозить. Это уже не подбор чисел наугад, а физическая интуиция, хотя, не вдаваясь в детали, это тоже кажется своего рода угадыванием. Второе — понимание расписаний learning rate. Cosine annealing здесь работает как медленное охлаждение, Warmup — как плавный разгон, а Warm restarts — это способ встряхнуть систему, чтобы вылезти из локального минимума (аналог в физике — метод имитации отжига). Третье, объяснение, почему большие батчи хуже обобщают. Маленький батч создает сильный стохастический шум. Это как броуновское движение: случайные толчки помогают шарику перепрыгнуть через невысокие барьеры и найти широкий минимум (который обычно лучше обобщает). Большой батч — это детерминированная сила, шарик катится в ближайшую яму и сидит там. Вместо итогов Я потратил пару выходных на то, чтобы обучить нейросеть методами Ньютона и Эйлера. Не самый продуктивный уикэнд, скажу честно. Зато теперь, когда я пишу optimizer = Adam(lr=3e-4), я вижу знакомое уравнение движения шарика по холмистому ландшафту. lr=3e-4 — шаг по времени. betas=(0.9, 0.999) — инерция и адаптивное трение. weight_decay=0.01 — пружина, не дающая шарику уехать слишком далеко от центра. Физика XVII–XVIII веков, замаскированная под API XXI века. Мне интересно, есть ли у вас похожие приземленные объяснения для других абстрактных вещей в ML? Например, как вы объясняете себе внимание в трансформерах или работу нормализации? Делитесь своим мнением в комментариях. Телеграм: t.me/ainewsline Источник: habr.com Комментарии: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||