python - PyTorch 反向传播的数值等价性
问题描述
在我用 numpy 编写了简单的神经网络之后,我想将它与 PyTorch 实现进行数值比较。单独运行,似乎我的神经网络实现收敛,所以它似乎没有错误。iv 还检查了与 PyTorch 的前向传递匹配,因此基本设置是正确的。
但是在反向传播时会发生一些不同的事情,因为一次反向传播后的权重是不同的。
我不想在这里发布完整的代码,因为它链接了几个 .py 文件,并且大部分代码与问题无关。我只想知道 PyTorch 是“基本”梯度下降还是不同的东西。
我正在查看关于最后一层全连接权重的最简单示例,因为如果它不同,进一步也会不同:
self.weight += self.learning_rate * hidden_layer.T.dot(output_delta )
在哪里
output_delta = self.expected - self.output
self.expected 是期望值,self.output 是正向传递结果
这里没有激活或其他东西。
火炬往事是:
optimizer = torch.optim.SGD(nn.parameters() , lr = 1.0)
criterion = torch.nn.MSELoss(reduction='sum')
output = nn.forward(x_train)
loss = criterion(output, y_train)
loss.backward()
optimizer.step()
optimizer.zero_grad()
所以有可能使用 SGD 优化器和 MSELoss 它使用一些不同的增量或反向传播函数,而不是上面提到的基本函数?如果它很想知道如何用 pytorch 对我的 numpy 解决方案进行数字检查。
解决方案
我只想知道 PyTorch 是“基本”梯度下降还是不同的东西。
如果设置torch.optim.SGD
,这意味着随机梯度下降。您在 GD 上有不同的实现,但 PyTorch 中使用的实现适用于小批量。
有 GD 实现将在整个 epoch 之后优化参数。您可能会猜到它们非常“慢”,这对于超级计算机进行测试可能非常有用。有适用于每个样本的 GD 实现,因为您可能会猜到它们的不完美之处是“巨大的”梯度波动。
这些都是相对术语,所以我使用“”
请注意,您使用了太大的学习率,例如lr = 1.0
,这意味着您一开始还没有标准化您的数据,但随着时间的推移,您可能会剥削这项技能。
所以有可能使用 SGD 优化器和 MSELoss 它使用一些不同的增量或反向传播函数,而不是上面提到的基本函数?
它使用你所说的。
这是 PyTorch 和 Python 中的示例,用于显示梯度检测按预期工作(用于反向传播):
x = torch.tensor([5.], requires_grad=True);
print(x) # tensor([5.], requires_grad=True)
y = 3*x**2
y.backward()
print(x.grad) # tensor([30.])
你如何在普通 python 中得到这个值 30?
def y(x):
return 3*x**2
x=5
e=0.01 #etha
g=(y(x+e)-y(x))/e
print(g) # 30.0299
正如我们预期的那样,我们得到了 ~30,如果使用更小的etha
.
推荐阅读
- javascript - Javascript:将同一项目多次放入数组中的最简单方法是什么?
- regex - 正则表达式在单词前包含可选换行符
- reactjs - 使用 React 时如何将 react-particles-js 设置为背景?
- ruby-on-rails - 如何在 Rails 的管理部分正确使用“link_to”
- c++ - C ++在互斥锁中记录源位置
- ansible - 使用 Ansible 连接文件
- discord.js - 如何添加显示一个人等级的进度条
- java - Heroku 无法部署 Java 11 Spring Boot 应用程序
- javascript - 链接变量(一个网页到其他网页)
- javascript - jQuery - 鼠标离开