DNN(深度神经网络)近似 Lyapunov 函数

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
# from torchviz import make_dot
import torchviz


# 1. Lyapunov 函数近似器(MLP 结构)
class LyapunovNet(nn.Module):
    def __init__(self, input_dim, hidden_dim=32):
        super(LyapunovNet, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, 1)  # 输出一个标量,表示Lyapunov函数值
        )
    
    def forward(self, x):
        return self.model(x)

# 2. 梯度伴随网络(计算 Lyapunov 函数的梯度)
def compute_gradient(model, x):
    x.requires_grad_(True)
    V = model(x)
    grad_V = torch.autograd.grad(V.sum(), x, create_graph=True)[0]
    return V, grad_V

# 3. 训练数据(随机生成一些状态数据)
def generate_data(num_samples=1000, state_dim=2):
    return torch.randn(num_samples, state_dim) * 5  # 扩大范围

# 4. 网络权重初始化
def init_weights(m):
    if isinstance(m, nn.Linear):
        torch.nn.init.xavier_uniform_(m.weight)
        if m.bias is not None:
            torch.nn.init.zeros_(m.bias)

# 5. 训练 Lyapunov 网络并绘制损失曲线
def train_lyapunov_net(state_dim=2, epochs=500, lr=0.001):
    model = LyapunovNet(input_dim=state_dim)
    model.apply(init_weights)  # 重新初始化网络
    optimizer = optim.Adam(model.parameters(), lr=lr)
    loss_history = []
    
    for epoch in range(epochs):
        x = generate_data()
        V, grad_V = compute_gradient(model, x)
        
        # 修正损失函数
        loss = torch.mean(torch.relu(-grad_V.sum(dim=1))) + torch.mean(torch.relu(-V))
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        loss_history.append(loss.item())
        
        if epoch % 50 == 0:
            print(f"Epoch {epoch}, Loss: {loss.item():.6f}")
    
    # 绘制损失曲线
    plt.plot(loss_history)
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.title("Training Loss Curve")
    plt.grid()
    plt.show()
    
    return model

# 6. 可视化神经网络计算图
def visualize_lyapunov_network(model, state_dim=2):
    x = torch.randn(1, state_dim, requires_grad=True)  # 生成一个测试输入
    V = model(x)
    dot = make_dot(V, params=dict(model.named_parameters()))
    dot.format = 'png'
    dot.render('lyapunov_network')  # 生成 PNG 图片
    dot.view()  # 打开图像

if __name__ == "__main__":
    trained_model = train_lyapunov_net()
    visualize_lyapunov_network(trained_model)


这段代码的核心目标是使用神经网络近似 Lyapunov 函数,并通过梯度信息优化其参数,以确保 Lyapunov 函数在物理系统的状态空间中满足稳定性条件。以下是详细的解析:


1. 代码整体架构

该代码主要包含 6 个部分:

  1. 定义 Lyapunov 函数近似器(MLP 神经网络)。
  2. 计算 Lyapunov 函数的梯度(用于优化)。
  3. 生成训练数据(模拟状态空间点)。
  4. 初始化网络权重(Xavier 初始化)。
  5. 训练 Lyapunov 网络(基于梯度信息优化 Lyapunov 函数)。
  6. 可视化网络结构(绘制计算图)。

2. 详细解析每个部分

(1) Lyapunov 函数近似器

python 复制代码
class LyapunovNet(nn.Module):
    def __init__(self, input_dim, hidden_dim=32):
        super(LyapunovNet, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, 1)  # 输出一个标量,表示Lyapunov函数值
        )
    
    def forward(self, x):
        return self.model(x)

📌 作用

  • 这是一个

    多层感知机(MLP)

    结构:

    • 输入 x 代表系统状态变量(维度 input_dim)。
    • 两个隐藏层,每层 hidden_dim=32,激活函数为 ReLU
    • 输出是一个标量 ,表示 Lyapunov 函数值 V(x)

📌 数学意义

  • 训练后,神经网络会学习到一个 Lyapunov 函数近似 V(x),用于判定系统稳定性

(2) 计算 Lyapunov 函数的梯度

python 复制代码
def compute_gradient(model, x):
    x.requires_grad_(True)  # 使 x 可微分
    V = model(x)  # 计算 Lyapunov 函数值
    grad_V = torch.autograd.grad(V.sum(), x, create_graph=True)[0]  # 计算梯度
    return V, grad_V

📌 作用

  • 计算 V(x)x 的梯度 ∇V(x)
  • torch.autograd.grad() 自动计算梯度,用于 Lyapunov 函数优化。

📌 数学意义

V ( x ) V(x) V(x)的梯度 ∇ V ( x ) ∇V(x) ∇V(x)

需要满足:

d V d t = ∇ V ( x ) ⋅ f ( x ) ≤ 0 \frac{dV}{dt} = \nabla V(x) \cdot f(x) \leq0 dtdV=∇V(x)⋅f(x)≤0

  • 这个条件保证 Lyapunov 函数单调递减,从而保证系统稳定性

(3) 生成训练数据

python 复制代码
def generate_data(num_samples=1000, state_dim=2):
    return torch.randn(num_samples, state_dim) * 5  # 生成随机状态点

📌 作用

  • 生成服从标准正态分布的随机状态数据,用于训练 Lyapunov 神经网络。

📌 数学意义

  • 这些数据点可以看作是随机抽取的系统状态,用于训练神经网络使其学会合适的 Lyapunov 函数。

(4) 网络权重初始化

python 复制代码
辑def init_weights(m):
    if isinstance(m, nn.Linear):
        torch.nn.init.xavier_uniform_(m.weight)
        if m.bias is not None:
            torch.nn.init.zeros_(m.bias)

📌 作用

  • 采用 Xavier(Glorot)初始化 线性层权重,保证网络初始梯度不会过大或过小。
  • bias 初始化为 0

📌 数学意义

  • Xavier 初始化

    W ∼ U ( − 6 n i n + n o u t , 6 n i n + n o u t ) W \sim U\left(-\sqrt{\frac{6}{n_{in} + n_{out}}}, \sqrt{\frac{6}{n_{in} + n_{out}}}\right) W∼U(−nin+nout6 ,nin+nout6 )

    • 其中 n i n n_{in} nin和 n o u t n_{out} nout分别是输入和输出的神经元数目。

(5) 训练 Lyapunov 网络

python 复制代码
def train_lyapunov_net(state_dim=2, epochs=500, lr=0.001):
    model = LyapunovNet(input_dim=state_dim)
    model.apply(init_weights)  # 重新初始化网络
    optimizer = optim.Adam(model.parameters(), lr=lr)
    loss_history = []
    
    for epoch in range(epochs):
        x = generate_data()
        V, grad_V = compute_gradient(model, x)
        
        # 修正损失函数
        loss = torch.mean(torch.relu(-grad_V.sum(dim=1))) + torch.mean(torch.relu(-V))
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        loss_history.append(loss.item())
        
        if epoch % 50 == 0:
            print(f"Epoch {epoch}, Loss: {loss.item():.6f}")
    
    # 绘制损失曲线
    plt.plot(loss_history)
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.title("Training Loss Curve")
    plt.grid()
    plt.show()
    
    return model

📌 作用

  • 优化 Lyapunov 函数 V(x),使其满足 Lyapunov 稳定性条件

    • V(x) > 0(Lyapunov 函数应该是正的)。
    • ∇V(x) ≤ 0(Lyapunov 函数应该单调递减)。

📌 数学意义

  • 损失函数

    L = E [ m a x ⁡ ( 0 , − ∇ V ( x ) ) ] + E [ m a x ⁡ ( 0 , − V ( x ) ) ] L=E[max⁡(0,−∇V(x))]+E[max⁡(0,−V(x))] L=E[max⁡(0,−∇V(x))]+E[max⁡(0,−V(x))]

    • 其中:
      • torch.relu(-grad_V.sum(dim=1)):强制 ∇V(x) ≤ 0,确保 Lyapunov 单调递减。
      • torch.relu(-V):确保 V(x) ≥ 0

(6) 可视化 Lyapunov 神经网络

python 复制代码
def visualize_lyapunov_network(model, state_dim=2):
    x = torch.randn(1, state_dim, requires_grad=True)  # 生成一个测试输入
    V = model(x)
    dot = make_dot(V, params=dict(model.named_parameters()))
    dot.format = 'png'
    dot.render('lyapunov_network')  # 生成 PNG 图片
    dot.view()  # 打开图像

📌 作用

  • 使用 torchviz 绘制计算图,直观展示神经网络结构。

3. main-run

python 复制代码
if __name__ == "__main__":
    trained_model = train_lyapunov_net()
    visualize_lyapunov_network(trained_model)

📌 作用

  1. 训练 Lyapunov 网络
  2. 可视化网络结构

4. 总结

模块 作用
LyapunovNet 使用 MLP 近似 V(x)
compute_gradient 计算 ∇V(x)
generate_data 生成随机状态数据
init_weights Xavier 权重初始化
train_lyapunov_net 训练神经网络,使其满足 Lyapunov 条件
visualize_lyapunov_network 可视化计算图

这个代码的核心思想是通过深度学习构建 Lyapunov 函数,确保 V(x) 单调递减,从而评估系统的瞬态稳定性。🔥

5.延伸

将以上的损失函数改为平方-以下为改后的损失函数公式展示

给定状态 x x x的动态系统:

d x d t = f ( x ) \frac{dx}{dt} = f(x) dtdx=f(x)

定义 Lyapunov 近似函数 V ( x ) V(x) V(x) 及其梯度:

∇ V = ∂ V ∂ x \nabla V = \frac{\partial V}{\partial x} ∇V=∂x∂V

损失函数由两个部分组成:

  1. Lyapunov 下降约束 (确保 d V d t ≤ 0 \frac{dV}{dt} \leq 0 dtdV≤0 ):

    L decay = E x [ max ⁡ ( 0 , − ∇ V ⋅ f ( x ) ) ] \mathcal{L}_{\text{decay}} = \mathbb{E}_x \left[ \max\left( 0, -\nabla V \cdot f(x) \right) \right] Ldecay=Ex[max(0,−∇V⋅f(x))]

    其中 ∇ V ⋅ f ( x ) = ∑ i ∂ V ∂ x i f i ( x ) \nabla V \cdot f(x) = \sum_{i} \frac{\partial V}{\partial x_i} f_i(x) ∇V⋅f(x)=∑i∂xi∂Vfi(x)是 Lyapunov 函数关于时间的导数。

  2. Lyapunov 函数非负性约束 (确保 V ( x ) ≥ 0 V(x)≥0 V(x)≥0 ):

    L positivity = E x [ V ( x ) 2 ] ] \mathcal{L}_{\text{positivity}} = \mathbb{E}_x \left[ V(x)^2 \right]] Lpositivity=Ex[V(x)2]]

    这里我们使用平方损失 V ( x ) 2 V(x)^2 V(x)2 代替 ReLU 约束 m a x ⁡ ( 0 , − V ( x ) ) max⁡(0,−V(x)) max⁡(0,−V(x)) 以增强稳定性。

总损失函数

L = L decay + L positivity L = \mathcal{L}{\text{decay}} + \mathcal{L}{\text{positivity}} L=Ldecay+Lpositivity

该损失函数的优化目标是找到一个满足 Lyapunov 条件的近似函数 V ( x ) V(x) V(x),使得:

  1. Lyapunov 下降条件 : d V d t ≤ 0 \frac{dV}{dt} \leq 0 dtdV≤0 适用于所有 x x x。
  2. Lyapunov 函数非负性 : V ( x ) ≥ 0 V(x)≥0 V(x)≥0 确保稳定性分析的正确性。

这样,我们训练出的神经网络可以逼近一个合适的 Lyapunov 函数,从而用于评估瞬态稳定性

代码

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from torchviz import make_dot

# 1. Lyapunov 函数近似器(MLP 结构)
class LyapunovNet(nn.Module):
    def __init__(self, input_dim, hidden_dim=32):
        super(LyapunovNet, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, 1)  # 输出一个标量,表示Lyapunov函数值
        )
    
    def forward(self, x):
        return self.model(x)

# 2. 定义系统动力学方程(如果已知)
def system_dynamics(x):
    return -x  # 示例:简单的线性动力学 dx/dt = -x

# 3. 计算 Lyapunov 函数的梯度
def compute_gradient(model, x):
    x.requires_grad_(True)
    V = model(x)
    grad_V = torch.autograd.grad(V.sum(), x, create_graph=True)[0]
    return V, grad_V

# 4. 训练数据(随机生成一些状态数据)
def generate_data(num_samples=1000, state_dim=2):
    return torch.randn(num_samples, state_dim) * 5  # 扩大范围

# 5. 网络权重初始化
def init_weights(m):
    if isinstance(m, nn.Linear):
        torch.nn.init.xavier_uniform_(m.weight)
        if m.bias is not None:
            torch.nn.init.zeros_(m.bias)

# 6. 训练 Lyapunov 网络并绘制损失曲线
def train_lyapunov_net(state_dim=2, epochs=500, lr=0.001):
    model = LyapunovNet(input_dim=state_dim)
    model.apply(init_weights)  # 重新初始化网络
    optimizer = optim.Adam(model.parameters(), lr=lr)
    loss_history = []
    
    for epoch in range(epochs):
        x = generate_data()
        V, grad_V = compute_gradient(model, x)
        dx_dt = system_dynamics(x)  # 获取系统的动态方程
        
        # 1. 约束 Lyapunov 下降条件: dV/dt = ∇V · f(x) ≤ 0
        lyapunov_decay = torch.mean(torch.relu(-(grad_V * dx_dt).sum(dim=1)))
        # 2. 确保 Lyapunov 函数 V(x) 是非负的
        lyapunov_positivity = torch.mean(V**2)  # 使 V(x) 逼近 0 而不是仅仅大于 0
        
        loss = lyapunov_decay + lyapunov_positivity
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        loss_history.append(loss.item())
        
        if epoch % 50 == 0:
            print(f"Epoch {epoch}, Loss: {loss.item():.6f}")
    
    # 绘制损失曲线
    plt.plot(loss_history)
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.title("Training Loss Curve")
    plt.grid()
    plt.show()
    
    return model

# 7. 可视化神经网络计算图
def visualize_lyapunov_network(model, state_dim=2):
    x = torch.randn(1, state_dim, requires_grad=True)  # 生成一个测试输入
    V = model(x)
    dot = make_dot(V, params=dict(model.named_parameters()))
    dot.format = 'png'
    dot.render('lyapunov_network')  # 生成 PNG 图片
    dot.view()  # 打开图像

if __name__ == "__main__":
    trained_model = train_lyapunov_net()
    visualize_lyapunov_network(trained_model)
相关推荐
NAGNIP1 天前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab1 天前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab1 天前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP1 天前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年1 天前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼1 天前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS1 天前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区1 天前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈1 天前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang1 天前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx