neural-network - 为什么我只使用 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 中的参数,我就不需要为任何进一步使用它的值执行此操作。为什么我在这里需要它?
添加此包装器后,神经网络可以毫无问题地收敛。你能告诉我为什么会这样吗?如果有一个我不喜欢的更简单的替代解决方案?
解决方案
首先,您不需要传入self.M
,Parameter
因为渐变不会通过它。你的forward
函数只使用self.W
和self.m
(加上激活,虽然你真的应该将它传递给构造函数,而不是forward
......)。
所有self.M
都是与模块同时创建的某种随机正态张量,它只是将您的self.W
矩阵初始化为具体值。一个单独的张量也是如此self.W
,它在计算上不依赖self.M
于任何方式。
推荐阅读
- javascript - 猫鼬总是保存错误的日期
- flutter - 下面的构造函数在 dart 中是如何工作的,我已经提取了小部件,flutter 为我的小部件提供了下面的构造函数
- java - Javadoc {@value} 不适用于常量
- javascript - 在登录 nodejs 上管理会话
- reactjs - React Ionic hooks 组件 setValue 不起作用
- lua - 脚本有效,但在 roblox 工作室游戏中没有任何反应
- java - IndexOf 不同的结果,带空格的输入
- c++ - vector.size() - 2 导致无限循环 - C++
- python - 使用 geoviews 时无法导入 matplotlib 后端
- c# - 使用 Win32 API 移动文件时自动设置安全属性?(C#)