arrays - 在使用 Julia 中预分配数组的函数上使用自动微分
问题描述
我的长主题标题几乎涵盖了它。
在下面的以下人为示例中,我设法隔离了我更大的问题。我无法弄清楚问题到底出在哪里,尽管我认为它与预分配数组的类型有关?
using ForwardDiff
function test()
A = zeros(1_000_000)
function objective(A, value)
for i=1:1_000_000
A[i] = value[1]
end
return sum(A)
end
helper_objective = v -> objective(A, v)
ForwardDiff.gradient(helper_objective, [1.0])
end
错误如下:
ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{getfield(Main, Symbol("##69#71")){Array{Float64,1},getfield(Main, Symbol("#objective#70")){Array{Float64,1}}},Float64},Float64,1})
在我自己的问题(此处未描述)中,我有一个需要使用 Optim 优化的函数,以及它提供的自动微分,并且该函数使用了一个我想预先分配的大矩阵以加速我的代码. 非常感谢。
解决方案
如果您查看http://www.juliadiff.org/ForwardDiff.jl/latest/user/limitations.html,您会发现:
目标函数必须写得足够通用,以接受 T<:Real 类型的数字作为输入(或这些数字的数组)(...)这也意味着函数中使用的任何分配的存储也必须是通用的。
这里的例子https://github.com/JuliaDiff/ForwardDiff.jl/issues/136#issuecomment-237941790。
这意味着您可以执行以下操作:
function test()
function objective(value)
for i=1:1_000_000
A[i] = value[1]
end
return sum(A)
end
A = zeros(ForwardDiff.Dual{ForwardDiff.Tag{typeof(objective), Float64},Float64,1}, 1_000_000)
ForwardDiff.gradient(objective, [1.0])
end
但我不会认为这会为您节省很多分配,因为它类型不稳定。
您可以做的是包装objective
并A
放入这样的模块中:
using ForwardDiff
module Obj
using ForwardDiff
function objective(value)
for i=1:1_000_000
A[i] = value[1]
end
return sum(A)
end
const A = zeros(ForwardDiff.Dual{ForwardDiff.Tag{typeof(objective), Float64},Float64,1}, 1_000_000)
end
现在这个:
ForwardDiff.gradient(Obj.objective, [1.0])
应该很快。
编辑
这也有效(尽管它的类型不稳定,但问题较少):
function test()::Vector{Float64}
function objective(A, value)
for i=1:1_000_000
A[i] = value[1]
end
return sum(A)
end
helper_objective = v -> objective(A, v)
A = Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(helper_objective), Float64},Float64,1}}(undef, 1_000_000)
ForwardDiff.gradient(helper_objective, [1.0])
end
推荐阅读
- android - Flutter build appbundle R8:com.bundle.id.MainActivity 类型定义了多次:
- laravel - Laravel 事件广播和通知
- angular - 在哪里放置 *ngIf 指令?
- .net - 在一个租户中创建多个企业应用程序注册到同一个 Web 应用程序
- csrf - Symfony5 CSRF 令牌无效 - 在主机上上传后
- c# - 具有默认动态值的 IOptions 模式未按预期工作
- c# - 在实体配置中使用 EF Core HasQueryFilter 将可为空的数据库列映射到不可为空的属性?
- python - 在 python 中连接 Bash 命令
- javascript - 更新不是功能 - firebase firestore
- julia - 添加到目标的组合 - Julia lang