From 6cd38f7dae85290d0f0fcf62fb347afcb40098f7 Mon Sep 17 00:00:00 2001 From: ThummeTo <83663542+ThummeTo@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:52:41 +0100 Subject: [PATCH] corrected paths for images in tutorials (#70) * corrected paths for images in tutorials * reduced chunk_size for Julia 1.6 * minor bug fix --- examples/src/advanced_hybrid_ME.ipynb | 7 ++++--- examples/src/mdpi_2022.ipynb | 12 ++++++------ examples/src/modelica_conference_2021.ipynb | 7 ++++--- examples/src/simple_hybrid_CS.ipynb | 5 +++-- examples/src/simple_hybrid_ME.ipynb | 7 ++++--- src/layers.jl | 10 +++++++--- src/neural.jl | 6 +++++- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/examples/src/advanced_hybrid_ME.ipynb b/examples/src/advanced_hybrid_ME.ipynb index 34a8c685..732dddcd 100644 --- a/examples/src/advanced_hybrid_ME.ipynb +++ b/examples/src/advanced_hybrid_ME.ipynb @@ -41,7 +41,7 @@ "\n", "NeuralFMUs do not need to be as easy as in this example. Basically a NeuralFMU can combine different ANN topologies that manipulate any FMU-input (system state, system inputs, time) and any FMU-output (system state derivative, system outputs, other system variables). However, for this example a NeuralFMU topology as shown in the following picture is used.\n", "\n", - "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/NeuralFMU.svg?raw=true)\n", + "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/NeuralFMU.svg?raw=true)\n", "\n", "*NeuralFMU (ME) from* [[1]](#Source).\n", "\n", @@ -109,6 +109,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -116,11 +117,11 @@ "\n", "The object-orientated structure of the *SpringPendulum1D* (*simpleFMU*) can be seen in the following graphic and corresponds to a simple modeling.\n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringPendulum1D.svg?raw=true)\n", + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringPendulum1D.svg?raw=true)\n", "\n", "In contrast, the model *SpringFrictionPendulum1D* (*realFMU*) is somewhat more accurate, because it includes a friction component. \n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringFrictionPendulum1D.svg?raw=true)" + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringFrictionPendulum1D.svg?raw=true)" ] }, { diff --git a/examples/src/mdpi_2022.ipynb b/examples/src/mdpi_2022.ipynb index 3adc52c3..c7a7a230 100644 --- a/examples/src/mdpi_2022.ipynb +++ b/examples/src/mdpi_2022.ipynb @@ -44,7 +44,7 @@ "\n", "In this example, a real-world simulation model is enhanced in terms of accuracy using a so called *physics-enhanced neural ordinary differential equation* (PeNode). Basically, this is an extension to the NeuralODE concept and looks as can be seen in Fig. 1.\n", "\n", - "![NeuralFMU.svg](https://github.com/ThummeTo/FMIFlux.jl/tree/main/examples/img/mdpi_2022/neuralfmu.svg?raw=true)\n", + "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/mdpi_2022/neuralfmu.svg?raw=true)\n", "\n", "*Fig.1: A possible representation for a physics-enhanced neural ordinary differential equation (PeNODE). PeNODEs that include FMUs instead of symbolic ODEs are called NeuralFMUs.*\n", "\n", @@ -371,9 +371,9 @@ "\n", "These considerations lead to the following topology:\n", "\n", - "![usedneuralfmu.svg](https://github.com/ThummeTo/FMIFlux.jl/tree/main/examples/img/mdpi_2022/usedneuralfmu.svg?raw=true)\n", + "![usedneuralfmu.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/mdpi_2022/usedneuralfmu.svg?raw=true)\n", "\n", - "*Fig.2: The used topology for a NeuralFMU in this example. The ANN operates based on the signals $\\dot{x}_4, \\dot{x}_5, \\dot{x}_6$ from the FMU, but only modifies the signal $\\hat{\\dot{x}}_5$.*\n", + "*Fig.2: The used topology for a NeuralFMU in this example. The ANN operates based on the signals $\\dot{x}_4, \\dot{x}_5, \\dot{x}_6$ from the FMU, but only modifies the signal $\\hat{\\dot{x}}_5$. The gates $p_{FMU}$ and $p_{ANN}$ control how much the dynamics of FMU and ANN contribute to the NeuralFMU dynamics. Starting with $p_{FMU}=1.0$ and $p_{ANN}=0.0$ makes an initialization routine obsolete, because the dynamics of the NeuralFMU equal the dynamics of the FMU, see [[1]](#Source) for further details.*\n", "\n", "### Part 2c: Translating topology to Julia\n", "To implement the signal bypass in a layer sequence, two layers named `CacheLayer` and `CacheRetrieveLayer` are used to cache and retrieve arbitrary values:" @@ -567,12 +567,12 @@ "metadata": {}, "outputs": [], "source": [ - "# Load parameters \n", - "# fmiLoadParameters(neuralFMU, paramsPath)\n", - "\n", "# check what had been learned by the NeuralFMU, simulate it ...\n", "resultNFMU_train = neuralFMU(x0, (tStart, tStop); parameters=data.params, showProgress=true, recordValues=manipulatedDerVars, maxiters=1e7) # [120s]\n", "\n", + "# Load parameters \n", + "fmiLoadParameters(neuralFMU, paramsPath)\n", + "\n", "# are we better?\n", "mse_NFMU = FMIFlux.Losses.mse(data.consumption_val, fmiGetSolutionState(resultNFMU_train, 6; isIndex=true))\n", "mse_FMU = FMIFlux.Losses.mse(data.consumption_val, fmiGetSolutionState(resultFMU, 6; isIndex=true))\n", diff --git a/examples/src/modelica_conference_2021.ipynb b/examples/src/modelica_conference_2021.ipynb index b89264cf..1e4a865a 100644 --- a/examples/src/modelica_conference_2021.ipynb +++ b/examples/src/modelica_conference_2021.ipynb @@ -41,7 +41,7 @@ "\n", "NeuralFMUs do not need to be as easy as in this example. Basically a NeuralFMU can combine different ANN topologies that manipulate any FMU-input (system state, system inputs, time) and any FMU-output (system state derivative, system outputs, other system variables). However, for this example a NeuralFMU topology as shown in the following picture is used.\n", "\n", - "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/NeuralFMU.svg?raw=true)\n", + "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/NeuralFMU.svg?raw=true)\n", "\n", "*NeuralFMU (ME) from* [[1]](#Source).\n", "\n", @@ -107,6 +107,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -114,11 +115,11 @@ "\n", "The object-orientated structure of the *SpringPendulum1D* (*simpleFMU*) can be seen in the following graphic and corresponds to a simple modeling.\n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringPendulum1D.svg?raw=true)\n", + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringPendulum1D.svg?raw=true)\n", "\n", "In contrast, the model *SpringFrictionPendulum1D* (*realFMU*) is somewhat more accurate, because it includes a friction component. \n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringFrictionPendulum1D.svg?raw=true)" + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringFrictionPendulum1D.svg?raw=true)" ] }, { diff --git a/examples/src/simple_hybrid_CS.ipynb b/examples/src/simple_hybrid_CS.ipynb index b2fef4c8..507ca5cf 100644 --- a/examples/src/simple_hybrid_CS.ipynb +++ b/examples/src/simple_hybrid_CS.ipynb @@ -41,7 +41,7 @@ "\n", "NeuralFMUs do not need to be as easy as in this example. Basically a NeuralFMU can combine different ANN topologies that manipulate any FMU-input (system state, system inputs, time) and any FMU-output (system state derivative, system outputs, other system variables). However, for this example a NeuralFMU topology as shown in the following picture is used.\n", "\n", - "![CS-NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/CSNeuralFMU.svg?raw=true)\n", + "![CS-NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/CSNeuralFMU.svg?raw=true)\n", "\n", "*NeuralFMU (CS) from* [[1]](#Source).\n", "\n", @@ -107,6 +107,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -114,7 +115,7 @@ "\n", "The objec-orientated structure of the *SpringPendulumExtForce1D* can be seen in the following graphic. This model is a simple spring pendulum without friction, but with an external force. \n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringPendulumExtForce1D.svg?raw=true)" + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringPendulumExtForce1D.svg?raw=true)" ] }, { diff --git a/examples/src/simple_hybrid_ME.ipynb b/examples/src/simple_hybrid_ME.ipynb index a5beacdb..4bf0a988 100644 --- a/examples/src/simple_hybrid_ME.ipynb +++ b/examples/src/simple_hybrid_ME.ipynb @@ -41,7 +41,7 @@ "\n", "NeuralFMUs do not need to be as easy as in this example. Basically a NeuralFMU can combine different ANN topologies that manipulate any FMU-input (system state, system inputs, time) and any FMU-output (system state derivative, system outputs, other system variables). However, for this example a NeuralFMU topology as shown in the following picture is used.\n", "\n", - "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/NeuralFMU.svg?raw=true)\n", + "![NeuralFMU.svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/NeuralFMU.svg?raw=true)\n", "\n", "*NeuralFMU (ME) from* [[1]](#Source).\n", "\n", @@ -107,6 +107,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -114,11 +115,11 @@ "\n", "The object-orientated structure of the *SpringPendulum1D* (*simpleFMU*) can be seen in the following graphic and corresponds to a simple modeling.\n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringPendulum1D.svg?raw=true)\n", + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringPendulum1D.svg?raw=true)\n", "\n", "In contrast, the model *SpringFrictionPendulum1D* (*realFMU*) is somewhat more accurate, because it includes a friction component. \n", "\n", - "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/pics/SpringFrictionPendulum1D.svg?raw=true)" + "![svg](https://github.com/thummeto/FMIFlux.jl/blob/main/docs/src/examples/img/SpringFrictionPendulum1D.svg?raw=true)" ] }, { diff --git a/src/layers.jl b/src/layers.jl index 8b937813..b0dd0c97 100644 --- a/src/layers.jl +++ b/src/layers.jl @@ -63,7 +63,7 @@ struct ScaleShift{T} end # init ScaleShift with inverse transformation of a given ShiftScale - function ScaleShift(l::ShiftScale{T}; indices=1:length(data)) where {T} + function ScaleShift(l::ShiftScale{T}; indices=1:length(l.scale)) where {T} return ScaleShift{T}(1.0 / l.scale[indices], -1.0 * l.shift[indices]) end @@ -140,10 +140,14 @@ struct CacheRetrieveLayer end export CacheRetrieveLayer -function (l::CacheRetrieveLayer)(idxBefore, x, idxAfter=nothing) +function (l::CacheRetrieveLayer)(idxBefore, x=nothing, idxAfter=nothing) # Zygote doesn't like empty arrays - if idxAfter == nothing + if idxAfter == nothing && x == nothing + return l.cacheLayer.cache[idxBefore] + elseif idxAfter == nothing return [l.cacheLayer.cache[idxBefore]..., x...] + elseif x == nothing + return [l.cacheLayer.cache[idxBefore]..., l.cacheLayer.cache[idxAfter]...] else return [l.cacheLayer.cache[idxBefore]..., x..., l.cacheLayer.cache[idxAfter]...] end diff --git a/src/neural.jl b/src/neural.jl index 72fbbd23..3e316bff 100644 --- a/src/neural.jl +++ b/src/neural.jl @@ -1340,6 +1340,10 @@ function train!(loss, params::Union{Flux.Params, Zygote.Params, Vector{Vector{Fl to_differentiate = p -> loss(p) + if VERSION < v"1.7.0" + @warn "Training under Julia 1.6 is very slow, please consider using Julia 1.7 or newer." + end + for i in 1:length(data) try @@ -1356,7 +1360,7 @@ function train!(loss, params::Union{Flux.Params, Zygote.Params, Vector{Vector{Fl chunk_size = ceil(Int, sqrt( Sys.total_memory()/(2^30) ))*32 else - chunk_size = ceil(Int, sqrt( Sys.total_memory()/(2^30) ))*4 + chunk_size = ceil(Int, sqrt( Sys.total_memory()/(2^30) ))*2 #grad = ForwardDiff.gradient(to_differentiate, params[j]); end