I am trying to take the second derivative of a custom neural network like this,
icnn = ICNN(1, [32, 32], soft_relu(0.1))
function df(x)
gradient(y->sum(icnn(y)), x)[1]
end
df([1])
gradient(y->sum(df(y)), [1])
This worked well for the first derivative. However, for the second derivative I get: Can’t differentiate foreigncall expression
Here, icnn is simply some custom neural network implemented as follows,
# soft ReLU
function soft_relu(d)
x -> max.(clamp.(sign.(x) .* 1/(2*d) .* x.^2, 0, d/2), x .- d/2)
end
################################################################################
# Input Convex Neural Network (ICNN)
struct ICNN
Ws
Us
bs
act
end
# constructor
ICNN(input_dim::Integer, layer_sizes::Vector, activation) = begin
Ws = []
Us = []
bs = []
push!(Ws, randn(layer_sizes[1], input_dim))
push!(bs, randn(layer_sizes[1]))
i = 1
for out in layer_sizes[2:end]
push!(Us, randn(out, input_dim))
push!(Ws, randn(out, layer_sizes[i]))
push!(bs, randn(out))
i += 1
end
push!(Us, randn(1, input_dim))
push!(Ws, randn(1, layer_sizes[end]))
push!(bs, randn(1))
ICNN(Ws, Us, bs, activation)
end
# forward pass
(m::ICNN)(x) = begin
z = m.act(m.Ws[1]*x + m.bs[1])
for i in 1:length(m.Us)
z = m.act(m.Ws[i+1]*z + m.Us[i]*x + m.bs[i+1])
end
return z
end
Is it possible to take 2nd derivatives and is there any best practice to work with nested gradients?
Thanks in advance for your help!