【问题标题】:How can I evaluate and take the derivative of a neural net in Julia如何在 Julia 中评估和获取神经网络的导数
【发布时间】:2022-01-16 14:31:41
【问题描述】:

我已经用神经网络求解了一个微分方程。我在下面留下代码示例。我希望能够计算这个神经网络关于其输入“x”的一阶导数,并针对任何“x”评估这个导数。

1- 请注意,我计算了 der = discretize.derivative 。这是神经网络对“x”的导数吗?使用这个表达式,如果我输入 [first(der(phi, u, [x], 0.00001, 1, res.minimizer)) for x in xs] 我会得到一些东西,我想知道它是否是导数,但我找不到在数组中提取它的方法,更不用说绘制它了。如何在任何时候评估这个导数,让我们说下面定义为“xs”的数组中的所有点?在下面的更新中,我给出了一种更直接的方法来尝试计算导数(但仍然没有成功)。

2- 有没有其他方法可以对神经网络的 x 求导?

我是 Julia 的新手,所以我在如何操作数据类型方面有点挣扎。感谢您的任何建议!

更新:我找到了一种查看神经网络符号表达式的方法:

predict(x) = first(phi(x,res.minimizer))
df(x)      = gradient(predict, x)[1]

在 REPL 中运行 predict(x)df(x) 的两行代码后,它将输出带有解决方案权重和偏差的完整神经网络。但是我无法评估梯度,它会吐出一个错误。如何评估函数 predict(x) 的 x 的梯度??

创建神经网络和求解方程的原始代码

using NeuralPDE, Flux, ModelingToolkit, GalacticOptim, Optim, DiffEqFlux
import ModelingToolkit: Interval, infimum, supremum

@parameters x
@variables u(..)

Dx   = Differential(x)
a    = 0.5
eq   = Dx(u(x)) ~ -log(x*a)

# Initial and boundary conditions
bcs  = [u(0.) ~ 0.01]
# Space and time domains
domains           = [x ∈ Interval(0.01,1.0)]
# Neural network
n                 = 15
chain             = FastChain(FastDense(1,n,tanh),FastDense(n,1))
discretization    = PhysicsInformedNN(chain, QuasiRandomTraining(100))
@named pde_system = PDESystem(eq,bcs,domains,[x],[u(x)])
prob              = discretize(pde_system,discretization)

const losses = []
cb = function (p,l)
    push!(losses, l)
    if length(losses)%100==0
        println("Current loss after $(length(losses)) iterations: $(losses[end])")
    end
    return false
end

res  = GalacticOptim.solve(prob, ADAM(0.01); cb = cb, maxiters=300)
prob = remake(prob,u0=res.minimizer)
res  = GalacticOptim.solve(prob,BFGS(); cb = cb, maxiters=1000)
phi  = discretization.phi
der  = discretization.derivative

using Plots

analytic_sol_func(x) = (1.0+log(1/a))*x-x*log(x)
dx                   = 0.05
xs                   = LinRange(0.01,1.0,50)
u_real               = [analytic_sol_func(x) for x in xs]
u_predict            = [first(phi(x,res.minimizer)) for x in xs]
x_plot               = collect(xs)
xconst               = analytic_sol_func(1)*ones(size(xs))
plot(x_plot ,u_real,title = "Solution",linewidth=3)
plot!(x_plot ,u_predict,line =:dashdot,linewidth=2)

【问题讨论】:

  • 用ForwardDiff做网的前向差分
  • 感谢您的建议。有用!我会把结果放在我的帖子里

标签: deep-learning neural-network julia flux.jl differentialequations.jl


【解决方案1】:

我找到的解决方案在于借助 ForwardDiff 对近似值进行微分。

因此,如果神经网络对未知函数的逼近被称为“funcres”,那么我们对其对 x 的导数如下所示。

using ForwardDiff
funcres(x) = first(phi(x,res.minimizer))
dxu        = ForwardDiff.derivative.(funcres, Array(x_plot))
display(plot(x_plot,dxu,title = "Derivative",linewidth=3))

【讨论】:

    猜你喜欢
    • 2013-06-30
    • 2018-04-30
    • 2016-11-04
    • 1970-01-01
    • 2017-04-13
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多