我才刚开始学习朱莉娅。这里是一个在强化学习算法中使用的经验回放记忆的实现。它非常简单,本质上是一个具有以下要求的环形缓冲区:
import Base.length
struct Memory{T <: Real}
max_size::UInt32
experiences::Vector{Vector{T}}
end
Memory{T}(max_size) where {T <: Real} = Memory{T}(max_size, Vector{Vector{T}}())
length(memory::Memory) = length(memory.experiences)
function remember!(memory::Memory, experience)
size = length(memory)
if size == memory.max_size
memory.experiences[1 + size % memory.max_size] = experience
else
push!(memory.experiences, experience)
end
end
function sample(memory::Memory{T}, count::Integer) where {T <: Real}
size = length(memory)
@assert count <= size
return [memory.experiences[1 + rand(UInt32) % size] for i in 1:count]
end发布于 2018-12-09 15:39:29
CircularBuffer中有一个DataStructures类型,它所做的几乎是一样的。看看它的代码,找出一些灵感。或者重用它,如果它符合您的需要,并且您可以毫不犹豫地添加该依赖项。iterate。remember!在语义上是有意义的,但是push!是这个功能的标准名称。您可以根据remember!实现push!并同时导出两者,或者只需使用push!并在文档中提及。StaticVectors。UInt32是否比使用它更容易节省。Int几乎是所有这类东西的标准:长度、索引、偏移等等。experiences预先分配为Vector{T}(undef, max_size),只使用索引(并跟踪实际长度),而不是在DataStructures实现之前使用push!。如果不是,调用sizehint!(experiences, max_size)可能是好的,如果您期望总是耗尽全部容量。sample,而是推荐钩入rand,从而免费获得更多的方法。在最简单的情况下,这只是定义Random.rand(rng::Random.AbstractRNG,s::Random.SamplerTrivial{Memory {T} }),其中{T}= rand( RNG,s[].experiences),它提供了所有的变体:rand(m)、rand(m, N) (对应于您的sample)、rand(rng, m)等等。如果您想要编写可重复的实验,特别是提供RNG的表单是相关的。默认情况下,rand!方法似乎不起作用,但如果需要,可以轻松地添加它们。(如果切换到预分配+索引解决方案,则需要确保只从@view experiences[1:length]中取样。)请注意,您可以使用a直接从数组rand(a)中取样。https://codereview.stackexchange.com/questions/208190
复制相似问题