You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Flux求梯度时出现‘Mutating arrays is not supported’错误的原因与修复

Flux/Zygote中push!创建的数组计算梯度报错的原因与修复

最小可复现代码

using Flux

myvector = []
for i in 1:3
    push!(myvector, 0.1 * i) # 生成向量 [0.1, 0.2, 0.3]
end

Q = Chain(Dense(3, 64, relu), Dense(64, 32, relu), Dense(32, 16, relu), 
    Dense(16, 1, identity)) # 创建神经网络,参数细节不影响问题
θ, re = Flux.destructure(Q)

f(x) = -re(θ)(x)[1]

gs = gradient(f, myvector)[1] # 在myvector处计算f的梯度

触发的错误信息

Mutating arrays is not supported -- called setindex!(Vector{Any}, ...)
This error occurs when you ask Zygote to differentiate operations that change
the elements of arrays in place (e.g. setting values with x .= ...)

用户疑问

明明未修改数组元素,仅通过push!扩展数组长度,为何触发该错误?如何修复?

注:直接定义myvector = [0.1, 0.2, 0.3]时无错误,但实际场景需逐个计算元素无法采用该方式;定义myvector = AbstractFloat[]时也无错误,但该方式在实际场景存在其他问题。


错误原因

问题出在myvector = []初始化的是Vector{Any}类型数组。Zygote在计算这类任意类型数组的梯度时,内部会涉及到隐式的类型转换与元素赋值操作(即报错里的setindex!)——因为数组元素类型不确定,Zygote需要在反向传播过程中调整元素类型或存储方式,这就触发了它禁止的原地修改操作。

而直接定义具体数值类型数组(如[0.1,0.2,0.3])或AbstractFloat[]时,数组的元素类型是明确的参数化类型,Zygote无需进行这类隐式修改,因此可以正常计算梯度。

修复方法

方法1:初始化时指定具体数值类型

将数组初始化为明确的数值类型容器,比如Float64类型:

myvector = Float64[] # 或 Vector{Float64}()
for i in 1:3
    push!(myvector, 0.1 * i)
end

这样数组元素类型固定,Zygote可以直接处理,不会触发隐式修改操作。

方法2:生成后转换为具体类型数组

如果实际场景无法提前指定类型,可以在生成数组后转换为明确类型:

myvector = []
for i in 1:3
    push!(myvector, 0.1 * i)
end
myvector = convert(Vector{Float64}, myvector) # 转换为Float64数组

或者直接用生成式(适配逐个计算元素的场景):

myvector = Float64[0.1*i for i in 1:3]

内容的提问来源于stack exchange,提问作者Allure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:15:34