# Weight regularisation which iterates params(m) in Flux -- Mutating arrays is not supported

**URL:** <https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314>\
**Category:** Machine Learning\
**Tags:** flux, zygote\
**Created:** [July 9, 2021, 12:36am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314 "2021-07-09T00:36:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [July 9, 2021, 12:36am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/1 "2021-07-09T00:36:11Z")

</div>

I’m trying to implement weight regularisation which requires adding a weight-dependent penalty to the loss function. When I proceed naively, I run into “Mutating arrays is not supported” but I don’t understand what arrays I am mutating. Here’s a MWE:

```julia
c = rand(3)
julia> gs = gradient(params(c)) do 
       sum(sum.(params(c)))
       end
ERROR: Mutating arrays is not supported

```

If I delete the second `params` the error disappears, but in my problem I don’t have explicit access to the params any other way.

Where is the mutation?  
What is the workaround?

---

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [July 9, 2021, 12:44am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/2 "2021-07-09T00:44:21Z")

</div>

Even this throws an error:

```julia
c = rand(3)
gs = gradient(params(c)) do
    params(c)[1][1]
end 

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [July 9, 2021, 1:09am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/3 "2021-07-09T01:09:42Z")

</div>

Don’t call params in the gradient call.

> [@ablaom](#):
>
> ```julia
> c = rand(3)
> gs = gradient(c) do
> c[1][1]
> end 
> 
> ```

---

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [July 9, 2021, 3:11am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/4 "2021-07-09T03:11:38Z")

</div>

Sure @ChrisRackauckas (and thanks) but that doesn’t solve my problem, as `c` is not an array in my problem but some generic Flux chain. I don’t have access to the individual parameters, because responsibility for constructing `c` lies elsewhere. Also, I cannot see any whiff of an array mutation in what I have written here, so what’s the explanation for the error?

In my problem I have a Flux model, `c` say. I don’t know how it was constructed, but I can extract it’s parameters with `ps = params(c)`. I need the parameters to compute a weight penalty. For example, for L2 regularisation, I’m doing something like this, but it doesn’t work:

```nohighlight
lambda = 0.1 # regularization
X, Y = # some input/target training data
gs = gradient(params(c)) do
loss(x, y) = mse(c(x), y) + lambda*sum(x->sum(x.^2), params(c))
gs = Flux.gradient(params(chain)) do
    loss(X[i], y[i])
end
# and so forth
```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [July 9, 2021, 3:48am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/5 "2021-07-09T03:48:17Z")

</div>

This might be [Flux#1588](https://github.com/FluxML/Flux.jl/issues/1588), for which there appear to be a dozen overlapping PRs. What seems to work is not calling `params` inside `gradient`, and not using broadcasting:

```julia
julia> using Zygote, Flux

julia> c = rand(3);

julia> ps = params(c);

julia> gs = gradient(params(c)) do 
              sum(sum(x) for x in ps)
           end
Grads(...)

julia> gs[c]
3-element Fill{Float64}: entries equal to 1.0

```

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [July 9, 2021, 4:32am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/6 "2021-07-09T04:32:13Z")

</div>

AIUI #1588 should’ve been fixed by [Differentiate `push!` with implicit Params by DhairyaLGandhi · Pull Request #992 · FluxML/Zygote.jl · GitHub](https://github.com/FluxML/Zygote.jl/pull/992), but there’s some funkiness going on that nobody has a good grasp on yet. In general though, having `params` work in a gradient context seems an unfortunate accident of history and should probably not have been allowed. 99% of the time, it’s incurring extra computation and allocation unecessarily.

---

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [July 9, 2021, 4:38am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/7 "2021-07-09T04:38:54Z")

</div>

@mcabbot Your workaround works. Thanks a million.

---

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [July 9, 2021, 4:42am UTC](https://discourse.julialang.org/t/weight-regularisation-which-iterates-params-m-in-flux-mutating-arrays-is-not-supported/64314/8 "2021-07-09T04:42:08Z")

</div>

@ToucheSir Thanks for that. I shall copy you into upcoming PR where my issue arose and perhaps you can suggest a more performant approach there, thanks.
