Skip to content

Commit 312d685

Browse files
authored
Updated sciml_train information. (#500)
* Updated sciml_train information. * Replaced sciml_train with GalacticOptim
1 parent d23fa12 commit 312d685

File tree

8 files changed

+244
-364
lines changed

8 files changed

+244
-364
lines changed

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
33

44
[compat]
5-
Documenter = "0.24.2"
5+
Documenter = "0.26.1"

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ makedocs(
7474
"FastChain" => "FastChain.md",
7575
"Smoothed Collocation" => "Collocation.md",
7676
"GPUs" => "GPUs.md",
77-
"sciml_train" => "Scimltrain.md",
77+
"GalacticOptim.jl" => "GalacticOptim.md",
7878

7979
],
8080
"Benchmarks" => "Benchmark.md"

docs/src/GalacticOptim.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# GalacticOptim.jl
2+
3+
*Important:* Please note that `sciml_train` has now been replaced by
4+
[GalacticOptim.jl](https://github.com/SciML/GalacticOptim.jl). The conversion to
5+
GalacitcOptim.jl-style should not pose too many problems! Consult
6+
[this](https://diffeqflux.sciml.ai/dev/examples/neural_ode_sciml/) tutorial
7+
to see how an optimization problem can be set up and/or also read the updated
8+
[GalacticOptim.jl documentation](https://galacticoptim.sciml.ai/stable/)
9+
to explore more options in detail.
10+
11+
GalacticOptim.jl is a package with a scope that is beyond your normal global optimization
12+
package. GalacticOptim.jl seeks to bring together all of the optimization packages
13+
it can find, local and global, into one unified Julia interface. This means, you
14+
learn one package and you learn them all! GalacticOptim.jl adds a few high-level
15+
features, such as integrating with automatic differentiation, to make its usage
16+
fairly simple for most cases, while allowing all of the options in a single
17+
unified interface.
18+
19+
##### Note: This package is still in active development.
20+
21+
## Installation
22+
23+
Assuming that you already have Julia correctly installed, it suffices to import
24+
GalacticOptim.jl in the standard way:
25+
26+
```julia
27+
import Pkg; Pkg.add("GalacticOptim")
28+
```
29+
The packages relevant to the core functionality of GalacticOptim.jl will be imported
30+
accordingly and, in most cases, you do not have to worry about the manual
31+
installation of dependencies. Below is the list of packages that need to be
32+
installed explicitly if you intend to use the specific optimization algorithms
33+
offered by them:
34+
35+
- [BlackBoxOptim.jl](https://github.com/robertfeldt/BlackBoxOptim.jl) (solver: `BBO()`)
36+
- [NLopt.jl](https://github.com/JuliaOpt/NLopt.jl) (usage via the NLopt API;
37+
see also the available [algorithms](https://nlopt.readthedocs.io/en/latest/NLopt_Algorithms/))
38+
- [MultistartOptimization.jl](https://github.com/tpapp/MultistartOptimization.jl)
39+
(see also [this documentation](https://juliahub.com/docs/MultistartOptimization/cVZvi/0.1.0/))
40+
- [QuadDIRECT.jl](https://github.com/timholy/QuadDIRECT.jl)
41+
- [Evolutionary.jl](https://github.com/wildart/Evolutionary.jl) (see also [this documentation](https://wildart.github.io/Evolutionary.jl/dev/))
42+
- [CMAEvolutionStrategy.jl](https://github.com/jbrea/CMAEvolutionStrategy.jl)
43+
44+
## Tutorials and Documentation
45+
46+
For information on using the package,
47+
[see the stable documentation](https://galacticoptim.sciml.ai/stable/). Use the
48+
[in-development documentation](https://galacticoptim.sciml.ai/dev/) for the version of
49+
the documentation, which contains the unreleased features.
50+
51+
## Examples
52+
53+
```julia
54+
using GalacticOptim, Optim
55+
rosenbrock(x,p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
56+
x0 = zeros(2)
57+
p = [1.0,100.0]
58+
59+
prob = OptimizationProblem(rosenbrock,x0,p)
60+
sol = solve(prob,NelderMead())
61+
62+
63+
using BlackBoxOptim
64+
prob = OptimizationProblem(rosenbrock, x0, p, lb = [-1.0,-1.0], ub = [1.0,1.0])
65+
sol = solve(prob,BBO())
66+
```
67+
68+
Note that Optim.jl is a core dependency of GalaticOptim.jl. However, BlackBoxOptim.jl
69+
is not and must already be installed (see the list above).
70+
71+
The output of the first optimization task (with the `NelderMead()` algorithm)
72+
is given below:
73+
74+
```julia
75+
* Status: success
76+
77+
* Candidate solution
78+
Final objective value: 3.525527e-09
79+
80+
* Found with
81+
Algorithm: Nelder-Mead
82+
83+
* Convergence measures
84+
(Σ(yᵢ-ȳ)²)/n 1.0e-08
85+
86+
* Work counters
87+
Seconds run: 0 (vs limit Inf)
88+
Iterations: 60
89+
f(x) calls: 118
90+
```
91+
We can also explore other methods in a similar way:
92+
93+
```julia
94+
f = OptimizationFunction(rosenbrock, GalacticOptim.AutoForwardDiff())
95+
prob = OptimizationProblem(f, x0, p)
96+
sol = solve(prob,BFGS())
97+
```
98+
For instance, the above optimization task produces the following output:
99+
100+
```julia
101+
* Status: success
102+
103+
* Candidate solution
104+
Final objective value: 7.645684e-21
105+
106+
* Found with
107+
Algorithm: BFGS
108+
109+
* Convergence measures
110+
|x - x'| = 3.48e-07 0.0e+00
111+
|x - x'|/|x'| = 3.48e-07 0.0e+00
112+
|f(x) - f(x')| = 6.91e-14 0.0e+00
113+
|f(x) - f(x')|/|f(x')| = 9.03e+06 0.0e+00
114+
|g(x)| = 2.32e-09 1.0e-08
115+
116+
* Work counters
117+
Seconds run: 0 (vs limit Inf)
118+
Iterations: 16
119+
f(x) calls: 53
120+
∇f(x) calls: 53
121+
```
122+
123+
```julia
124+
prob = OptimizationProblem(f, x0, p, lb = [-1.0,-1.0], ub = [1.0,1.0])
125+
sol = solve(prob, Fminbox(GradientDescent()))
126+
```
127+
The examples clearly demonstrate that GalacticOptim.jl provides an intuitive
128+
way of specifying optimization tasks and offers a relatively
129+
easy access to a wide range of optimization algorithms.

docs/src/Scimltrain.md

Lines changed: 0 additions & 63 deletions
This file was deleted.

docs/src/examples/neural_ode_sciml.md

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
# Neural Ordinary Differential Equations with sciml_train
1+
# Neural Ordinary Differential Equations with GalacticOptim.jl
22

33
We can use DiffEqFlux.jl to define, solve, and train neural ordinary
44
differential equations. A neural ODE is an ODE where a neural network defines
55
its derivative function. Thus for example, with the multilayer perceptron neural
6-
network `Chain(Dense(2, 50, tanh), Dense(50, 2))`,
6+
network `Chain(Dense(2, 50, tanh), Dense(50, 2))`, we obtain the following results.
77

88
## Copy-Pasteable Code
99

10-
Before getting to the explanation, here's some code to start with. We will follow
11-
wil a full explanation of the definition and training process:
10+
Before getting to the explanation, here's some code to start with. We will
11+
follow a full explanation of the definition and training process:
1212

1313
```julia
14-
using DiffEqFlux, OrdinaryDiffEq, Flux, Optim, Plots
14+
using DiffEqFlux, OrdinaryDiffEq, Flux, Optim, Plots, GalacticOptim
1515

1616
u0 = Float32[2.0; 0.0]
1717
datasize = 30
@@ -52,15 +52,24 @@ callback = function (p, l, pred; doplot = true)
5252
return false
5353
end
5454

55-
result_neuralode = DiffEqFlux.sciml_train(loss_neuralode, prob_neuralode.p,
56-
ADAM(0.05), cb = callback,
57-
maxiters = 300)
55+
# use GalacticOptim.jl to solve the problem
56+
adtype = GalacticOptim.AutoZygote()
57+
58+
optf = GalacticOptim.OptimizationFunction((x, p) -> loss_neuralode(x), adtype)
59+
optfunc = GalacticOptim.instantiate_function(optf, prob_neuralode.p, adtype, nothing)
60+
optprob = GalacticOptim.OptimizationProblem(optfunc, prob_neuralode.p)
61+
62+
result_neuralode = GalacticOptim.solve(optprob,
63+
ADAM(0.05),
64+
cb = callback,
65+
maxiters = 300)
66+
67+
optprob2 = remake(optprob,u0 = result_neuralode.minimizer)
5868

59-
result_neuralode2 = DiffEqFlux.sciml_train(loss_neuralode,
60-
result_neuralode.minimizer,
61-
LBFGS(),
62-
cb = callback,
63-
allow_f_increases = false)
69+
result_neuralode2 = GalacticOptim.solve(optprob2,
70+
LBFGS(),
71+
cb = callback,
72+
allow_f_increases = false)
6473
```
6574

6675
![Neural ODE](https://user-images.githubusercontent.com/1814174/88589293-e8207f80-d026-11ea-86e2-8a3feb8252ca.gif)
@@ -147,15 +156,25 @@ We then train the neural network to learn the ODE.
147156
Here we showcase starting the optimization with `ADAM` to more quickly find a
148157
minimum, and then honing in on the minimum by using `LBFGS`. By using the two
149158
together, we are able to fit the neural ODE in 9 seconds! (Note, the timing
150-
commented out the plotting).
159+
commented out the plotting). You can easily incorporate the procedure below to
160+
set up custom optimization problems. For more information on the usage of
161+
[GalacticOptim.jl](https://github.com/SciML/GalacticOptim.jl), please consult
162+
[this](https://galacticoptim.sciml.ai/stable/) documentation.
151163

152164
```julia
153165
# Train using the ADAM optimizer
154-
result_neuralode = DiffEqFlux.sciml_train(loss_neuralode, prob_neuralode.p,
155-
ADAM(0.05), cb = callback,
156-
maxiters = 300)
166+
adtype = GalacticOptim.AutoZygote()
157167

158-
* Status: failure (reached maximum number of iterations)
168+
optf = GalacticOptim.OptimizationFunction((x, p) -> loss_neuralode(x), adtype)
169+
optfunc = GalacticOptim.instantiate_function(optf, prob_neuralode.p, adtype, nothing)
170+
optprob = GalacticOptim.OptimizationProblem(optfunc, prob_neuralode.p)
171+
172+
result_neuralode = GalacticOptim.solve(optprob,
173+
ADAM(0.05),
174+
cb = callback,
175+
maxiters = 300)
176+
# output
177+
* Status: success
159178

160179
* Candidate solution
161180
Minimizer: [4.38e-01, -6.02e-01, 4.98e-01, ...]
@@ -164,19 +183,6 @@ result_neuralode = DiffEqFlux.sciml_train(loss_neuralode, prob_neuralode.p,
164183
* Found with
165184
Algorithm: ADAM
166185
Initial Point: [-3.02e-02, -5.40e-02, 2.78e-01, ...]
167-
168-
* Convergence measures
169-
|x - x'| = NaN 0.0e+00
170-
|x - x'|/|x'| = NaN 0.0e+00
171-
|f(x) - f(x')| = NaN 0.0e+00
172-
|f(x) - f(x')|/|f(x')| = NaN 0.0e+00
173-
|g(x)| = NaN 0.0e+00
174-
175-
* Work counters
176-
Seconds run: 5 (vs limit Inf)
177-
Iterations: 300
178-
f(x) calls: 300
179-
∇f(x) calls: 300
180186
```
181187

182188
We then complete the training using a different optimizer starting from where
@@ -185,12 +191,13 @@ halt when near the minimum.
185191

186192
```julia
187193
# Retrain using the LBFGS optimizer
188-
result_neuralode2 = DiffEqFlux.sciml_train(loss_neuralode,
189-
result_neuralode.minimizer,
190-
LBFGS(),
191-
cb = callback,
192-
allow_f_increases = false)
194+
optprob2 = remake(optprob,u0 = result_neuralode.minimizer)
193195

196+
result_neuralode2 = GalacticOptim.solve(optprob2,
197+
LBFGS(),
198+
cb = callback,
199+
allow_f_increases = false)
200+
# output
194201
* Status: success
195202

196203
* Candidate solution
@@ -239,10 +246,10 @@ my_neural_ode_prob = solve(prob, Tsit5(), args...; kwargs...)
239246

240247
and then one would use `solve` for the prediction like in other tutorials.
241248

242-
In total, the from scratch form looks like:
249+
In total, the 'from-scratch' form looks like:
243250

244251
```julia
245-
using DiffEqFlux, OrdinaryDiffEq, Flux, Optim, Plots
252+
using DiffEqFlux, OrdinaryDiffEq, Flux, Optim, Plots, GalacticOptim
246253

247254
u0 = Float32[2.0; 0.0]
248255
datasize = 30
@@ -260,13 +267,10 @@ ode_data = Array(solve(prob_trueode, Tsit5(), saveat = tsteps))
260267
dudt2 = FastChain((x, p) -> x.^3,
261268
FastDense(2, 50, tanh),
262269
FastDense(50, 2))
263-
neural_ode_f(u,p,t) = dudt2(u,p)
264-
pinit = initial_params(dudt2)
265-
prob = ODEProblem(neural_ode_f, u0, tspan, pinit)
270+
prob_neuralode = NeuralODE(dudt2, tspan, Tsit5(), saveat = tsteps)
266271

267272
function predict_neuralode(p)
268-
tmp_prob = remake(prob,p=p)
269-
Array(solve(tmp_prob,Tsit5(),saveat=tsteps))
273+
Array(prob_neuralode(u0, p))
270274
end
271275

272276
function loss_neuralode(p)
@@ -286,13 +290,21 @@ callback = function (p, l, pred; doplot = true)
286290
return false
287291
end
288292

289-
result_neuralode = DiffEqFlux.sciml_train(loss_neuralode, pinit,
290-
ADAM(0.05), cb = callback,
291-
maxiters = 300)
293+
adtype = GalacticOptim.AutoZygote()
294+
295+
optf = GalacticOptim.OptimizationFunction((x, p) -> loss_neuralode(x), adtype)
296+
optfunc = GalacticOptim.instantiate_function(optf, prob_neuralode.p, adtype, nothing)
297+
optprob = GalacticOptim.OptimizationProblem(optfunc, prob_neuralode.p)
298+
299+
result_neuralode = GalacticOptim.solve(optprob,
300+
ADAM(0.05),
301+
cb = callback,
302+
maxiters = 300)
303+
304+
optprob2 = remake(optprob,u0 = result_neuralode.minimizer)
292305

293-
result_neuralode2 = DiffEqFlux.sciml_train(loss_neuralode,
294-
result_neuralode.minimizer,
295-
LBFGS(),
296-
cb = callback,
297-
allow_f_increases = false)
306+
result_neuralode2 = GalacticOptim.solve(optprob2,
307+
LBFGS(),
308+
cb = callback,
309+
allow_f_increases = false)
298310
```

0 commit comments

Comments
 (0)