【问题标题】:LoadError: MethodError while training LSTM model in JuliaLoadError:在 Julia 中训练 LSTM 模型时出现 MethodError
【发布时间】:2021-12-29 17:33:49
【问题描述】:

我正在尝试训练 LSTM 模型来预测多项式的实根数。 x_train 和 y_train 包括数组数组,例如[[-204, 20, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],它们是多项式的系数。 x_test 和 y_test 包括每个多项式的实根数,例如 1,2,5...

这是我的代码和错误信息:

using Flux: @epochs, throttle
using Flux

function input()
    ## x_train
    lines = Tuple(readlines("/home/user/Desktop/train_x_data.txt"))
    x_train = []

    for i in lines
        push!(x_train, convert(Vector{Float32},eval(Meta.parse(i))))
    end

    ## y_train
    lines = Tuple(readlines("/home/user/Desktop/train_y_data.txt"))
    y_train = []

    for i in lines
        push!(y_train, eval(Meta.parse(i)))
    end
    
    y_train = convert(Vector{Float32}, y_train)

    ## x_test
    lines = Tuple(readlines("/home/user/Desktop/test_x_data.txt"))
    x_test = []

    for i in lines
        push!(x_test, convert(Vector{Float32},eval(Meta.parse(i))))
    end


    ## y_test
    lines = Tuple(readlines("/home/user/Desktop/test_y_data.txt"))
    y_test = []

    for i in lines
        push!(y_test, eval(Meta.parse(i)))
    end
    
    y_test = convert(Vector{Float32}, y_test)

    return x_train, x_test, y_train, y_test
end

function LSTM_model(N,num_of_classes)
    scanner = Chain(LSTM(N,200),
                Dropout(0.2),
                LSTM(200,200),
                Dropout(0.1),
                Dense(200,101),
                Dropout(0.1))
    encoder = Dense(101,num_of_classes)
    return scanner, encoder
end

function model(x, scanner, encoder)
    state = scanner.(x)[end]
    reset!(scanner)
    encoder(state)
end

function main()
    num_of_classes = 101
    num_epochs = 50

    x_train, x_test, y_train, y_test = input()

    
    N = size(x_train)[1]
    scanner, encoder = LSTM_model(N,num_of_classes)

    loss(x, y)=  (model(x, scanner, encoder) - y)^2
    ps = Flux.params(scanner,encoder)

    # use the ADAM optimizer. It's a pretty good one!
    opt = Flux.ADAM(0.001)

    evalcb = () -> @show testloss()
    @info("Training...")
    Flux.train!(loss, ps, zip(x_train, y_train), opt, cb = throttle(evalcb, 10))
    
end

main()

错误:

ERROR: LoadError: MethodError: no method matching (::Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}})(::Tuple{Matrix{Float32}, Matrix{Float32}}, ::Float32)
Closest candidates are:
  (::Flux.LSTMCell{A, V, <:Tuple{AbstractMatrix{T}, AbstractMatrix{T}}})(::Any, ::Union{AbstractVector{T}, AbstractMatrix{T}, Flux.OneHotArray}) where {A, V, T} at ~/.julia/packages/Flux/BPPNj/src/layers/recurrent.jl:157
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0 [inlined]
  [2] _pullback(::Zygote.Context, ::Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, ::Tuple{Matrix{Float32}, Matrix{Float32}}, ::Float32)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:9
  [3] _pullback
    @ ~/.julia/packages/Flux/BPPNj/src/layers/recurrent.jl:47 [inlined]
  [4] _pullback(ctx::Zygote.Context, f::Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, args::Float32)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0
  [5] _pullback
    @ ~/.julia/packages/Flux/BPPNj/src/layers/basic.jl:47 [inlined]
  [6] _pullback(::Zygote.Context, ::typeof(Flux.applychain), ::Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}, ::Float32)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0
  [7] _pullback
    @ ~/.julia/packages/Flux/BPPNj/src/layers/basic.jl:49 [inlined]
  [8] _pullback(ctx::Zygote.Context, f::Chain{Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}}, args::Float32)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0
  [9] #1099
    @ ~/.julia/packages/Zygote/umM0L/src/lib/broadcast.jl:186 [inlined]
 [10] _broadcast_getindex_evalf
    @ ./broadcast.jl:670 [inlined]
 [11] _broadcast_getindex
    @ ./broadcast.jl:643 [inlined]
 [12] getindex
    @ ./broadcast.jl:597 [inlined]
 [13] copy
    @ ./broadcast.jl:899 [inlined]
 [14] materialize
    @ ./broadcast.jl:860 [inlined]
 [15] _broadcast(f::Zygote.var"#1099#1103"{Zygote.Context, Chain{Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}}}, x::Vector{Float32})
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/lib/broadcast.jl:163
 [16] adjoint
    @ ~/.julia/packages/Zygote/umM0L/src/lib/broadcast.jl:186 [inlined]
 [17] _pullback(__context__::Zygote.Context, 680::typeof(Base.Broadcast.broadcasted), 681::Base.Broadcast.DefaultArrayStyle{1}, f::Chain{Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}}, args::Vector{Float32})
    @ Zygote ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65
 [18] _apply(::Function, ::Vararg{Any})
    @ Core ./boot.jl:814
 [19] adjoint
    @ ~/.julia/packages/Zygote/umM0L/src/lib/lib.jl:200 [inlined]
 [20] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [21] _pullback
    @ ./broadcast.jl:1297 [inlined]
 [22] _pullback
    @ ~/Desktop/lstm_model.jl:82 [inlined]
 [23] _pullback(::Zygote.Context, ::typeof(model), ::Vector{Float32}, ::Chain{Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}}, ::Dense{typeof(identity), Matrix{Float32}, Vector{Float32}})
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0
 [24] _pullback
    @ ~/Desktop/lstm_model.jl:108 [inlined]
 [25] _pullback(::Zygote.Context, ::var"#loss#2"{Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Chain{Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}}}, ::Vector{Float32}, ::Float32)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0
 [26] _apply(::Function, ::Vararg{Any})
    @ Core ./boot.jl:814
 [27] adjoint
    @ ~/.julia/packages/Zygote/umM0L/src/lib/lib.jl:200 [inlined]
 [28] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [29] _pullback
    @ ~/.julia/packages/Flux/BPPNj/src/optimise/train.jl:105 [inlined]
 [30] _pullback(::Zygote.Context, ::Flux.Optimise.var"#39#45"{var"#loss#2"{Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Chain{Tuple{Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Flux.Recur{Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Tuple{Matrix{Float32}, Matrix{Float32}}}, Dropout{Float64, Colon}, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Dropout{Float64, Colon}}}}, Tuple{Vector{Float32}, Float32}})
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface2.jl:0
 [31] pullback(f::Function, ps::Zygote.Params)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface.jl:352
 [32] gradient(f::Function, args::Zygote.Params)
    @ Zygote ~/.julia/packages/Zygote/umM0L/src/compiler/interface.jl:75
 [33] macro expansion
    @ ~/.julia/packages/Flux/BPPNj/src/optimise/train.jl:104 [inlined]
 [34] macro expansion
    @ ~/.julia/packages/Juno/n6wyj/src/progress.jl:134 [inlined]
 [35] train!(loss::Function, ps::Zygote.Params, data::Base.Iterators.Zip{Tuple{Vector{Any}, Vector{Float32}}}, opt::ADAM; cb::Flux.var"#throttled#72"{Flux.var"#throttled#68#73"{Bool, Bool, var"#1#3", Int64}})
    @ Flux.Optimise ~/.julia/packages/Flux/BPPNj/src/optimise/train.jl:102
 [36] main()
    @ Main ~/Desktop/lstm_model.jl:116
 [37] top-level scope
    @ ~/Desktop/lstm_model.jl:120
in expression starting at /home/user/Desktop/lstm_model.jl:120

【问题讨论】:

  • 完整的错误信息是什么?
  • 我添加到问题@ForceBru

标签: machine-learning julia lstm recurrent-neural-network flux.jl


【解决方案1】:

AFAIK,这个:

(::Flux.LSTMCell{Matrix{Float32}, Vector{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}}})(
    ::Tuple{Matrix{Float32}, Matrix{Float32}}, ::Float32
)

...表示您尝试在单个 Float32 而不是向量上调用模型。

您的代码在model 函数中显示state = scanner.(x)[end],因此,如果xVector{Float32}scanner.(x) 确实会尝试将scanner 应用于每个值,这是不受支持的(IMO,应该支持它只是为了更容易在一维数据上运行模型,但是嘿,我不设计 ML 库,所以也许当前的实现......更好?)。

  1. x_trainVector{Vector{Float32}}
  2. zip(x_train, y_train) 在对Flux.train! 的调用中迭代元组(x_train[i], y_train[i]),因此是Tuple{Vector{Float32}, Float32} 类型的元组
  3. 因此,train! 将调用loss(x_train[i], y_train[i]),因为"For each datapoint d in data ... If d is a tuple of arguments to loss call loss(d...)"
  4. 因此,对loss 的调用中的x 将是x_train[i]::Vector{Float32}
  5. 最后,model 将使用该单个向量调用,scanner.(x) 将应用 scanner,即您的 LSTM,应用于您的 Float32 的每个 Float32

另外,Flux 的 documentation 建议不要在 LSTM 中使用广播和矢量化:

不鼓励使用有状态层的映射和广播操作,因为 julia 语言不保证特定的执行顺序。因此,避免[向量化]并使用显式循环:

y = [m(x) for x in x]

【讨论】:

  • 非常感谢您的回答,我正在尝试修复错误
猜你喜欢
  • 1970-01-01
  • 2022-07-31
  • 2022-10-22
  • 2020-03-08
  • 2023-03-03
  • 2018-01-30
  • 1970-01-01
  • 2021-05-18
  • 1970-01-01
相关资源
最近更新 更多