绘制函数的梯度逼近

Plotting gradient approximation of a function

我正在尝试使用梯度绘制函数的局部近似值。这是我的代码:

using Random
using LinearAlgebra
using Plots
using LaTeXStrings

Random.seed!(0)
x = rand(5,1)
v = rand(5,1)
alphas = LinRange(-1,1,100)

f(x) = log(sum(exp.(x)))
∇f(x) = (1/log(sum(exp.(x))))*[exp(x[1]),exp(x[2]),exp(x[3]), 
                               exp(x[4]), exp(x[5])]

plot(alphas, [f(x+alpha*v) for alpha in alphas], color = :black,
label = L"f(x + \alpha v)")
plot!(alphas, [f(x) + alpha*dot(∇f(x), v) for alpha in alphas], 
    color=:red, label=L"f(x) + \alpha \nabla f(x)^T v")
xlabel!(L"\alpha")

根据我的理解,红线应该与 alpha = 0 处的曲线相切,但事实并非如此。我希望确定这是我计算梯度的问题,还是我在 Julia 中做的不正确。

有问题的函数是 f(x) = log(Σe^x_i).

您对 ∇f(x) 使用了错误的公式。应该是:

∇f(x) = (ex = exp.(x); ex / sum(ex)) # precalculate exp.(x) to avoid computing it twice

您也可以避免手动计算,例如使用 ForwardDiff.jl 包并编写:

∇f(x) = ForwardDiff.gradient(f, x)