# Is it possible to unnormalise data in Flux.jl?

**URL:** <https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404>\
**Category:** New to Julia\
**Tags:** flux, machine-learning\
**Created:** [July 10, 2021, 8:53am UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404 "2021-07-10T08:53:07Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [July 10, 2021, 8:53am UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/1 "2021-07-10T08:53:07Z")

</div>

Hi,

I’ve seen a convenient normalisation function in Flux.jl, [Flux.normalise](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.normalise).  
However, what if I want to unnormalise data (recover the original data)? Is there such functionality in Flux.jl?

Thanks.

---

<div class="post-metadata">

**Author:** ![CarloLucibello](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carlolucibello/32/3278_2.png) [@CarloLucibello](https://discourse.julialang.org/u/CarloLucibello)\
**Post date:** [July 10, 2021, 10:50am UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/2 "2021-07-10T10:50:12Z")

</div>

you will have to store the mean and variance by yourself to perform the inverse transform, otherwise that information is lost

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 10, 2021, 11:41am UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/3 "2021-07-10T11:41:19Z")

</div>

Nice thing about Flux is that it works with all julia packages.  
I am surprised it actually has a `normalize` of it’s own.

Something like [StatsBase](https://juliastats.org/StatsBase.jl/stable/transformations/#Standardization-1) can do this.

```julia
julia> using StatsBase

julia> x = randn(10) .+ 5
10-element Vector{Float64}:
 5.964172883616336
 4.116442184696866
 6.605584680364782
 3.519368666428235
 6.201987836586334
 4.446148516233912
 6.684526916570591
 4.791433884353377
 3.683098936166946
 4.955188515988089

julia> t = fit(ZScoreTransform, x)
ZScoreTransform{Float64, Vector{Float64}}(1, 1, [5.0967953021005465], [1.1905029391356516])

julia> px = StatsBase.transform(t, x)
10-element Vector{Float64}:
  0.7285807980831507
 -0.823478115993105
  1.267354601711165
 -1.3250086025134726
  0.9283408701940692
 -0.5465310201913723
  1.3336645902132718
 -0.2564978276902644
 -1.1874782660847485
 -0.11894702772869165

julia> StatsBase.reconstruct
reconstruct reconstruct!
julia> StatsBase.reconstruct(t, px)
10-element Vector{Float64}:
 5.964172883616336
 4.116442184696866
 6.605584680364782
 3.5193686664282353
 6.201987836586334
 4.446148516233912
 6.684526916570591
 4.791433884353377
 3.683098936166946
 4.955188515988089

```

Another option is [FeatureTransforms.jl](https://invenia.github.io/FeatureTransforms.jl/dev/examples/#examples)

```julia
julia> using FeatureTransforms

julia> t = MeanStdScaling(x)
MeanStdScaling(5.0967953021005465, 1.1905029391356516)

julia> xp = FeatureTransforms.apply(x, t)
10-element Vector{Float64}:
  0.7285807980831507
 -0.823478115993105
  1.267354601711165
 -1.3250086025134726
  0.9283408701940692
 -0.5465310201913723
  1.3336645902132718
 -0.2564978276902644
 -1.1874782660847485
 -0.11894702772869165

julia> FeatureTransforms.apply(x, t; inverse=true)
10-element Vector{Float64}:
 12.197160649558949
  9.997431821764149
 12.960763278784253
  9.286614043385278
 12.48028005004014
 10.389948178510636
 13.05474424300921
 10.801011424097393
  9.481535410734686
 10.995961794355594

```

I haven’t actually tested these with Flux.  
They should work, though they might give mutation errors.

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [July 12, 2021, 1:52am UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/4 "2021-07-12T01:52:06Z")

</div>

I’ve tested StatsBase.jl with Flux.jl as you suggested but it does not work properly.  
It seems that StatsBase.jl mutates arrays, which is not supported by Zygote.jl for auto-differentiation.

---

<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 12, 2021, 4:06pm UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/5 "2021-07-12T16:06:10Z")

</div>

Did you try the second package @oxinabox mentioned? FeatureTransforms should be relatively AD-safe since it [doesn’t use mutation at all](https://github.com/invenia/FeatureTransforms.jl/blob/f66d6a4757ab683f9f848cb89b3a8e63b2b3bb36/src/scaling.jl#L73-L80).

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [July 12, 2021, 11:54pm UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/6 "2021-07-12T23:54:54Z")

</div>

Not yet.  
Since the package is relatively young, I thought there is a risk to use it.  
But it would be worth to try it. Thanks 🙂

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 13, 2021, 9:25am UTC](https://discourse.julialang.org/t/is-it-possible-to-unnormalise-data-in-flux-jl/64404/7 "2021-07-13T09:25:26Z")

</div>

> [@iHany](#):
>
> Since the package is relatively young, I thought there is a risk to use it.

NB I work for Invenia, so I am in no way unbiased.  
But you can trust most things we make.  
We do this as a job, we have higher standards than anyone else for continued maintainance.  
That one is being used in like 6+ components of our production system.
