簡體   English   中英

從均勻分布采樣時沒有方法匹配 logpdf

[英]no method matching logpdf when sampling from uniform distribution

我正在嘗試在 julia 中使用強化學習來教一輛不斷向后加速(但初始速度為正)的汽車應用剎車,以便在向后移動之前盡可能接近目標距離。

為此,我正在使用具有許多求解器的POMDPs.jlcrux.jl (我正在使用 DQN)。 我將首先列出我認為是腳本的相關部分,然后在最后列出更多內容。

為了定義 MDP,我將初始 position、速度和剎車力設置為在某些值上的均勻分布。

@with_kw struct SliderMDP <: MDP{Array{Float32}, Array{Float32}}
        x0 = Distributions.Uniform(0., 80.)# Distribution to sample initial position
        v0 = Distributions.Uniform(0., 25.) # Distribution to sample initial velocity
        d0 = Distributions.Uniform(0., 2.) # Distribution to sample brake force
        ...
end

我的 state 保存的值是(position, velocity, brake force) ,初始 state 給出為:

function POMDPs.initialstate(mdp::SliderMDP)
    ImplicitDistribution((rng) -> Float32.([rand(rng, mdp.x0), rand(rng, mdp.v0), rand(rng, mdp.d0)]))
end

然后,我使用crux.jl設置我的 DQN 求解器並調用 function 來求解策略

solver_dqn = DQN(π=Q_network(), S=s, N=30000)
policy_dqn = solve(solver_dqn, mdp)

調用solve()給我錯誤MethodError: no method matching logpdf(::Distributions.Categorical{Float64, Vector{Float64}}, ::Nothing) 我很確定這來自最初的 state 采樣,但我不確定為什么或如何修復它。 我只是在很短的時間內從各種書籍和在線講座中學習 RL,因此對於錯誤或我設置的 model(或其他我沒有注意到的任何東西)的任何幫助將不勝感激。


更全面的代碼:

套餐:

using POMDPs
using POMDPModelTools
using POMDPPolicies
using POMDPSimulators

using Parameters
using Random

using Crux
using Flux

using Distributions

它的Rest:

@with_kw struct SliderMDP <: MDP{Array{Float32}, Array{Float32}}
    x0 = Distributions.Uniform(0., 80.)# Distribution to sample initial position
    v0 = Distributions.Uniform(0., 25.) # Distribution to sample initial velocity
    d0 = Distributions.Uniform(0., 2.) # Distribution to sample brake force
    
    m::Float64 = 1.
    tension::Float64 = 3.
    dmax::Float64 = 2.
    target::Float64 = 80.
    dt::Float64 = .05
    
    γ::Float32 = 1.
    actions::Vector{Float64} = [-.1, 0., .1]
end
    
function POMDPs.gen(env::SliderMDP, s, a, rng::AbstractRNG = Random.GLOBAL_RNG)
    x, ẋ, d = s

    if x >= env.target
        a = .1
    end
    if d+a >= env.dmax || d+a <= 0
        a = 0.
    end
    
    force = (d + env.tension) * -1
    ẍ = force/env.m
    
    # Simulation
    x_ = x + env.dt * ẋ
    ẋ_ = ẋ + env.dt * ẍ
    d_ = d + a

    sp = vcat(x_, ẋ_, d_)
    reward = abs(env.target - x) * -1
        
    return (sp=sp, r=reward)
end

    

function POMDPs.initialstate(mdp::SliderMDP)
    ImplicitDistribution((rng) -> Float32.([rand(rng, mdp.x0), rand(rng, mdp.v0), rand(rng, mdp.d0)]))
end
    
POMDPs.isterminal(mdp::SliderMDP, s) = s[2] <= 0
POMDPs.discount(mdp::SliderMDP) = mdp.γ

mdp = SliderMDP();
s = state_space(mdp); # Using Crux.jl

function Q_network()
    layer1 = Dense(3, 64, relu)
    layer2 = Dense(64, 64, relu)
    layer3 = Dense(64, length(3))
    return DiscreteNetwork(Chain(layer1, layer2, layer3), [-.1, 0, .1])
end

solver_dqn = DQN(π=Q_network(), S=s, N=30000) # Using Crux.jl
policy_dqn = solve(solver_dqn, mdp) # Error comes here

簡短的回答

將您的 output 向量更改為Float32Float32[-.1, 0, .1]

長答案

Crux 在您的網絡的 output 值上創建一個Distribution ,並在某些時候 (policies.jl:298) 從中采樣一個隨機值。 然后它將這個值轉換為Float32 后來 (utils.jl:15) 它執行findfirst以在原始 output 數組(在分發中存儲為objs )中找到此值的索引,但由於原始數組仍然是Float64 ,因此失敗並返回nothing 因此錯誤。

我相信這(轉換采樣值而不是objs數組)是一個錯誤,並鼓勵您在 Github 上將此作為問題提出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM