问题标签 [automatic-differentiation]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C++ 用图逆向自动微分
我正在尝试在 C++ 中进行反向模式自动微分。
我想出的想法是,对一个或两个其他变量进行操作的每个变量都将把梯度保存在一个向量中。
这是代码:
我试图运行这样的代码:
应该构建的计算图如下:
然后,例如,如果我想计算∂k/∂x
,我必须乘以沿边缘的梯度,并对每个边缘的结果求和。这是由 递归完成的double gradient(Var* var) const
。所以我有∂k/∂x = ∂k/∂w * ∂w/∂x + ∂k/∂z * ∂z/∂x
。
问题
如果我有像x*y
这里这样的中间计算,就会出现问题。此处未注释时std::cout
为输出:
它打印哪个变量连接到哪个变量,然后是它们的地址,以及连接的权重(应该是梯度)。
问题 weight=0
出在中间变量和中间变量之间x
,中间变量保存了x*y
(我w
在图中表示)的结果。我不知道为什么这个是零而不是连接到的另一个重量y
。
我注意到的另一件事是,如果您operator*
像这样切换线路:
然后是y
取消的连接。
提前感谢您的帮助。
c++ - 为什么 C++ 编译器不做更好的常量折叠?
我正在研究加速大部分 C++ 代码的方法,该代码具有用于计算雅可比的自动导数。这涉及在实际残差中做一些工作,但大部分工作(基于分析的执行时间)是计算雅可比。
这让我很惊讶,因为大多数雅可比是从 0 和 1 向前传播的,所以工作量应该是函数的 2-4 倍,而不是 10-12 倍。为了模拟大量的 jacobian 工作是什么样的,我做了一个超级最小的例子,只有一个点积(而不是真实情况下的 sin、cos、sqrt 等),编译器应该能够优化为单个返回值:
应该是一样的
我很失望地发现,在没有启用快速数学的情况下,GCC 8.2、Clang 6 或 MSVC 19 都无法对充满 0 的矩阵的天真点积进行任何优化。即使使用快速数学(https://godbolt.org/z/GvPXFy),GCC 和 Clang 的优化也很差(仍然涉及乘法和加法),并且 MSVC 根本不做任何优化。
我没有编译器的背景,但这有什么原因吗?我相当肯定,在大部分科学计算中,能够进行更好的常数传播/折叠将使更多优化变得明显,即使常数折叠本身并没有导致加速。
虽然我对解释为什么不在编译器方面这样做很感兴趣,但我也对我可以在实际方面做些什么来使我自己的代码在面对这些类型的模式时变得更快感兴趣。
arrays - 在使用 Julia 中预分配数组的函数上使用自动微分
我的长主题标题几乎涵盖了它。
在下面的以下人为示例中,我设法隔离了我更大的问题。我无法弄清楚问题到底出在哪里,尽管我认为它与预分配数组的类型有关?
错误如下:
在我自己的问题(此处未描述)中,我有一个需要使用 Optim 优化的函数,以及它提供的自动微分,并且该函数使用了一个我想预先分配的大矩阵以加速我的代码. 非常感谢。
python - 梯度计算过程中tensorflow如何处理不可微节点?
我理解自动微分的概念,但找不到任何解释 tensorflow 如何计算不可微分函数的误差梯度,例如tf.where
在我的损失函数或tf.cond
图表中。它工作得很好,但我想了解 tensorflow 如何通过这些节点反向传播错误,因为没有公式可以计算它们的梯度。
c++ - 使用 CoDiPack 自动区分
以下代码:
给我编译错误:
nnBFAD.cpp:在函数 'void OptBF()' 中:
nnBFAD.cpp:156:25: 错误: 在初始化 double 中无法将 'codi::RealForward {aka codi::ActiveReal >}' 转换为 'double'
提示?
python - 使用 Pytorch 的黑盒函数的 Hessian
首先,我对 Python 和机器学习非常陌生,所以请原谅我对可能是一个非常基本的问题的无知;我非常感谢您对这个问题的任何意见!
我有一个用 Python 实现的非常复杂的标量值多变量函数,它使用 Pytorch 功能(它实际上是神经网络和依赖于网络输出的操作的组合),我希望找到梯度向量和 Hessian 矩阵此功能在某些点。除此之外numdifftools
,当输入的维度很高时,有限差分并且不是非常快速和准确,还有其他选择吗?看起来很有希望的是torch.autograd
我相信它被用来计算神经网络的梯度,但是,它可以计算任何运行 Pytorch 代码的黑盒函数的梯度和 Hessian 吗?任何输入表示赞赏!
complexity-theory - 如何计算自动微分的计算复杂度?
我正在使用 Pytorch 中实现的自动网格来训练神经网络,我需要计算整个算法的计算复杂度。我在哪里可以找到 autograd 计算复杂度的完整计算?我在 Pytorch 文档中进行了搜索,但没有找到任何答案。谢谢
julia - 与 ::getfield() 相关的 ForwardDiff.jl 和 ReverseDiff.jl 错误消息
我正在尝试使用 ForwardDiff.jl 和/或 ReverseDiff.jl 库来计算优化问题中的梯度。
这两个包都给我一个与 ::getfield() 相关的错误消息。
ReverseDiff 给了我一个 LoadError:
ForwardDiff 给了我一个 LoadError:
我不知道如何理解这个错误信息。我的代码太复杂,无法在这里发布,但据我所知,我没有使用任何不是用 Julia 编写的库。我确实在整个过程中广泛使用自定义数据类型(可变结构),但我不明白为什么这会导致问题......
python - 牛顿方法的 PyTorch 实现中的更新步骤
我试图通过实现牛顿求解x = cos(x)的方法来深入了解 PyTorch 的工作原理。这是一个有效的版本:
这段代码对我来说似乎不优雅(效率低下?),因为它在for
循环的每个步骤中都重新创建了整个计算图(对吗?)。我试图通过简单地更新每个变量持有的数据而不是重新创建它们来避免这种情况:
似乎,对于DoubleTensor
s,我携带了足够多的精度来排除舍入误差。那么错误来自哪里?
可能相关:如果循环,上面的代码片段retain_graph=True
在每一步都没有设置标志的情况下中断。for
如果我在循环中省略它——但在第 3 行保留它——我得到的错误消息是:
RuntimeError: Trying backing through the graph a second time, but the buffers have been freed. 第一次向后调用时指定retain_graph=True 。这似乎证明我误解了什么......