Add jacobian function
This commit is contained in:
parent
9f5c4dd3e9
commit
385dee9d16
@ -9,7 +9,7 @@ using Lazy: @forward
|
|||||||
|
|
||||||
export Chain, Dense, RNN, LSTM, Dropout, LayerNorm,
|
export Chain, Dense, RNN, LSTM, Dropout, LayerNorm,
|
||||||
SGD, ADAM, Momentum, Nesterov,
|
SGD, ADAM, Momentum, Nesterov,
|
||||||
param, params, mapleaves
|
param, params, mapleaves, jacobian
|
||||||
|
|
||||||
using NNlib
|
using NNlib
|
||||||
export σ, relu, leakyrelu, elu, swish, softmax
|
export σ, relu, leakyrelu, elu, swish, softmax
|
||||||
|
19
src/utils.jl
19
src/utils.jl
@ -120,3 +120,22 @@ function throttle(f, timeout; leading=true, trailing=false)
|
|||||||
nothing
|
nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
J = jacobian(m,x)
|
||||||
|
|
||||||
|
Calculate the output jacobian `J = d/dx m(x)` such that each row `i` of `J` corresponds to the gradient `J[i,:] = ∇ₓ(m(x)[i])`
|
||||||
|
"""
|
||||||
|
function jacobian(m,x)
|
||||||
|
xp = param(x)
|
||||||
|
y = m(xp)
|
||||||
|
k = length(y)
|
||||||
|
n = length(x)
|
||||||
|
J = Matrix{eltype(x)}(n,k)
|
||||||
|
for i = 1:k
|
||||||
|
Flux.back!(y[i]) # Populate gradient accumulator
|
||||||
|
J[:,i] = xp.grad
|
||||||
|
xp.grad .*= 0 # Reset gradient accumulator
|
||||||
|
end
|
||||||
|
J'
|
||||||
|
end
|
||||||
|
@ -47,3 +47,12 @@ using Flux: throttle
|
|||||||
@test a == [1, 3]
|
@test a == [1, 3]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@testset "Jacobian" begin
|
||||||
|
A = param(randn(2,2))
|
||||||
|
x = randn(2)
|
||||||
|
m(x) = A*x
|
||||||
|
y = m(x)
|
||||||
|
J = jacobian(m,x)
|
||||||
|
@test J ≈ A.data
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user