gpt4 book ai didi

machine-learning - Julia ReverseDiff : how to take a gradient w. r.t.仅输入的子集?

转载 作者:行者123 更新时间:2023-11-30 08:40:41 25 4
gpt4 key购买 nike

在我的数据流中,我正在查询数据库的一小部分,使用这些结果构建大约十几个数组,然后,给定一些参数值,计算似然值。然后对数据库的子集重复此操作。我想计算似然函数相对于参数而不是数据的梯度。但 ReverseDiff 计算所有输入的梯度。我该如何解决这个问题?具体来说,如何构造 ReverseDiff.Tape 对象

TL;DR:如何将随机梯度下降和 ReverseDiff 结合起来? (我并不热衷于使用 ReverseDiff。它似乎是适合这项工作的工具。)

看来这必须是一种常见的编码模式。我的领域一直在使用它。但我错过了一些东西。 Julia 的作用域规则似乎破坏了作用域/匿名函数方法,并且 ReverseDiff 保留生成的磁带中的原始数据值,而不是使用变异值。

一些不起作用的示例代码

using ReverseDiff
using Base.Test


mutable struct data
X::Array{Float64, 2}
end

const D = data(zeros(Float64, 2, 2))

# baseline known data to compare against
function f1(params)
X = float.([1 2; 3 4])
f2(params, X)
end

# X is data, want derivative wrt to params only
function f2(params, X)
sum(params[1]' * X[:, 1] - (params[1] .* params[2])' * X[:, 2].^2)
end

# store data of interest in D.X so that we can call just f2(params) and get our
# gradient
f2(params) = f2(params, D.X)

# use an inner function and swap out Z's data
function scope_test()
function f2_only_params(params)
f2(params, Z)
end
Z = float.([6 7; 1 3])
f2_tape = ReverseDiff.GradientTape(f2_only_params, [1, 2])

Z[:] = float.([1 2; 3 4])
grad = ReverseDiff.gradient!(f2_tape, [3,4])
return grad
end

function struct_test()
D.X[:] = float.([6 7; 1 3])
f2_tape = ReverseDiff.GradientTape(f2, [1., 2.])
D.X[:] = float.([1 2; 3 4])
grad = ReverseDiff.gradient!(f2_tape, [3., 4.])
return grad
end

function struct_test2()
D.X[:] = float.([1 2; 3 4])
f2_tape = ReverseDiff.GradientTape(f2, [3., 4.])
D.X[:] = float.([1 2; 3 4])
grad = ReverseDiff.gradient!(f2_tape, [3., 4.])
return grad
end

D.X[:] = float.([1 2; 3 4])

@test f1([3., 4.]) == f2([3., 4.], D.X)
@test f1([3., 4.]) == f2([3., 4.])

f1_tape = ReverseDiff.GradientTape(f1, [3,4])
f1_grad = ReverseDiff.gradient!(f1_tape, [3,4])
# fails! uses line 33 values
@test scope_test() == f1_grad
# fails, uses line 42 values
@test struct_test() == f1_grad
# succeeds, so, not completely random
@test struct_test2() == f1_grad

最佳答案

目前这是不可能的(遗憾的是)。这两种解决方法都存在 GitHub 问题: https://github.com/JuliaDiff/ReverseDiff.jl/issues/36

  • 不要使用预先录制的磁带
  • 或相对于所有参数进行微分并忽略某些输入参数的梯度。

我也遇到了同样的问题,我改用了 Knet 的 grad 函数。我只支持相对于一个参数的微分,但这个参数可以非常灵活(例如数组的数组或一个或多个字典)。

关于machine-learning - Julia ReverseDiff : how to take a gradient w. r.t.仅输入的子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50168800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com