Como verificar a entrada de dimensões de um modelo de Fluxo.jl?

0

Pergunta

Eu tenho um resnet o modelo que estou trabalhando. Originalmente, eu treinou o modelo usando lotes de imagens. Agora que ele é treinado, eu quero fazer inferência em uma única imagem (224x224 com 3 canais de cores). No entanto, quando eu passar a imagem para o meu modelo, através de model(imgs[:, :, :, 2]) Eu recebo:

DimensionMismatch("Rank of x and w must match! (3 vs. 4)")

Stacktrace:
  [1] DenseConvDims(x::Array{Float32, 3}, w::Array{Float32, 4}; kwargs::Base.Iterators.Pairs{Symbol, Any, NTuple{4, Symbol}, NamedTuple{(:stride, :padding, :dilation, :groups), Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Int64}}})
    @ NNlib ~/.julia/packages/NNlib/P9BhZ/src/dim_helpers/DenseConvDims.jl:58
  [2] (::Conv{2, 2, typeof(identity), Array{Float32, 4}, Vector{Float32}})(x::Array{Float32, 3})
    @ Flux ~/.julia/packages/Flux/ZnXxS/src/layers/conv.jl:162
...
...

Para referência, imgs[:, :, :, 2] dá:

224×224×3 Array{Float32, 3}:
[:, :, 1] =
 0.4       0.419608  0.482353  0.490196  …  0.623529  0.611765  0.627451
 0.423529  0.478431  0.513726  0.486275     0.65098   0.65098   0.65098
 0.419608  0.47451   0.541176  0.54902      0.682353  0.670588  0.639216
 0.52549   0.529412  0.568627  0.564706     0.588235  0.592157  0.572549
 0.556863  0.541176  0.513726  0.505882     0.603922  0.635294  0.654902
 0.486275  0.490196  0.521569  0.537255  …  0.635294  0.654902  0.65098
 0.529412  0.513726  0.533333  0.537255     0.603922  0.596078  0.596078
 0.521569  0.52549   0.505882  0.513726     0.580392  0.576471  0.572549
...
...

Alguma idéia do que eu estou faltando aqui? O modelo de exigir as mesmas dimensões durante a inferência de que ele foi treinado na? Existe uma maneira de verificar isso para se certificar de que eu estou dando a entrada correcta dimensões?

Update: eu percebi que eu precisa passar o número de imagens (que neste caso é um), então eu fiz:

img1 = cat(imgs[:, :, :, 1]; dims = ndims(imgs[:, :, :, 1]) + 1 )
img1
model(img1)

o que funciona conforme o esperado. Vou deixar esta questão em aberto, se alguém tem uma resposta para as perguntas original sobre a verificação de entrada, são obscurecidas.

flux.jl julia
2021-11-22 17:25:52
3

Melhor resposta

4

Como você descobriu, NNlib.jl (a biblioteca que implementa convolução de Fluxo) espera que a entrada para ter o lote dimensão. Se você está passando por uma única imagem, que você pode preencher um singleton dimensão. Existem várias formas de o conseguir.

Primeiro, o problema:

julia> size(x[:, :, :, 1])
(3, 3, 16)

Uma imagem de cor deve ser 4D (largura por altura por cor/profundidade por lote).

Uma opção para preencher um lote dimensão é a utilização de um intervalo para o índice:

julia> size(x[:, :, :, 1:1])
(3, 3, 16, 1)

Outra opção, se você é dado uma única imagem como uma matriz 3D é usar Flux.unsqueeze:

julia> size(Flux.unsqueeze(x[:, :, :, 1], ndims(x)))
(3, 3, 16, 1)

julia> all(Flux.unsqueeze(x[:, :, :, 1], ndims(x)) .== x[:, :, :, 1])
true

Passamos unsqueeze a dimensão queremos pad como um argumento. No nosso caso, esta deve ser a última dimensão do x (i.e. o lote dimensão) que podemos obter em Julia com ndims(x).

2021-11-22 18:25:51
4

Desculpe, eu estou realmente não é um especialista, mas não é o problema que imgs[:, :, :, 2] caixotes de um 3-dimensional tensor? Pode-ser imgs[:, :, :, 2:2] iria trabalhar, como se faz um quatro dimensões tensor com a última dimensão igual a um (desde que você tenha uma imagem)

2021-11-22 18:23:47
3

Ambas as respostas estão corretas, realmente. Um simples reshape(x, size(x)..., 1) deve fazer o truque também, supondo que x é a 3 dimensões da imagem do tensor de você chegar em indexação em lote

2021-11-22 18:41:39

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................