Прочтите часть 1 здесь.

Тестирование различных техник инициализации веса

Современные библиотеки глубокого обучения, такие как Keras, PyTorch и т. Д., Предлагают множество методов инициализации сети, которые, по сути, инициализируют веса небольшими случайными числами. Мы сделаем обзор различных методов и покажем вам, как эти разные методы влияют на производительность модели.

Напоминание №1: не инициализируйте свою сеть нулями.

Напоминание № 2: разветвление относится к количеству единиц на предыдущем уровне, а разветвление относится к количеству единиц в последующем уровне.

  • Стандартная нормальная инициализация - этот подход выбирает каждый вес из нормального распределения с небольшим отклонением.
  • Инициализация Lecun - эти инициализации производят веса, которые представляют собой произвольно выбранные числа, умноженные на дисперсию 1 / разветвление
  • Инициализация Xavier (также называемая инициализацией Glorot) - в этом подходе каждый случайно сгенерированный вес умножается на дисперсию 2 / (разветвление + разветвление). Теоретическое обоснование инициализации Xavier можно найти в сообщении deeplearning.ai об инициализации.
  • Инициализация - этот подход принимает случайно сгенерированные веса и умножает их на 2 / разветвление и рекомендуется для активации ReLU. См. He et al. Газета 2015 г. здесь.

В разных фреймворках по умолчанию установлены разные методы инициализации веса. Для Keras инициализация Xavier является по умолчанию, но в PyTorch инициализация Lecun является по умолчанию. В приведенном ниже примере мы покажем вам, как реализовать в PyTorch различные методы инициализации (помимо метода Lecun по умолчанию), и сравним различия в производительности.

Приведем несколько примеров!

Мы адаптируем это руководство из мастера глубокого обучения, чтобы построить довольно простую нейронную сеть с прямой связью и переключить метод инициализации, который мы используем.

Наиболее важной частью кода будет раздел «Создание класса модели», поскольку именно здесь мы определяем нашу функцию активации и метод инициализации веса:

class FeedforwardNeuralNetModel(nn.Module):
   def __init__(self, input_dim, hidden_dim, output_dim):
       super(FeedforwardNeuralNetModel, self).__init__()
       # Linear function
       self.fc1 = nn.Linear(input_dim, hidden_dim)
       ###  LECUN INITIALIZATION IS DEFAULT
      
       ### FOR NORMAL INITIALIZATION - uncomment to use
       # nn.init.normal_(self.fc1.weight, mean=0, std=1)
       ### FOR XAVIER INITIALIZATION
       nn.init.xavier_normal_(self.fc1.weight)
       # Non-linearity
       self.tanh = nn.Tanh()
       # Linear function
       self.fc2 = nn.Linear(hidden_dim, output_dim) 
       # nn.init.normal_(self.fc2.weight, mean=0, std=1)
       nn.init.xavier_normal_(self.fc2.weight)
       
def forward(self, x):
       # Linear function
       out = self.fc1(x)
       # Non-linearity
       out = self.tanh(out)
       # Linear function (readout)
       out = self.fc2(out)
       return out
       

В качестве конкретного примера, если мы используем метод инициализации Xavier с функцией активации tanh, определение класса модели будет выглядеть следующим образом:

class FeedforwardNeuralNetModel(nn.Module):
   def __init__(self, input_dim, hidden_dim, output_dim):
       super(FeedforwardNeuralNetModel, self).__init__()
       # Linear function
       self.fc1 = nn.Linear(input_dim, hidden_dim)
       ### FOR XAVIER INITIALIZATION
       # Linear weight, W,  Y = WX + B
       nn.init.xavier_normal_(self.fc1.weight)
       # Non-linearity
       self.tanh = nn.Tanh()
       # Linear function
       self.fc2 = nn.Linear(hidden_dim, output_dim) 
       nn.init.xavier_normal_(self.fc2.weight)
       
def forward(self, x):
       # Linear function
       out = self.fc1(x)
       # Non-linearity
       out = self.tanh(out)
       # Linear function (readout)
       out = self.fc2(out)
       return out

А вот обычный метод инициализации с функциями активации tanh:

class FeedforwardNeuralNetModel(nn.Module):
   def __init__(self, input_dim, hidden_dim, output_dim):
       super(FeedforwardNeuralNetModel, self).__init__()
       # Linear function
       self.fc1 = nn.Linear(input_dim, hidden_dim)
      
       ### FOR NORMAL INITIALIZATION
       # Linear weight, W,  Y = WX + B
       nn.init.normal_(self.fc1.weight, mean=0, std=1)
       # Non-linearity
       self.tanh = nn.Tanh()
       # Linear function
       self.fc2 = nn.Linear(hidden_dim, output_dim) 
       nn.init.normal_(self.fc2.weight, mean=0, std=1)
def forward(self, x):
       # Linear function
       out = self.fc1(x)
       # Non-linearity
       out = self.tanh(out)
       # Linear function (readout)
       out = self.fc2(out)
       return out

Примечание к версии: если вы используете PyTorch 1.1, планировщик lr (т.е. вызов функции schedule.step ()) должен вызываться в конце эпохи! В этом примере мы используем PyTorch 1.0.0. См. Дополнительную информацию в документации PyTorch здесь.

Мы используем Comet.ml для отслеживания деталей эксперимента и результатов для этих различных методов инициализации. Наличие автоматизированного способа регистрации этой информации позволяет нам быстро выполнять итерацию с различными параметрами и визуально сравнивать эти разные эксперименты.

См. полный интерактивный проект Comet.ml здесь:

Проведя различные эксперименты, мы видим, что метод инициализации Xavier дает нам наивысшую точность (97,36) для активации tanh. Неудивительно!

Однако метод инициализации Xavier также превосходит метод инициализации He для активаций ReLU с точки зрения точности (97,56 для He по сравнению с 97,68 для Xavier). Интересный…

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

Мы надеемся, что этот пост помог вам глубже понять, почему важна инициализация веса, предыстория и исследования, лежащие в основе различных методов инициализации веса, и как реализовать свой выбор инициализации!

Начни с Comet сегодня.

Дальнейшее чтение: