Neural ODE for dynamic systems with input signals
31 views (last 30 days)
Show older comments
Hi! Community!
Is it possible to consider input signals in training? That is, to define the differential equation to be:
where is the input signal.
However, dlode45 will not allow the ODE function to be with more than three inputs.
So is there any other possible approach to incorporate the input signal?
Thanks a lot!
0 Comments
Accepted Answer
Ben
on 25 Jan 2022
Hi Bowei,
You should be able to create a new ODE function that has only three inputs as required. Let me show a few cases.
Case 1 -
In this case you can define . Assuming you have f as a function handle you can define g in code with:
g = @(t,x,theta) f(t,x,theta,e(t))
Then solve using g in dlode45.
Case 2 -
This is a special case of case 1:
g = @(t,x,theta) f(t,x,theta) + e(t)
Call dlode45 with g.
Case 3 - for
In this case you have an extra hyperparameter i which you just have to select a specific value for. For example let and . You could write this in code as:
e = @(t,i) cos(i*t);
f = @(t,x,A,i) A*x + e(t,i);
x0 = dlarray(randn());
tspan = [0,1];
A = dlarray(randn());
i = 3;
x = dlode45(@(t,x,A) f(t,x,A,i), tspan, x0, A, DataFormat="CB");
Note that in this case you can loop over the values you want for i.
Hope that helps,
Ben
6 Comments
Ben
on 11 Dec 2024
Edited: Ben
on 11 Dec 2024
On the second question regarding the example, neuralODELayer can be used here as follows:
% https://uk.mathworks.com/help/deeplearning/ug/dynamical-system-modeling-using-neural-ode.html
% using neuralODELayer
% Generate training data
x0 = [2; 0];
A = [-0.1 -1; 1 -0.1];
trueModel = @(t,y) A*y;
numTimeSteps = 2000;
T = 15;
odeOptions = odeset(RelTol=1.e-7);
t = linspace(0, T, numTimeSteps);
[~, xTrain] = ode45(trueModel, t, x0, odeOptions);
xTrain = xTrain';
% Rearrange the single solution [x(1),x(2),...,x(end)] into subsequences
% x(t) and [x(t+1), ..., x(t+40)].
neuralOdeTimesteps = 40;
dt = t(2);
timesteps = (0:neuralOdeTimesteps)*dt;
input = xTrain(:,1:end-neuralOdeTimesteps);
numObs = numTimeSteps - neuralOdeTimesteps;
targets = cell(numObs, 1);
for i = 1:numObs
targets{i} = xTrain(:,i + (1:neuralOdeTimesteps));
end
% Design neural ODE.
stateSize = size(xTrain,1);
hiddenSize = 20;
odeNet = [
fullyConnectedLayer(hiddenSize)
tanhLayer
fullyConnectedLayer(stateSize)];
odeNet = dlnetwork(odeNet,Initialize=false);
odeLayer = neuralODELayer(odeNet,timesteps,GradientMode="adjoint");
net = dlnetwork([featureInputLayer(stateSize); odeLayer]);
% Train neural ODE.
opts = trainingOptions("adam", ...
Plots="training-progress", ...
ExecutionEnvironment="cpu", ...
InputDataFormats="CB",...
TargetDataFormats="CTB");
trainednet = trainnet(input,targets,net,"l2loss",opts);
% Use neural ODE to predict on a longer time interval.
% This requires extracting the layer, setting the new time interval, and
% calling replaceLayer to put the layer back into the network with the new
% time interval.
% Alternatively you can extract odeNet = trainednet.Layers(2).Network and use
% dlode45(odeNet, t, x0)
layer = trainednet.Layers(2);
layer.TimeInterval = t;
inferencenet = replaceLayer(trainednet,layer.Name,layer);
inferencenet = initialize(inferencenet);
x0Pred1 = sqrt([2,2]);
xPred1 = predict(inferencenet,x0Pred1);
plot(xPred1(:,1),xPred1(:,2))
Regarding trainnet - the inputs and targets don't have to have the same dimensions. A neuralODELayer(net, ts) will take an initial condition as input, corresponding to the state at time ts(1), and output the solution as a sequence (with T dimension) at times ts(2:end).
Hope that helps.
More Answers (1)
David Willingham
on 24 Jan 2022
Hi Bowei,
Thanks for the feedback on our neural ode example! For your request, can you elloborate on what type of signal e(t) might be and what use cases you're looking to apply neural ode's to?
David
See Also
Categories
Find more on Sequence and Numeric Feature Data Workflows in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!