如何解引用GlobalRef以获取其指向的全局变量实际值
问题解答
核心问题:从GlobalRef中获取实际值
你要的函数f可以直接通过访问GlobalRef的两个内置字段实现:
f(p::GlobalRef) = getproperty(p.mod, p.name)
也可以用更底层的getfield实现,效果完全一致:
f(p::GlobalRef) = getfield(p.mod, p.name)
此时就满足W1 === f(p)的判断条件。
Zygote优化场景注意事项
你当前写的p += η * g是无效的:
- 这里的
p是GlobalRef类型的局部变量,直接对它做加法赋值只会修改当前局部变量p的指向,完全不会更新你全局定义的W1的值。 - 正确的更新写法有两种:
- 如果你的参数是数组,推荐用原地操作避免额外内存开销:
for (p, g) in pairs(gs.grads) # 先拿到实际的参数数组 param = getproperty(p.mod, p.name) # 原地更新参数值 param .+= η .* g end - 如果参数是标量或者其他不可原地修改的类型,可以用
setproperty!更新全局变量:for (p, g) in pairs(gs.grads) old_val = getproperty(p.mod, p.name) new_val = old_val + η * g setproperty!(p.mod, p.name, new_val) end
- 如果你的参数是数组,推荐用原地操作避免额外内存开销:
补充说明:如果你的优化参数是全局定义的,建议给参数加
const声明,既可以避免Zygote返回GlobalRef类型的引用,也能大幅提升Julia的运行性能。
内容的提问来源于stack exchange,提问作者Telcrome
相关产品推荐
相关产品推荐

