主要内容

本页采用了机器翻译。点击此处可查看英文原文。

简单摆系统的神经状态空间模型

本示例演示了如何设计和训练一个深度神经网络,以对连续时间下的非线性状态空间系统进行逼近。

神经状态空间模型

状态空间模型是通过状态方程和输出方程来描述动态系统的建模方法。

状态方程:x˙=f(x,u)

输出方程:y=g(x,u)

这里,xuy 分别是表示系统状态、输入和测量输出量的向量。

状态方程是一组一阶常微分方程 (ODE) 或差分方程,通常基于第一性原理推导得出(白盒建模)。然而,在实际应用中,要找到能够准确描述系统的简单解析方程往往很困难,因为,例如,系统本身较为复杂,或者缺乏对其内部运作机制的某些领域知识,抑或无法获得这些知识。

在这些情况下,数据驱动建模(灰盒黑盒建模)可成为一种有效的替代方案。神经状态空间建模就是这样一种基于数据的方法,它通过神经网络同时表示非线性系统的状态方程和输出方程,如图所示。

image 2.jpg

例如,对于一个连续时间非线性系统,可以使用多层感知机 (MLP) 网络来近似状态方程。网络的输入是 xu,即被控对象的状态向量和输入向量;网络的输出是 x˙,即被控对象状态导数的向量。

同样地,当存在一个非平凡的(即 yx)输出方程时,您可以使用另一个多层感知机 (MLP) 网络来对其进行逼近。对于该网络,输入仍然是 xu,而网络输出是 y,即被控对象的测量输出。

简单摆

例如,在此示例中,您将构建一个简单受迫摆的神经状态空间模型。该摆具有两个状态(角度 θ 和角速度 θ˙)、一个输入(扭矩 τ)以及两个输出(质点的水平位置 y1、质点的垂直位置 y2)。

pendulum.jpg

要成功辨识神经状态空间模型,必须满足以下前提条件:

  1. 您所选择的状态变量必须能够充分描述系统行为(例如,在已知系统方程的情况下,仅需状态变量的当前值即可预测未来状态)。对于物理系统,您可以利用领域知识来确定,在您想要建模的特定动态特性中,状态向量应包含哪些系统变量。如果目标状态集不可测,则必须选择另一组能够等效描述系统动力学行为的状态集。例如,如果在简摆问题中无法测量角度 θ 和角速度 θ˙,则应选择质点的位置 [y1,y2] 及其速度 [y1˙,y2˙] 作为状态向量,因为只要它们可测量,就能充分描述摆的运动行为。

  2. 状态、输入和输出(当 yx 时)必须是可测的,因为训练数据由试验过程中收集的状态、输入和输出轨迹组成。

例如,您可以假设状态 [θ,θ˙] 足以描述该系统,并且这些状态以及输出 [y1,y2] 都是可测的。

试验设计

试验设计 (DoE) 是任何基于数据的建模应用中的关键步骤,因为通常来说,模型的质量取决于用于构建该模型的数据质量。在为神经状态空间建模收集数据时,请确保状态轨迹在设计规定的运行条件下尽可能全面地覆盖状态空间。

在此示例中,针对一个仿真被控对象(即真实被控对象)进行了 101 次试验,每次试验均从不同的初始角度和角速度 [θ0,θ˙0] 开始。每次试验持续 1 秒,每 0.1 秒记录一次状态轨迹。在每次试验中,植物输入(扭矩)在 [-2,2] 的范围内随机变化。

加载数据,该数据由两个包含时间表的元胞数组组成:状态轨迹 Y 和输入轨迹 U。将训练试验的数量 N 设置为比试验总数少 1(即 100)。将最后一个试验留作验证之用。

load pendulumdata;
N = length(Y) - 1;

实际上,出于操作、安全和经济方面的原因,通常会对可进行的试验数量以及单个试验的持续时间进行限制。例如,在此示例中,您也可以进行 10 次试验,每次试验持续 10 秒。您可以将每个试验分为 10 个片段,只要这 10 条状态轨迹也能覆盖足够大的状态空间,这实际上就等同于原始试验。

设计神经状态空间模型

定义一个具有两个状态和一个输入的神经状态空间模型。在神经网络状态空间模型中,由于状态总是作为模型的第一个 nx 输出包含在内,因此应包含四个输出。前两个输出是状态量(角位置和角速度),后两个输出是质点的水平位置和垂直位置。

sys = idNeuralStateSpace(2,NumInputs=1,NumOutput=4);

状态网络和输出网络均采用随机初始化。为了确保结果可重复,请固定随机数生成器的种子。

rng(0);

现在,通过为状态网络和输出网络分别创建多层感知机 (MLP) 网络,对它们进行自定义。请注意,当输出方程非平凡时(例如本示例所示),OutputNetwork 属性包含一个由两个神经网络组成的向量,其中第一个代表 y=x,第二个代表输出方程 y=g(x,u)。因此,在为输出方程自定义网络时,请更新 OutputNetwork(2)

% State network
sys.StateNetwork = createMLPNetwork(sys,'state', ...
   LayerSizes=[128 128], ...
   Activations="tanh", ...
   WeightsInitializer="glorot", ...
   BiasInitializer="zeros");

% Output network
sys.OutputNetwork(2) = createMLPNetwork(sys,'output', ...
   LayerSizes=[128 128], ...
   Activations="tanh", ...
   WeightsInitializer="glorot", ...
   BiasInitializer="zeros");

训练神经状态空间模型

创建一个训练选项对象,并将求解器设置为 'adam'。将最大迭代次数设置为 200,学习率设置为 0.005

options = nssTrainingOptions('adam');
options.MaxEpochs = 200;
options.LearnRate = 0.005;

该模型的参数数量超过了数据样本数量,因此触发了警告。在调用 nlssest 之前,请抑制此警告。

Warn = warning('off','Ident:estimation:NparGTNsamp');
WarnReset = onCleanup(@()warning(Warn));

要训练神经状态空间模型,请使用 nlssest。若要将数据集中的最后一个试验用于验证图,请在命令中将 UseLastExperimentForValidation 参量设置为 true

sys = nlssest(U,Y,sys,options,UseLastExperimentForValidation=true);

Figure Loss contains 2 axes objects and another object of type uigridlayout. Axes object 1 with title Output Network: Training Loss (MeanAbsoluteError), xlabel Epoch, ylabel Loss contains an object of type animatedline. Axes object 2 with title State Network: Training Loss (MeanAbsoluteError), xlabel Epoch, ylabel Loss contains an object of type animatedline.

Figure Validation Plot contains 4 axes objects. Axes object 1 with title Epoch = 200, Elapsed: 00:00:43, ylabel x1 contains 2 objects of type line. These objects represent Truth, Predicted. Axes object 2 with ylabel x2 contains 2 objects of type line. These objects represent Truth, Predicted. Axes object 3 with ylabel y1 contains 2 objects of type line. These objects represent Truth, Predicted. Axes object 4 with xlabel time (seconds), ylabel y2 contains 2 objects of type line. These objects represent Truth, Predicted.

Generating estimation report...done.

在训练过程中,会显示两幅图供检查。第一张图展示了两个神经网络在不同完成 epoch 数下的损失值。第二幅图展示了基于验证数据集的预测状态和输出轨迹与实测轨迹的对比。

分析已训练的神经状态空间模型

神经状态空间模型提供了一系列指令,以便于对训练好的模型进行分析和使用。例如,您可以使用 evaluate 根据状态和输入来计算状态导数和输出。

x0 = rand(2,1);
u0 = rand;
[dxdt,y] = evaluate(sys,x0,u0);

使用 linearize 在指定的工作点处创建一个 LTI 状态空间模型。将线性模型的阶跃响应与原始模型的阶跃响应进行比较。

sysLinear = linearize(sys,x0,u0);
opt = RespConfig(InputOffset=u0,InitialState=x0);
step(sys,sysLinear,30,opt)

MATLAB figure

您可以从神经状态空间模型中生成用于状态函数和输出函数及其雅可比矩阵的独立的 MATLAB® 函数。您可以使用这些函数来仿真神经状态空间系统,并生成用于部署的 C/C++ 代码,以应用于非线性状态估计和模型预测控制等场景。

generateMATLABFunction(sys,"myStateFcn","myOutputFcn");

请等待文件写入完成,并由文件系统提供访问权限。

while ~exist("myStateFcn","file") 
    pause(1); 
end
while ~exist("myOutputFcn","file")
    pause(1); 
end

调用状态和输出函数,以显示工作点处的状态导数和输出。

dxdt1 = myStateFcn(x0,u0)
dxdt1 = 2×1

    0.4491
   -2.7142

y1 = myOutputFcn(x0,u0)
y1 = 2×1

    1.1843
    0.4245

调用这些函数得到的结果与直接对神经状态空间对象调用 evaluate 函数所得到的结果相同。

error = norm([dxdt;y(3:4)]-[dxdt1;y1])
error = 
0

您还可以在神经状态空间模型上使用其他 System Identification Toolbox™ 命令,例如 simpredictcompare

另请参阅

对象

函数

模块

实时编辑器任务

主题