Инициализация параметров ======================== Теперь, когда мы знаем, как получить доступ к параметрам, рассмотрим, как их правильно инициализировать. Необходимость правильной инициализации мы обсуждали в :numref:`sec_numerical_stability`. Фреймворк глубокого обучения предоставляет слоям случайную инициализацию по умолчанию. Однако зачастую нам требуется инициализировать веса в соответствии с различными другими схемами. Фреймворк поддерживает наиболее часто используемые схемы, а также позволяет создавать пользовательские инициализаторы. .. raw:: latex \diilbookstyleinputcell .. code:: python import torch from torch import nn По умолчанию PyTorch инициализирует матрицы весов и смещений, равномерно выбирая значения из диапазона, вычисляемого на основе размерности входа и выхода. Модуль ``nn.init`` PyTorch предоставляет множество предустановленных методов инициализации. .. raw:: latex \diilbookstyleinputcell .. code:: python net = nn.Sequential(nn.LazyLinear(8), nn.ReLU(), nn.LazyLinear(1)) X = torch.rand(size=(2, 4)) net(X).shape Встроенная инициализация ------------------------ Начнем с использования встроенных инициализаторов. Приведённый ниже код инициализирует все параметры весов как гауссовы случайные величины со стандартным отклонением 0.01, а параметры смещения обнуляются. .. raw:: latex \diilbookstyleinputcell .. code:: python def init_normal(module): if type(module) == nn.Linear: nn.init.normal_(module.weight, mean=0, std=0.01) nn.init.zeros_(module.bias) net.apply(init_normal) net[0].weight.data[0], net[0].bias.data[0] Мы также можем инициализировать все параметры заданным постоянным значением (например, 1). .. raw:: latex \diilbookstyleinputcell .. code:: python def init_constant(module): if type(module) == nn.Linear: nn.init.constant_(module.weight, 1) nn.init.zeros_(module.bias) net.apply(init_constant) net[0].weight.data[0], net[0].bias.data[0] Мы также можем применять различные инициализаторы для отдельных блоков. Например, ниже мы инициализируем первый слой с помощью инициализатора Глорота, а второй слой — константным значением 42. .. raw:: latex \diilbookstyleinputcell .. code:: python def init_xavier(module): if type(module) == nn.Linear: nn.init.xavier_uniform_(module.weight) def init_42(module): if type(module) == nn.Linear: nn.init.constant_(module.weight, 42) net[0].apply(init_xavier) net[2].apply(init_42) print(net[0].weight.data[0]) print(net[2].weight.data) Пользовательская инициализация ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Иногда необходимые методы инициализации не предоставляются фреймворком глубокого обучения. В примере ниже мы определяем инициализатор для любого параметра веса :math:`w`, используя следующее странное распределение: .. math:: \begin{aligned} w \sim \begin{cases} U(5, 10) & \textrm{ with probability } \frac{1}{4} \\ 0 & \textrm{ with probability } \frac{1}{2} \\ U(-10, -5) & \textrm{ with probability } \frac{1}{4} \end{cases} \end{aligned} Снова мы реализуем функцию ``my_init``, которую будем применять к ``net``. .. raw:: latex \diilbookstyleinputcell .. code:: python def my_init(module): if type(module) == nn.Linear: print("Init", *[(name, param.shape) for name, param in module.named_parameters()][0]) nn.init.uniform_(module.weight, -10, 10) module.weight.data *= module.weight.data.abs() >= 5 net.apply(my_init) net[0].weight[:2] Обратите внимание, что мы всегда можем задавать параметры напрямую. .. raw:: latex \diilbookstyleinputcell .. code:: python net[0].weight.data[:] += 1 net[0].weight.data[0, 0] = 42 net[0].weight.data[0] Итоги ----- Параметры можно инициализировать с помощью встроенных и пользовательских инициализаторов. Упражнения ---------- Посмотрите онлайн-документацию, чтобы узнать о других встроенных инициализаторах. `Обсуждения `__