FluxML / Zygote.jl

21st century AD
https://fluxml.ai/Zygote.jl/
Other
1.49k stars 213 forks source link

Training Neural SDEs with Mutating Arrays #1341

Closed Alexio-Phytides closed 1 year ago

Alexio-Phytides commented 1 year ago

I am writing a training function in a similar form to the method of moments one in the neural SDE tutorial in the DiffEqFlux.jl documentation, that requires a loop as my loss is the difference between call prices which I need to calculate for various strikes using a loop. However, this results in a mutating array, how do I get around this?

function predict_neuralsde(p, u = S₀) 
  return Array(Pre_NSDE(u, p)) # Returns an array of stock prices/SDE solutions at each time point. 
end

function loss_neuralsde(p; n = 10000)
u = repeat(reshape(S₀, :, 1), 1, n)
stock = predict_neuralsde(p,u)[1,:,end]

for i = 1:length(K)
NSDE_call[i] = exp(-r*tspan[2]).*mean(maximum([terminal_values .- K[i] zeros(size(terminal_values))], dims = 2))
end 

NSDE_call

loss = sum(abs2, NSDE_call - BS_Price')  
 return loss , NSDE_call  
end  

opt = ADAM(0.025)

adtype = Optimization.AutoZygote()
optf = Optimization.OptimizationFunction((x,p) -> loss_neuralsde(x, n=10000), adtype)
optprob = Optimization.OptimizationProblem(optf, Pre_NSDE.p)
result1 = Optimization.solve(optprob, opt, callback = callback, maxiters = 200)  # 200 iterations of training.

The error message is as follows:

Mutating arrays is not supported -- called setindex!(Matrix{Float64}, ...)
This error occurs when you ask Zygote to differentiate operations that change
the elements of arrays in place (e.g. setting values with x .= ...)
ToucheSir commented 1 year ago

In the interest of keeping the issue tracker for bugs/feature requests and centralizing help in one place, I'm going to close this issue and pick up on your Discourse thread.