【问题标题】:How to check the input dimensions of a model in Flux.jl?如何检查 Flux.jl 中模型的输入尺寸?
【发布时间】:2021-11-22 17:25:52
【问题描述】:

我有一个正在使用的resnet 模型。我最初使用批量图像训练模型。现在它已经过训练,我想对单个图像(224x224 和 3 个颜色通道)进行推理。但是,当我通过 model(imgs[:, :, :, 2]) 将图像传递给我的模型时,我得到:

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
...
...

供参考,imgs[:, :, :, 2] 给出:

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
...
...

知道我在这里缺少什么吗?模型在推理过程中是否需要与训练时相同的维度?有没有办法检查这个以确保我提供了正确的输入尺寸?

更新:我意识到我需要传入图像的数量(在本例中是一个),所以我这样做了:

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

按预期工作。如果有人对有关检查输入暗淡的原始问题有答案,我将保留此问题。

【问题讨论】:

    标签: julia flux.jl


    【解决方案1】:

    正如您所发现的,NNlib.jl(为 Flux 实现卷积的库)期望输入具有批量维度。如果您正在通过单个图像,则可以填充单个维度。有几种方法可以实现这一点。

    首先,问题:

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

    彩色图像应该是 4D(宽度×高度×颜色/深度×批次)。

    填充批次维度的一个选项是使用索引范围:

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

    如果您将单个图像作为 3D 数组提供,另一种选择是使用 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
    

    我们将要填充的维度作为参数传递给unsqueeze。在我们的例子中,这应该是 x 的最后一个维度(即批次维度),我们可以在 Julia 中使用 ndims(x) 获得它。

    【讨论】:

      【解决方案2】:

      对不起,我真的不是专家,但不是imgs[:, :, :, 2] crates a 3-dimensional tensor的问题吗?也许imgs[:, :, :, 2:2] 会起作用,因为它会生成一个最后一维等于一的四维张量(因为你有一张图像)

      【讨论】:

        【解决方案3】:

        这两个答案都是正确的,真的。一个简单的 reshape(x, size(x)..., 1) 也应该可以解决问题,假设 x 是您在批量索引时获得的 3 维图像张量

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-13
          • 2020-09-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多