Add jacobian function

This commit is contained in:
baggepinnen 2017-12-08 14:46:12 +01:00
parent 9f5c4dd3e9
commit 385dee9d16
3 changed files with 29 additions and 1 deletions

View File

@ -9,7 +9,7 @@ using Lazy: @forward
export Chain, Dense, RNN, LSTM, Dropout, LayerNorm,
SGD, ADAM, Momentum, Nesterov,
param, params, mapleaves
param, params, mapleaves, jacobian
using NNlib
export σ, relu, leakyrelu, elu, swish, softmax

View File

@ -120,3 +120,22 @@ function throttle(f, timeout; leading=true, trailing=false)
nothing
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

View File

@ -47,3 +47,12 @@ using Flux: throttle
@test a == [1, 3]
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