【发布时间】:2020-05-03 18:07:09
【问题描述】:
我正在尝试在损失函数中使用分位数进行训练! (对于某些稳健性,例如最小修剪平方),但它会改变数组并且 Zygote 会抛出来自 sort! 的错误 Mutating arrays is not supported。下面是一个简单的例子(内容当然没有意义):
using Flux, StatsBase
xdata = randn(2, 100)
ydata = randn(100)
model = Chain(Dense(2,10), Dense(10, 1))
function trimmedLoss(x,y; trimFrac=0.f05)
yhat = model(x)
absRes = abs.(yhat .- y) |> vec
trimVal = quantile(absRes, 1.f0-trimFrac)
s = sum(ifelse.(absRes .> trimVal, 0.f0 , absRes ))/(length(absRes)*(1.f0-trimFrac))
#s = sum(absRes)/length(absRes) # using this and commenting out the two above works (no surprise)
end
println(trimmedLoss(xdata, ydata)) #works ok
Flux.train!(trimmedLoss, params(model), zip([xdata], [ydata]), ADAM())
println(trimmedLoss(xdata, ydata)) #changed loss?
这一切都在 Flux 0.10 和 Julia 1.2 中
提前感谢任何提示或解决方法!
【问题讨论】:
-
这不是像教科书中的不可微损失函数示例吗?如果是这样,我已经看到了一些用无梯度优化器训练 Flux NN 的 hacky 代码,但我手头没有。
-
或许你可以把问题分解成一个可微的损失和投影到一个凸集上,然后实现一个投影梯度法? OTOH,我不确定这是否明智,因为无论如何损失都不会是凸的......
-
是的,当然严格来说它是不可微的。但是,启发式地,它与其他优化器(Levenberg-Marq 等)一起工作得很好,特别是当修剪的分数很小时。使用随机梯度下降,恕我直言,它甚至应该更不重要。它在早期版本的 Flux 中工作,没有 Zygote。
标签: machine-learning julia flux.jl