Обсуждение участника:Mishenkoil — различия между версиями
(правки x3) |
(код) |
||
Строка 34: | Строка 34: | ||
Этот способ инициализации хорошо подойдет для симметричных относительно нуля функций активации (гиперболический тангенс, сигмоид), для ReLU<ref>[https://en.wikipedia.org/wiki/Rectifier_(neural_networks) ReLU, Wikipedia]</ref> данный способ не подходит. | Этот способ инициализации хорошо подойдет для симметричных относительно нуля функций активации (гиперболический тангенс, сигмоид), для ReLU<ref>[https://en.wikipedia.org/wiki/Rectifier_(neural_networks) ReLU, Wikipedia]</ref> данный способ не подходит. | ||
− | ===Метод инициализации He<ref>[https:// | + | ====Пример на языке Python с библиотекой NumPy==== |
+ | |||
+ | <font color=darkgreen># example of the normalized xavier weight initialization</font> | ||
+ | from math import sqrt | ||
+ | from numpy import mean | ||
+ | from numpy.random import rand | ||
+ | <font color=darkgreen># number of nodes in the previous layer</font> | ||
+ | n = 10 | ||
+ | <font color=darkgreen># number of nodes in the next layer</font> | ||
+ | m = 20 | ||
+ | <font color=darkgreen># calculate the range for the weights</font> | ||
+ | lower, upper = -(sqrt(6.0) / sqrt(n + m)), (sqrt(6.0) / sqrt(n + m)) | ||
+ | <font color=darkgreen># generate random numbers</font> | ||
+ | numbers = rand(1000) | ||
+ | <font color=darkgreen># scale to the desired range</font> | ||
+ | scaled = lower + numbers * (upper - lower) | ||
+ | |||
+ | ===Метод инициализации He<ref>[https://arxiv.org/pdf/1502.01852.pdf Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification ]</ref>=== | ||
Поскольку ReLU несимметричная функция $f(x) = max(0, x)$, мы уже не можем утверждать, что среднее значение входных данных в каждом преобразовании будет нулевым: | Поскольку ReLU несимметричная функция $f(x) = max(0, x)$, мы уже не можем утверждать, что среднее значение входных данных в каждом преобразовании будет нулевым: | ||
Строка 49: | Строка 66: | ||
Для нормального распределения $\mathcal N$ это будет: | Для нормального распределения $\mathcal N$ это будет: | ||
*<tex>w_i \sim \mathcal N(0,\frac{2}{n_{in}})</tex> | *<tex>w_i \sim \mathcal N(0,\frac{2}{n_{in}})</tex> | ||
+ | |||
+ | ====Пример на языке Python с библиотекой NumPy==== | ||
+ | |||
+ | <font color=darkgreen># example of the he weight initialization</font> | ||
+ | from math import sqrt | ||
+ | from numpy.random import randn | ||
+ | <font color=darkgreen># number of nodes in the previous layer</font> | ||
+ | n = 10 | ||
+ | <font color=darkgreen># calculate the range for the weights</font> | ||
+ | std = sqrt(2.0 / n) | ||
+ | <font color=darkgreen># generate random numbers</font> | ||
+ | numbers = randn(1000) | ||
+ | <font color=darkgreen># scale to the desired range</font> | ||
+ | scaled = numbers * std | ||
+ | |||
==См.также== | ==См.также== |
Версия 19:15, 9 мая 2022
Инициализация — это процесс установки настраиваемых параметров для нашей глубокой сети. Выбор правильного метода инициализации важен для качества обучения нашей модели. Также это позволяет сократить время сходимости и минимизировать функцию потерь. Поэтому важно уметь выбрать правильный метод инициализации.
Содержание
Наивная инициализация
Если задать все параметры нулевыми или константными значениями, это приведёт к тому, что наша сеть либо совсем не обучится, либо абсолютно все нейроны будут вести себя одинаково — совсем не то, что мы хотим получить. Глубокая сеть должна обучаться разным признакам.
Инициализация случайными числами
Рассмотрим линейное преобразование:
Его дисперсия (считаем настраиваемые параметры и входные данные независимыми):
Если отнормировать входные данные и подобрать параметры, чтобы среднее было нулевым, получится:
Поскольку $x_i$ мы отнормировали, а $w_i$ из одного распределения, то все дисперсии одинаковые:
Отсюда видно, что дисперсия результата линейно зависит от дисперсии входных данных с коэффициентом $n_{in} \mathrm{Var}[w_i]$.
Если коэффициент будет $>1$ это приведет к увеличению дисперсии с каждым новым преобразованием, что может привести к ошибкам или насыщению функции активации, что негативно скажется на обучении сети.
Если коэффициент будет $<1$ это приведет к снижению дисперсии с каждым новым преобразованием с около нулевым промежуточным представлением, что тоже негативно скажется на обучении сети.
Поэтому для начальной инициализации параметров стоит использовать такое распределение, что $\mathrm{Var}[w_i]=\frac{1}{n_{in}}$, которое позволит сохранить дисперсию входных данных.
Метод инициализации Xavier[1].
Предыдущий подход хорошо работает, когда размерность наших данных не изменяется после преобразований $(n_{in} = n_{out})$, но так бывает не всегда. В качестве компромисса Xavier Glorot и Yoshua Bengio предлагают инициализировать параметры из распределения с дисперсией $\mathrm{Var}[w_i]=\frac{2}{n_{in}+n_{out}}$.
Для равномерного распределения $\mathcal U$ это будет:
Для нормального распределения $\mathcal N$ это будет:
Этот способ инициализации хорошо подойдет для симметричных относительно нуля функций активации (гиперболический тангенс, сигмоид), для ReLU[2] данный способ не подходит.
Пример на языке Python с библиотекой NumPy
# example of the normalized xavier weight initialization from math import sqrt from numpy import mean from numpy.random import rand # number of nodes in the previous layer n = 10 # number of nodes in the next layer m = 20 # calculate the range for the weights lower, upper = -(sqrt(6.0) / sqrt(n + m)), (sqrt(6.0) / sqrt(n + m)) # generate random numbers numbers = rand(1000) # scale to the desired range scaled = lower + numbers * (upper - lower)
Метод инициализации He[3]
Поскольку ReLU несимметричная функция $f(x) = max(0, x)$, мы уже не можем утверждать, что среднее значение входных данных в каждом преобразовании будет нулевым:
Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению $y_{prev}$:
Тогда с учётом поведения ReLU и того, что $\mathrm{E}(y_{prev})=0$, можно сказать, что:
Получается, что при использовании ReLU, нужно инициализировать параметры из распределения с дисперсией $\mathrm{Var}[w_i]=\frac{2}{n_{in}}$.
Для нормального распределения $\mathcal N$ это будет:
Пример на языке Python с библиотекой NumPy
# example of the he weight initialization from math import sqrt from numpy.random import randn # number of nodes in the previous layer n = 10 # calculate the range for the weights std = sqrt(2.0 / n) # generate random numbers numbers = randn(1000) # scale to the desired range scaled = numbers * std