Инициализация параметров глубокой сети — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
м (fix 4)
(he выкладки)
Строка 53: Строка 53:
 
Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению yprev:
 
Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению yprev:
 
*<tex>x=\mathrm{ReLU}(y_{prev})</tex>
 
*<tex>x=\mathrm{ReLU}(y_{prev})</tex>
Тогда с учётом поведения ReLU и того, что $\mathrm{E}(y_{prev})=0$, можно сказать, что:
+
Давайте покажем, что $\mathbb{E}(y_{prev})=0$, так как wprevi и xprevi независимы:
*<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>
 +
Также yprevi распределены симметрично относительно нуля:
 +
*<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

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

Наивная инициализация

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

Инициализация случайными числами

Рассмотрим линейное преобразование:

  • y=wTx+b=(wixi)+b=(yi)+b

Его дисперсия (считаем настраиваемые параметры и входные данные независимыми):

  • Var[yi]=Var[wixi]=E[xi]2Var[wi]+E[wi]2Var[xi]+Var[wi]Var[xi] (см. дисперсия произведения)

Если отнормировать входные данные и подобрать параметры, чтобы среднее было нулевым, получится:

  • (E[xi]=0,E[wi]=0)Var[yi]=Var[wi]Var[xi]

Поскольку xi мы отнормировали, а wi из одного распределения, то все дисперсии одинаковые:

  • Var[y]=Var[nini=1[yi]]=nini=1[wixi]=ninVar[wi]Var[xi]

Отсюда видно, что дисперсия результата линейно зависит от дисперсии входных данных с коэффициентом ninVar[wi].

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

Если коэффициент будет <1 это приведет к снижению дисперсии с каждым новым преобразованием с около нулевым промежуточным представлением, что тоже негативно скажется на обучении сети.

Поэтому для начальной инициализации параметров стоит использовать такое распределение, что Var[wi]=1nin, которое позволит сохранить дисперсию входных данных.

Метод инициализации Xavier[1]

Предыдущий подход хорошо работает, когда размерность наших данных не изменяется после преобразований (nin=nout), но так бывает не всегда. В качестве компромисса Xavier Glorot и Yoshua Bengio предлагают инициализировать параметры из распределения с дисперсией Var[wi]=2nin+nout.

Для равномерного распределения U это будет:

  • wiU[6nin+nout,6nin+nout]

Для нормального распределения N это будет:

  • wiN(0,2nin+nout)

Этот способ инициализации хорошо подойдет для симметричных относительно нуля функций активации (гиперболический тангенс, сигмоид), для 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), мы уже не можем утверждать, что среднее значение входных данных в каждом преобразовании будет нулевым:

  • (E[xi]0,E[wi]=0)
    Var[yi]=E[xi]2Var[wi]+Var[wi]Var[xi]=Var[wi](E[xi]2+Var[xi])=Var[wi]E[x2i]
    Var[y]=ninVar[wi]E[x2i]

Поэтому мы будем пытаться контролировать дисперсию не между слоями, а между входами ReLU. Пусть представление на входе было получено после применения данной функции активации к предыдущему представлению yprev:

  • x=ReLU(yprev)

Давайте покажем, что E(yprev)=0, так как wprevi и xprevi независимы:

  • E[yprevi]=E[wprevixprevi]=E[wprevi]E[xprevi]=0
    E[yprev]=E[nini=1[yprevi]]=nini=1(E[yprevi])=0

Также yprevi распределены симметрично относительно нуля:

  • P(yprevi>0)=P(wprevixprevi>0)
    =P((wprevi>0xprevi>0)((wprevi<0xprevi<0)))
    =P(wprevi>0)P(xprevi>0)+P(wprevi<0)P(xprevi<0)
    =12P(xprevi>0)+12P(xprevi<0)=12

Из предыдущих двух выкладок следует:

  • E[x2i]=E[max(0,yprev)2]=12E[y2prev]=12Var[yprev]
    Var[y]=12ninVar[wi]Var[yprev]

Получается, что при использовании ReLU, нужно инициализировать параметры из распределения с дисперсией Var[wi]=2nin.

Для равномерного распределения U это будет:

  • wiU[3nin,3nin]

Для нормального распределения N это будет:

  • wiN(0,2nin)

Пример инициализации 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))

См.также

Примечания

Источники информации

  1. Онлайн-учебник по машинному обучению от ШАД