I am trying to index over the last dimension of an array of unknown dimension. Please see the following MWE for a 2-dimensional array:
a = rand(2, 4)
indices = [1:2, 3:4]
colons = repeat([:], ndims(a) - 1)
v = [a[colons..., idx] for idx ∈ indices]
This works as intended:
# Sanity check:
v[1] == a[:, 1:2] # true
v[2] == a[:, 3:4] # true
However, I received an error when using this approach while training a Flux
model:
ERROR: MethodError: no method matching reshape(::Tuple{Nothing}, ::Int64, ::Colon)
Closest candidates are:
reshape(::FillArrays.AbstractFill, ::Union{Colon, Int64}...) at /home/matthew/.julia/packages/FillArrays/Vzxer/src/FillArrays.jl:221
reshape(::FillArrays.AbstractFill, ::Union{Colon, Integer}...) at /home/matthew/.julia/packages/FillArrays/Vzxer/src/FillArrays.jl:222
reshape(::ChainRulesCore.AbstractZero, ::Any...) at /home/matthew/.julia/packages/ChainRulesCore/7OROc/src/tangent_types/abstract_zero.jl:37
...
Stacktrace:
[1] (::Zygote.var"#542#543"{Vector{Colon}})(ȳ::Tuple{Nothing})
@ Zygote ~/.julia/packages/Zygote/l3aNG/src/lib/array.jl:168
[2] (::Zygote.var"#2555#back#544"{Zygote.var"#542#543"{Vector{Colon}}})(Δ::Tuple{Nothing})
@ Zygote ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:67
[3] Pullback
@ ~/Dropbox/SpatialDeepSets/src/DeepSetStruct.jl:163 [inlined]
[4] (::typeof(∂(λ)))(Δ::CuArray{Float32, 2})
@ Zygote ~/.julia/packages/Zygote/l3aNG/src/compiler/interface2.jl:0
[5] Pullback
@ ~/Dropbox/SpatialDeepSets/src/Train.jl:116 [inlined]
[6] (::typeof(∂(λ)))(Δ::Float32)
@ Zygote ~/.julia/packages/Zygote/l3aNG/src/compiler/interface2.jl:0
[7] (::Zygote.var"#90#91"{Params, typeof(∂(λ)), Zygote.Context})(Δ::Float32)
@ Zygote ~/.julia/packages/Zygote/l3aNG/src/compiler/interface.jl:348
[8] gradient(f::Function, args::Params)
@ Zygote ~/.julia/packages/Zygote/l3aNG/src/compiler/interface.jl:76
[9] train(model::DeepSet{Chain{Tuple{Conv{2, 4, typeof(relu), Array{Float32, 4}, Vector{Float32}}, Conv{2, 4, typeof(relu), Array{Float32, 4}, Vector{Float32}}, Conv{2, 4, typeof(relu), Array{Float32, 4}, Vector{Float32}}, typeof(Flux.flatten), Dense{typeof(relu), Matrix{Float32}, Vector{Float32}}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}}}, typeof(mean_over_last_dim), typeof(identity)}, data_simulator::typeof(data_simulator), train_params::ParameterConfigurations, val_params::ParameterConfigurations; run::Int64, save_best_model_only::Bool, args::Args, num_prior_epochs::Int64)
@ Main ~/Dropbox/SpatialDeepSets/src/Train.jl:116
[10] top-level scope
@ ~/Dropbox/SpatialDeepSets/src/GaussianProcess/nuVaried/TrainNF30.jl:31
[11] eval
@ ./boot.jl:360 [inlined]
By hard coding the number of dimensions for a specific case, I have confirmed that it is my above indexing that is causing this error; that is, my code works if I use a[:, idx]
rather than a[colons..., idx]
.
Is there a better way to subset an array with unknown ndims
over its last dimension?