# What does passing a vector as `dims` to `Statistics.std` mean?

I have been trying to use the `std` function on a batch of images. For instance, this is a batch of 2 images having 3 channels each -

``````xs = rand(3, 3, 3, 2)
``````

I want to find the standard deviation of the first image which can be achieved using -

``````std(xs[:, :, :, 1])
``````

Now I want to achieve the same thing using the `dims` kwarg, but I cannot figure out the usage of the same. More precisely, what is the function actually calculating if I pass in a vector as dims? I couldn’t find any examples of this on the internet or in Julia’s documentation. An example with the batch of images defined above -

``````julia> xs
3×3×3×2 Array{Float64, 4}:
[:, :, 1, 1] =
0.775483  0.804976  0.805342
0.502332  0.571661  0.788025
0.627064  0.175482  0.733361

[:, :, 2, 1] =
0.744905  0.861811  0.236851
0.493482  0.672934  0.954064
0.382317  0.368025  0.0896878

[:, :, 3, 1] =
0.287127  0.505461  0.280565
0.637652  0.07373   0.132018
0.493528  0.173168  0.0917483

[:, :, 1, 2] =
0.993559  0.85186   0.974956
0.962802  0.20569   0.171647
0.344311  0.158447  0.0416952

[:, :, 2, 2] =
0.0756434   0.800149  0.0489549
0.868386    0.197549  0.56844
0.00663242  0.131731  0.614948

[:, :, 3, 2] =
0.154051   0.93772    0.143768
0.196975   0.0213649  0.0269268
0.0658219  0.913233   0.179747

julia> std(xs, dims=[3,1])
1×3×1×2 Array{Float64, 4}:
[:, :, 1, 1] =
0.16137  0.287385  0.354948

[:, :, 1, 2] =
0.412971  0.39161  0.332775
``````

Could someone please explain to me how is the final `1x3x1x2` Array has been calculated? Thank you!

`dims` is used to specify on which dimensions you want to calculate the `std` on…
Let’s say for example we have two 3-channel images of size (4, 4) as below →

``````julia> using Statistics

# two 3-channel images of size (4, 4)
julia> xs = rand(3, 4, 4, 2)
3×4×4×2 Array{Float64, 4}:
[:, :, 1, 1] =
0.638898  0.0607577   0.248664  0.134614
0.359026  0.045089    0.934976  0.208916
0.574276  0.00640597  0.916209  0.146101

[:, :, 2, 1] =
0.337945    0.385004  0.941823  0.879369
0.00222145  0.191058  0.53481   0.513988
0.760298    0.589457  0.286568  0.510345

[:, :, 3, 1] =
0.815596  0.157969  0.623036  0.0807889
0.557733  0.813058  0.474988  0.159235
0.893057  0.386838  0.570377  0.518802

[:, :, 4, 1] =
0.104052  0.380098  0.268024   0.578795
0.413343  0.998084  0.449842   0.224211
0.864892  0.808143  0.0459052  0.457739

[:, :, 1, 2] =
0.24586   0.870185   0.770928  0.31385
0.3981    0.391596   0.845867  0.146243
0.114382  0.0579019  0.247182  0.0315621

[:, :, 2, 2] =
0.306497  0.418139    0.713051  0.87407
0.14916   0.302198    0.621749  0.0677304
0.753772  0.00230659  0.938192  0.106774

[:, :, 3, 2] =
0.624643  0.598719   0.160968   0.766046
0.755545  0.0378673  0.397636   0.86422
0.809038  0.915949   0.0150156  0.0320573

[:, :, 4, 2] =
0.128597  0.0363205  0.862884  0.957192
0.646652  0.159509   0.553012  0.71586
0.5693    0.270781   0.950244  0.844724

# std on over all numbers (on all dims)
julia> std(xs, dims=[1, 2, 3, 4])
1×1×1×1 Array{Float64, 4}:
[:, :, 1, 1] =
0.308191790621495
# we will just get a single number, preserving input shape (x, x, x, x)

# std on batch dimension (i.e, last dim), we specify 1st 3 dims to calc std on
julia> std(xs, dims=[1, 2, 3])
1×1×1×2 Array{Float64, 4}:
[:, :, 1, 1] =
0.29192537121237955

[:, :, 1, 2] =
0.32666112721755525
# we will just get two numbers, each for one image

# std on channel dimension (i.e, first dim), we specify last 3 dims to calc std on
julia> std(xs, dims=[2, 3, 4])
3×1×1×1 Array{Float64, 4}:
[:, :, 1, 1] =
0.30341597287159655
0.2841992921298127
0.34238183603676203
# we will just get three numbers, each for one channel
``````

Input shape will be preserved in outputs, IMO there is no real benefit of thinking in terms of output dim, rather we can just think of it as numbers with `length` == `dim length you wanted the output to be on`.

1 Like

Thank you for the detailed explanation and the examples! I have been using the `WHCN` format for images (as used by `Flux`) and tweaking your examples just by a tiny bit did the trick. Additionally, I discovered that the dims can also be specified like this -

``````julia> std(xs, dims=1:3)
``````
1 Like

That’s cool ! 1 Like