Neural ODE Modeling of a Single-Link Robot with External Input
古いコメントを表示
I want to construct the NeuralODE model of a single-link robot which can be described as ODEs with external control input:

where
and
represent angle position and angle velocity of the robot, respectively. The u is the external input.
However, when I start to train the neuralODE model with external input, the loss function curve can not reduce to zero. I want to konw how to verify that the obtained training results are effective even though the loss function does not equal to 0.
% Data generation of 1DoF Robot
dt = 1e-3;
tspan = 0:dt:5;
x0 = [0;0]; % initial state
u = sin(2*pi*tspan); % external input
Params = struct;
Params.M = 1;
Params.m = 2;
Params.g = 9.8;
Params.L = 0.5;
[T,X] = ode45(@(t,x) robotOdes(t,x,Params),tspan,x0);
tiledlayout("flow");
ax1 = nexttile;
plot(ax1,T,X);
legend(ax1,["Position x_1","Velocity x_2"]);
function dX = robotOdes(t,X,P)
dX = zeros(2,1);
dX(1) = X(2);
dX(2) = 1/P.M * sin(2*pi*t) - 1/(2*P.M) * P.m * P.g * P.L * sin(X(1));
end
% Define and Initialize Model Parameters
xTrain = X.'; % training datas
neuralOdeTimesteps = 50;
timesteps = (0:neuralOdeTimesteps)*dt;
% Initialize the parameters structure.
neuralOdeParameters = struct;
stateSize = size(xTrain,1);
hiddenSize = 30;
neuralOdeParameters.fc1 = struct;
neuralOdeParameters.fc1.Weights = dlarray(randn([hiddenSize stateSize],"single"));
neuralOdeParameters.fc1.Bias = dlarray(zeros([hiddenSize 1],"single"));
neuralOdeParameters.fc2 = struct;
neuralOdeParameters.fc2.Weights = dlarray(randn([stateSize hiddenSize],"single"));
neuralOdeParameters.fc2.Bias = dlarray(zeros([stateSize 1],"single"));
neuralOdeParameters.fc3 = struct;
sz = [hiddenSize stateSize];
neuralOdeParameters.fc3.Weights = dlarray(randn([hiddenSize stateSize],"single"));
neuralOdeParameters.fc3.Bias = dlarray(zeros([hiddenSize 1],"single"));
neuralOdeParameters.fc4 = struct;
neuralOdeParameters.fc4.Weights = dlarray(randn([stateSize hiddenSize],"single"));
neuralOdeParameters.fc4.Bias = dlarray(zeros([stateSize 1],"single"));
% Specify training options
gradDecay = 0.9;
sqGradDecay = 0.99;
learnRate = 0.005;
numIter = 1200;
miniBatchSize = 100;
averageGrad = [];
averageSqGrad = [];
% monitor = trainingProgressMonitor(Metrics="Loss",Info=["Iteration","LearnRate"],XLabel="Iteration");
numTrainingTimesteps = size(xTrain,2);
trainingTimesteps = 1:numTrainingTimesteps;
% Training loop
iteration = 0;
ax2 = nexttile;
an = animatedline(ax2);
while iteration < numIter
iteration = iteration + 1;
% Create batch
[X0,Targets,uVal,uTime] = createMiniBatch(numTrainingTimesteps,neuralOdeTimesteps,miniBatchSize,xTrain,u,tspan);
% Evaluate network and compute loss and gradients
[loss,gradients] = dlfeval(@modelLoss,timesteps,X0,neuralOdeParameters,Targets,uVal,uTime);
an.addpoints(iteration,extractdata(loss));
% Update network
[neuralOdeParameters,averageGrad,averageSqGrad] = adamupdate(neuralOdeParameters,gradients,averageGrad,averageSqGrad,iteration,...
learnRate,gradDecay,sqGradDecay);
end
% Helper functions
function X = model(tspan,X0,neuralOdeParameters,U,T)
X = dlode45(@(t,y,p) odeModel(t,y,p,U,T),tspan,X0,neuralOdeParameters,DataFormat="CB");
end
function [loss,gradients] = modelLoss(tspan,X0,neuralOdeParameters,targets,U,T)
% Compute predictions.
X = model(tspan,X0,neuralOdeParameters,U,T);
% Compute L1 loss.
loss = l1loss(X,targets,DataFormat="CBT",NormalizationFactor="all-elements");
% Compute gradients.
gradients = dlgradient(loss,neuralOdeParameters);
end
function dy = odeModel(t,y,theta,uVal,uTime)
f = tanh(theta.fc1.Weights*y + theta.fc1.Bias);
f = tanh(theta.fc2.Weights*f + theta.fc2.Bias);
g = tanh(theta.fc3.Weights*y + theta.fc3.Bias);
g = tanh(theta.fc4.Weights*g + theta.fc4.Bias);
u = zeros(size(uVal,[1 2])); % "CB" format
for batchIdx = 1:size(u,2)
% The size of control input is one
u(:,batchIdx) = interp1(squeeze(uTime(:,batchIdx,:)),squeeze(uVal(:,batchIdx,:)),t,"linear","extrap");
end
dy = f + g.*u; % neuralODE with external input dy == f_(y) + g_(y)*u affine form
end
function [x0,targets,u,t] = createMiniBatch(numTimesteps,numTimesPerObs,miniBatchSize,X,U,T)
% Create batches of trajectories.
s = randperm(numTimesteps - numTimesPerObs, miniBatchSize);
x0 = dlarray(X(:, s));
targets = zeros([size(X,1) miniBatchSize numTimesPerObs]);
u = zeros([size(U,1) miniBatchSize numTimesPerObs]);
t = zeros([1 miniBatchSize numTimesPerObs]);
for i = 1:miniBatchSize
targets(:, i, 1:numTimesPerObs) = X(:, s(i) + 1:(s(i) + numTimesPerObs));
u(:,i,1:numTimesPerObs) = U(:,s(i) + 1:(s(i) + numTimesPerObs));
t(:,i,1:numTimesPerObs) = T(:,s(i) + 1:(s(i) + numTimesPerObs));
end
end
採用された回答
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Sequence and Numeric Feature Data Workflows についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

