Что такое «паралич» сети, и как его избежать?

Паралич сети — это явление, когда глубокие слои не обучаются. Это происходит из-за затухания градиента при обратном распространении ошибки. Затухание градиента может возникнуть из-за большой глубины сети или больших выходных значений.

Почему большая глубина сети приводит к затуханию градиента?

Для разъяснения приведем пример, где пять полносвязных слоёв соединены сигмоидой.

Несколько слоев, связанные сигмоидой

Несколько слоев, связанные сигмоидой

У выбранной функции активации производная не превышает ¼, значит градиент каждый раз, проходя через нее, будет умножаться на число не большее ¼. Если в сети 5 функций активаций, то к самому глубокому слою градиент будет умножен на (¼)^5, что равно 1/1024. Было бы в сети 10 слоев, градиент уменьшился бы в миллионы раз.

Почему большие выходные значения приводят к затуханию градиента?

Попробуем взять другую функцию активации, у которой производная достигает единицы, например, гиперболический тангенс. В этом случае, как и в предыдущем, у функции есть плато, на котором значение почти не меняется. Если выходные значения слоя будут достаточно большими, градиент будет умножаться на очень маленькие значения, потому что производная в точках, удаленных от центра оси, почти нулевая.

Производная гиперболического тангенса, красным отмечено плато функции

Производная гиперболического тангенса, красным отмечено плато функции

Как избежать паралича сети?

Сменить функцию активации

Можно попробовать сменить функцию активации на ReLU. У нее в положительной части оси производная всегда равна единице. Казалось бы, что градиент будет проходить по сети без потерь, но в части случаев он не будет походить дальше. Если выходы слоя центрированы, то в половине случаев значения градиента не пройдут дальше и станут равными нулю. Теперь градиенту пройти через пять слоев уже проще, но проблема с затуханием осталась.

Leaky ReLU и ELU немного помогают ситуации, но глобально ее не меняют.

Нормализовать данные

Например, можно использовать batch normalization. В этом случае выходные значения будут реже выходить на плато функции активации. Это позволит реже умножать градиент на нулевые значения.

Модифицировать архитектуру сети

В GoogLeNet использовали дополнительные функции потерь у глубоких слоев, тем самым обучая их той же самой задаче. Это подпитывало обновление весов на глубоких слоях сети. В нашей статье важны части в красных эллипсах на изображении, через них и проходят дополнительные функции потерь.

GoogLe Net

GoogLe Net

В ResNet использовались Residual блоки. В этих блоках к результату работы слоев добавляют входные данные. Таким образом, градиент не затухает и приводит к обновлению весов слоя на любой глубине.

Residual block

Residual block

В LSTM выходные значения складываются с новыми данными, чтобы избежать затухания градиента на старых данных. В Vanilla RNN использовалась функция активации при переходе от старого состояния к новому, из-за чего обратное распространение ошибки затухало.

Заключение

Паралич сети или затухание градиента — очень сложная проблема, решение которой может привести к необычным архитектурным решениям.

© Habrahabr.ru