Началось всё с того, что мне было нечем заняться, и я баловался с языковой моделью, мучая её всякими разными вопросами по ML. В какой-то момент дело дошло до функций активации — сначала прошлись по уже известным, а затем и до ещё непроверенных. Так и появилась LLA — функция активации, являющаяся центральным элементом всей этой истории.
Формула у неё довольно простая:
Да-да, всего лишь один натуральный логарифм, один модуль и два сложения. Отсюда и название — Log-Linear Activation. Но, тем не менее, мне показалось, что у этой функции есть большой потенциал. Поэтому бедному ИИ пришлось не только меня развлекать, но и писать мне код на Python, чтобы я проверил, действительно ли так хороша LLA. Однако я, как абсолютный хардкорщик, не имею никакого компьютера и запускать код могу только в Pydroid. И, понятное дело, платить за библиотеки я не собирался, поэтому языковая модель переписала мне код на чистом NumPy и встроенных модулях. Немного доработок и исправлений багов и вот, у меня на руках готовый инструмент для тестирования своей функции активации. Задачец сетей было аппроксимировать синусоиду.
Запустил, и знатно охренел. Моя функция училась, хотя и скакала, в то время как конкуренты (ReLU и сигмоида) практически не учились. Спустя несколько тестов с другими параметрами результат подтвердился — моя функция отлично себя чувствует на глубоких сетях, в то время как стандартные функции просто умирают. ИИ улучшил код: добавил предварительную остановку и замер времени, заодно заменив неудачных конкурентов на Swish. И снова полный разгром — swish вырубило из-за ранней остановки, ведь она совершенно не училась, в то время как LLA продолжала учиться и понизила лосс (MSE) до ~0.45. Провёл десятки разных тестов — и всё равно LLA каждый раз либо побеждала Swish, либо оставалась в ничьей. Было ясно одно: LLA прекрасно работает в любых условиях, в то время как все стандартные функции активации требуют особых условий.
Я уже подумывал о том, чтобы куда-то выложить результаты своих исследований. Решил перед этим проверить на какой-нибудь серьёзной задаче, и выбор пал на CIFAR-10. Решил переключиться на другого ИИ — говорят, он пишет код лучше, чем тот, которого я использовал изначально. Я показал ему формулы своей функции и её производной из прошлого кода.
Он же донёс до меня откровение: это неправильная производная. В коде стояла вот эта:
А правильная — вот эта:
Сказать, что я охренел — это ничего не сказать. Затем шок постепенно начал переходить в радость — потому что если уж функция с неправильной производной уничтожала всех конкурентов, то с правильной наверняка будет ещё лучше. Но оказалось, что всё вовсе наоборот — неправильная производная оказалась намного лучше и в аппроксимации синусоиды, и в классификации картинок, пусть и только на глубоких сетях. Стало понятно, почему — неправильная производная никогда не падает ниже единицы (всегда от 1 до 2). У неё просто нет проблемы затухающих градиентов как таковой, потому «бракованная» производная намного лучше правильной на глубоких сетях. Кроме того, ряд экспериментов подтвердил, что феноменальная устойчивость к бутылочным горлышкам — также заслуга неправильной производной.
Вот ссылка на репозиторий в GitHub: тык. Там код, при помощи которого я сравнивал Swish и LLA на CIFAR-10. Он имеет удобные настройки для ваших экспериментов. Надеюсь, там нет серьёзных багов 😀
ссылка на оригинал статьи https://habr.com/ru/articles/1048764/