伴随灵敏度分析
伴随灵敏度分析(Adjoint Sensitivity Analysis),也称为反向灵敏度分析(Reverse Sensitivity Analysis),是一种高效计算标量目标函数关于大量参数梯度的方法。
理论基础
考虑一个离散动力学系统: $ x_{k+1} = f(x_k, u_k, \theta), \quad k=0, \dots, N-1 $ 以及一个定义在轨迹上的目标函数: $ J = \sum_{k=0}^{N-1} L_k(x_k, u_k) + \Phi(x_N) $ 其中
为了计算梯度
Rible.jl 实现
Rible.jl 实现了基于 Zhong06 变分积分子(Variational Integrator)的离散伴随方法。这种方法直接在离散层面上构建伴随方程,保证了梯度的精确性和数值稳定性,特别适合处理包含接触和碰撞的非光滑系统。
核心组件
Adjoint_Zhong06_Constant_Mass_Cache: 存储伴随求解所需的中间变量。generate_cache: 初始化伴随求解器缓存。solve!: 执行反向伴随求解。
使用示例
using Rible
# 1. 定义问题 (prob) 和前向仿真结果 (sim)
# 假设 prob 是 DynamicsProblem,sim 是 Simulator
# 2. 配置伴随求解器
adjoint_solver = Rible.AdjointDynamicsSensitivitySolver(
Rible.DynamicsSolver(Rible.Zhong06()),
objective_function # 用户定义的目标函数
)
# 3. 生成缓存
# 注意:伴随求解通常需要前向仿真的完整轨迹
adjoint_cache = Rible.generate_cache(
prob,
adjoint_solver,
Val(true);
dt = 1e-3,
totalstep = 1000
)
# 4. 求解伴随状态
# 这将反向遍历时间步,计算伴随变量
Rible.solve!(
sim,
forward_cache,
adjoint_cache;
dt = 1e-3
)
# 5. 获取梯度
# 梯度信息存储在 adjoint_cache 中
# 例如,获取关于初始状态的梯度
grad_x0 = adjoint_cache.solver_cache.adjoint_cache.∂J∂x₀ᵀ注意事项
内存消耗:伴随方法需要存储整个前向仿真过程的状态轨迹,对于长时间仿真,内存消耗可能较大。
接触处理:Rible.jl 的伴随求解器能够处理接触约束,但需要确保前向仿真中正确记录了接触事件。
常质量假设:目前的实现主要针对常质量矩阵系统进行了优化。