Практическое руководство по глубокому обучению 5.2 PyTorch Инициализация параметров

глубокое обучение PyTorch

Примите участие в 19-м дне Ноябрьского испытания обновлений и узнайте подробности события:Вызов последнего обновления 2021 г.

import torch
from torch import nn

Сначала создайте новую сеть и сгенерируйте тестовые данные X.

net = nn.Sequential(nn.Linear(4,8),
                    nn.ReLU(),
                    nn.Linear(8,2),
                    nn.MSELoss(),
                    nn.Linear(2,4))
print(net)

X = torch.rand(size=(5, 4))

Сеть такая.

>>
Sequential(
  (0): Linear(in_features=4, out_features=8, bias=True)
  (1): ReLU()
  (2): Linear(in_features=8, out_features=2, bias=True)
  (3): MSELoss()
  (4): Linear(in_features=2, out_features=4, bias=True)
)

image.png

Встроенная инициализация

def init_normal(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, mean=0, std=0.01)
        nn.init.zeros_(m.bias)
net.apply(init_normal)

Вызов встроенного инициализатора. В приведенном ниже коде все параметры веса инициализируются как гауссовы случайные величины со стандартным отклонением 0,01, а для параметра смещения устанавливается значение 0.

print(net[4].weight)
print(net[0].bias.data)
>>
Parameter containing:
tensor([[ 0.0047, -0.0060],
        [ 0.0135, -0.0032],
        [ 0.0048, -0.0043],
        [ 0.0058,  0.0013]], requires_grad=True)
tensor([0., 0., 0., 0., 0., 0., 0., 0.])

Взгляните на вывод весов и паранойи.

Мы также можем инициализировать все параметры заданными константами.

def init_constant(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 5)
        nn.init.zeros_(m.bias)
net.apply(init_constant)

print(net[4].weight)
print(net[0].bias.data)
>>
Parameter containing:
tensor([[5., 5.],
        [5., 5.],
        [5., 5.],
        [5., 5.]], requires_grad=True)
tensor([0., 0., 0., 0., 0., 0., 0., 0.])

Кроме того, для разных слоев могут применяться разные методы инициализации.

net[0].apply(init_normal)
net[2].apply(init_constant)
net[4].apply(init_constant)

print(net[0].weight.data)
print(net[2].weight.data)
>>
tensor([[-0.0138,  0.0057, -0.0061,  0.0052],
        [ 0.0126, -0.0008, -0.0102, -0.0230],
        [ 0.0144, -0.0041,  0.0095,  0.0127],
        [ 0.0108, -0.0063, -0.0181, -0.0175],
        [-0.0085,  0.0055, -0.0014, -0.0086],
        [-0.0082,  0.0100, -0.0025, -0.0020],
        [ 0.0009, -0.0099,  0.0047,  0.0040],
        [ 0.0020, -0.0097, -0.0025, -0.0075]])
tensor([[5., 5., 5., 5., 5., 5., 5., 5.],
        [5., 5., 5., 5., 5., 5., 5., 5.]])

пользовательская инициализация

Помимо инициализации константой и инициализации распределения Гаусса, pytorch также поддерживает другие методы инициализации.Дополнительные методы инициализации см. в официальном руководстве:torch.nn.init — документация PyTorch 1.10.0

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

Например, мы используем следующее распределение для произвольных весовых параметровwwОпределите метод инициализации:

w{U(5,10) with probability 140 with probability 12U(10,5) with probability 14\begin{aligned} w \sim \begin{cases} U(5, 10) & \text{ with probability } \frac{1}{4} \\ 0 & \text{ with probability } \frac{1}{2} \\ U(-10, -5) & \text{ with probability } \frac{1}{4} \end{cases} \end{aligned}
def my_init(m):
    if type(m) == nn.Linear:
        nn.init.uniform_(m.weight, -10, 10)
        m.weight.data *= m.weight.data.abs() >= 5

net.apply(my_init)

print(net[0].weight.data[0])
print(net[2].weight.data[0])
>>
tensor([-8.9126, -7.9010, -0.0000, -0.0000])
tensor([-0.0000, -8.6281,  0.0000,  9.8472, -0.0000,  9.7564,  0.0000,  8.5654])

понялmy_initфункция для применения кnet. Здесь выводится только первая строка весов.

Проанализируйте этоnn.init.uniform_(m.weight, -10, 10)и m.weight.data *= m.weight.data.abs() >= 5Две строчки кода.

Требование состоит в том, чтобы w имел14\frac 1 4Вероятность подчиняться равномерному распределению (-10,5), имеем14\frac 1 4Вероятность подчинения равномерному распределению (5, 10) и12\frac 1 2Вероятность равна 0.

  • nn.init.uniform_(m.weight, -10, 10)является равномерным распределением, где w все инициализировано значением (-10, 10).
  • m.weight.data *= m.weight.data.abs() >= 5Примите решение, чтобы увидеть, является ли абсолютное значение каждого веса больше или равным 5. Если оно больше или равно 5, доказано, что оно находится в интервале (5, 10) и (-10, -5 ), затем верните true, что равно 1,m.weight.dataУмножение на 1 не изменит значение; в противном случае будет возвращено значение false, равное 0.m.weight.dataНуль. Как гарантировать14\frac 1 4,12\frac 1 2Вероятности, поскольку они распределены равномерно, по умолчанию их распределение на интервале является равномерным.

Ручная настройка

Следуя приведенному выше коду, мы также можем вручную изменить значение параметра, например:

print(net[4].weight.data)

net[4].weight.data[:] += 10
print(net[4].weight.data)

net[4].weight.data[0, 0] = 666
print(net[4].weight.data)
>>
tensor([[ 0.0000,  6.9226],
        [-0.0000, -0.0000],
        [-8.0648,  9.4455],
        [-5.8219,  5.6904]])
tensor([[10.0000, 16.9226],
        [10.0000, 10.0000],
        [ 1.9352, 19.4455],
        [ 4.1781, 15.6904]])
tensor([[666.0000,  16.9226],
        [ 10.0000,  10.0000],
        [  1.9352,  19.4455],
        [  4.1781,  15.6904]])

Параметры изменятся там, где вы их вручную измените.


  1. Подробнее о серии «Практическое глубокое обучение» см. здесь:Колонка «Практическое глубокое обучение» (juejin.cn)

  2. Примечания Адрес Github:DeepLearningNotes/d2l(github.com)

Все еще в процессе обновления......