【发布时间】:2020-06-22 20:29:37
【问题描述】:
我正在编写一个脚本,将 Python 的 Keras (v1.1.0) 模型转换为 Julia 的 Flux 模型,并且我正在努力实现正则化(我已阅读 https://fluxml.ai/Flux.jl/stable/models/regularisation/)作为了解 Julia 的一种方式。
所以,在Keras 的 json 模型中,我有类似的内容:"W_regularizer": {"l2": 0.0010000000474974513, "name": "WeightRegularizer", "l1": 0.0} 对应每个 Dense 层。我想使用这些系数在Flux 模型中创建正则化。问题是,在Flux 中,它被直接添加到损失中,而不是被定义为层本身的属性。
为避免在此处发布过多代码,我已将其添加到存储库中。这是一个小脚本,它采用 json 并创建 Flux 的 Chain:https://github.com/iegorval/Keras2Flux.jl/blob/master/Keras2Flux/src/Keras2Flux.jl
现在,我想使用预定义的l1/l2 系数为每个Dense 层创建一个惩罚。我试着这样做:
using Pkg
pkg"activate /home/username/.julia/dev/Keras2Flux"
using Flux
using Keras2Flux
using LinearAlgebra
function get_penalty(model::Chain, regs::Array{Any, 1})
index_model = 1
index_regs = 1
penalties = []
for layer in model
if layer isa Dense
println(regs[index_regs](layer.W))
penalty(m) = regs[index_regs](m[index_model].W)
push!(penalties, penalty)
#println(regs[i])
index_regs += 1
end
index_model += 1
end
total_penalty(m) = sum([p(m) for p in penalties])
println(total_penalty)
println(total_penalty(model))
return total_penalty
end
model, regs = convert_keras2flux("examples/keras_1_1_0.json")
penalty = get_penalty(model, regs)
所以,我为每个Dense 层创建了一个惩罚函数,然后将其相加为总惩罚。但是,它给了我这个错误:
ERROR: LoadError: BoundsError: attempt to access 3-element Array{Any,1} at index [4]
我明白这意味着什么,但我真的不明白如何解决它。因此,似乎当我调用total_penalty(model) 时,它使用index_regs == 4(因此,index_regs 和index_model 的值在for-cycle 之后)。相反,我想使用他们的实际指数,同时将给定的惩罚推到惩罚列表中。
另一方面,如果我不是将其作为函数列表而是作为值列表,那么它也是不正确的,因为我将损失定义为:
loss(x, y) = binarycrossentropy(model(x), y) + total_penalty(model)。如果我只是将它用作值列表,那么我将有一个静态的total_penalty,而在模型训练期间每次都应该为每个Dense 层重新计算它。
如果有 Julia 经验的人给我一些建议,我将不胜感激,因为我肯定无法理解它在 Julia 中是如何工作的,特别是在 Flux 中。如何创建在训练期间自动重新计算的total_penalty?
【问题讨论】: