Почему я собираюсь только с помощью обертки параметров в PyTorch? - PullRequest
0 голосов
/ 30 июня 2019

Я пишу реализацию Bayesian Dropout, и следующий код работал после нескольких часов отладки:

class DropoutLayer(nn.Module):

    def __init__(self, n_in, n_out, dropout_rate):
        super(DropoutLayer,self).__init__()
        self.M = Parameter(torch.normal(torch.zeros(n_in,n_out),0.01))
        self.m = Parameter(torch.rand(n_out))

        # 1-p is used to be consistent with original dropout definition
        self.z = Bernoulli(torch.tensor([1-dropout_rate]))

        self.W = Parameter(torch.mm(
        torch.diagflat(self.z.sample(sample_shape=(n_in,))),
        self.M))



    def forward(self,x,act):
        activation = torch.mm(x,self.W) + self.m

        out = act(activation) 
        return out

Однако я, похоже, не понимаю, почему умножение матриц в self.W требует переноса параметров. Я предположил бы, что как только я назначу self.M как параметр в autograd, мне не нужно будет делать это для любых значений, которые используют его в дальнейшем. Зачем мне это здесь?

После добавления этой оболочки нейронная сеть сходится без проблем. Не могли бы вы сказать мне, почему это так, и есть ли более простое заменитель этого решения, которое мне не нравится?

1 Ответ

1 голос
/ 01 июля 2019

Прежде всего, вам не нужно , чтобы передать self.M в Parameter, поскольку градиент не проходит через него.Ваша forward функция использует только self.W и self.m (плюс активация, хотя вы действительно должны передать ее конструктору, а не forward ...).

Все self.M является своего родаслучайного нормального тензора, созданного одновременно с модулем, и он просто инициализирует вашу матрицу self.W конкретными значениями.Так что self.W - это отдельный тензор, он никак не зависит от self.M в вычислительном отношении.

...