首页 > 解决方案 > 为什么我只使用 PyTorch 中的参数包装器进行收敛?

问题描述

我正在编写贝叶斯 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 中的参数,我就不需要为任何进一步使用它的值执行此操作。为什么我在这里需要它?

添加此包装器后,神经网络可以毫无问题地收敛。你能告诉我为什么会这样吗?如果有一个我不喜欢的更简单的替代解决方案?

标签: neural-networkpytorchbayesian-networks

解决方案


首先,您不需要传入self.MParameter因为渐变不会通过它。你的forward函数只使用self.Wself.m(加上激活,虽然你真的应该将它传递给构造函数,而不是forward......)。

所有self.M都是与模块同时创建的某种随机正态张量,它只是将您的self.W矩阵初始化为具体值。一个单独的张量也是如此self.W,它在计算上不依赖self.M于任何方式。


推荐阅读