Инициализация параметров глубокой сети — различия между версиями
м (fix 4) |
(he выкладки) |
||
Строка 53: | Строка 53: | ||
Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению $y_{prev}$: | Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению $y_{prev}$: | ||
*<tex>x=\mathrm{ReLU}(y_{prev})</tex> | *<tex>x=\mathrm{ReLU}(y_{prev})</tex> | ||
− | + | Давайте покажем, что $\mathbb{E}(y_{prev})=0$, так как $w_{prev_{i}}$ и $x_{prev_{i}}$ независимы: | |
− | *<tex>\mathbb{E}[x_i^2]=\frac{1}{2}\mathrm{Var}[ | + | *<tex>\mathbb{E}[y_{prev_{i}}]=\mathbb{E}[w_{prev_{i}} x_{prev_{i}}]=\mathbb{E}[w_{prev_{i}}] \mathbb{E}[x_{prev_{i}}]=0</tex><br><tex>\Rightarrow \mathbb{E}[y_{prev}]=\mathbb{E}[\sum\limits_{i=1}^{n_{in}}[y_{prev_{i}}]]=\sum\limits_{i=1}^{n_{in}}(\mathbb{E}[y_{prev_{i}}])=0</tex> |
+ | Также $y_{prev_i}$ распределены симметрично относительно нуля: | ||
+ | *<tex>\mathbb{P}(y_{prev_i}>0)=\mathbb{P}(w_{prev_{i}} x_{prev_{i}}>0)</tex><br><tex>=\mathbb{P}((w_{prev_{i}}>0 \wedge x_{prev_{i}}>0) \vee ((w_{prev_{i}}<0 \wedge x_{prev_{i}}<0)))</tex><br><tex>=\mathbb{P}(w_{prev_{i}}>0)\mathbb{P}(x_{prev_{i}}>0)+\mathbb{P}(w_{prev_{i}}<0)\mathbb{P}(x_{prev_{i}}<0)</tex><br><tex>=\frac{1}{2}\mathbb{P}(x_{prev_{i}}>0)+\frac{1}{2}\mathbb{P}(x_{prev_{i}}<0)=\frac{1}{2}</tex> | ||
+ | Из предыдущих двух выкладок следует: | ||
+ | *<tex>\mathbb{E}[x_i^2]=\mathbb{E}[max(0, y_{prev})^2]=\frac{1}{2}\mathbb{E}[y_{prev}^2]=\frac{1}{2}\mathrm{Var}[ | ||
y_{prev}]</tex><br><tex>\Rightarrow \mathrm{Var}[y]=\frac{1}{2}n_{in}\mathrm{Var}[w_i]\mathrm{Var}[y_{prev}]</tex> | y_{prev}]</tex><br><tex>\Rightarrow \mathrm{Var}[y]=\frac{1}{2}n_{in}\mathrm{Var}[w_i]\mathrm{Var}[y_{prev}]</tex> | ||
Версия 22:24, 12 мая 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] данный способ не подходит.
Пример инициализации Xavier на языке Python с фреймворком PyTorch
# инициализация параметров одного слоя conv1 = torch.nn.Conv2d(...) torch.nn.init.xavier_uniform(conv1.weight)
Пример инициализации Xavier на языке Python с библиотекой TensorFlow
# инициализация параметров тензора 2x2 initializer = tf.keras.initializers.GlorotUniform() values = initializer(shape=(2, 2))
Метод инициализации He[3]
Поскольку ReLU несимметричная функция $f(x) = max(0, x)$, мы уже не можем утверждать, что среднее значение входных данных в каждом преобразовании будет нулевым:
Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению $y_{prev}$:
Давайте покажем, что $\mathbb{E}(y_{prev})=0$, так как $w_{prev_{i}}$ и $x_{prev_{i}}$ независимы:
Также $y_{prev_i}$ распределены симметрично относительно нуля:
Из предыдущих двух выкладок следует:
Получается, что при использовании ReLU, нужно инициализировать параметры из распределения с дисперсией $\mathrm{Var}[w_i]=\frac{2}{n_{in}}$.
Для равномерного распределения $\mathcal U$ это будет:
Для нормального распределения $\mathcal N$ это будет:
Пример инициализации He на языке Python с фреймворком PyTorch
# инициализация параметров одного слоя conv1 = torch.nn.Conv2d(...) torch.nn.init.kaiming_uniform_(conv1.weight)
Пример инициализации He на языке Python с библиотекой TensorFlow
# инициализация параметров тензора 2x2 initializer = tf.keras.initializers.HeUniform() values = initializer(shape=(2, 2))