使用 pykan 求解二维 Poisson 方程并进行符号化解释:KAN 偏微分方程数值求解实战

发布时间:2026/11/7 11:14:08

使用 pykan 求解二维 Poisson 方程并进行符号化解释:KAN 偏微分方程数值求解实战 使用 pykan 求解二维 Poisson 方程并进行符号化解释KAN 偏微分方程数值求解实战【免费下载链接】pykanKolmogorov Arnold Networks项目地址: https://gitcode.com/GitHub_Trending/pyk/pykan导读本文基于 pykan 仓库的官方示例docs/Example/Example_6_PDE_interpretation.ipynb 及其 RST 版本 docs/Example/Example_6_PDE_interpretation.rst完整演示如何用 KANKolmogorov-Arnold Networks求解带 Dirichlet 边界条件的二维 Poisson 方程通过torch.autograd构造拉普拉斯算子残差损失与边界损失使用 L-BFGS 优化器训练网络再通过fix_symbolic将激活函数替换为线性函数与正弦函数最终借助symbolic_formula输出闭合解析表达式实现数值求解 符号回归一体化的 PDE 可解释求解流程。读完本文你将掌握 KAN 求解 PDE 的完整代码骨架、自动微分求二阶导数的技巧以及把训练好的网络翻译成数学公式的标准步骤。一、问题设定二维 Poisson 方程与 Dirichlet 边界条件本示例求解的偏微分方程为$$ \nabla^2 f(x,y) -2\pi^2\sin(\pi x)\sin(\pi y) $$定义域为 $x, y \in [-1, 1]$边界条件为 $f(-1,y)f(1,y)f(x,-1)f(x,1)0$对应的解析真解为$$ f(x,y)\sin(\pi x)\sin(\pi y) $$该设定十分巧妙真解本身是两个一元正弦函数的乘积而 KAN 的核心假设Kolmogorov-Arnold 表示定理恰好表明多元函数可以表示为一元函数的有序叠加与复合。因此用 KAN 求解该方程并在训练后把网络翻译回 $\sin(\pi x)\sin(\pi y)$是验证KAN 天然适合符号化解释 PDE 解这一命题的典型实验。二、环境准备与模型初始化示例代码首先导入依赖并创建 KAN 模型from kan import * import matplotlib.pyplot as plt from torch import autograd from tqdm import tqdm device torch.device(cuda if torch.cuda.is_available() else cpu) print(device) dim 2 np_i 21 # number of interior points (along each dimension) np_b 21 # number of boundary points (along each dimension) ranges [-1, 1] model KAN(width[2,2,1], grid5, k3, seed1, devicedevice)关键点说明from kan import *会从 kan/init.py 导入MultKAN及KAN别名和utils中的全部工具函数width[2,2,1]表示网络结构为 2 个输入$x, y$→ 2 个隐藏神经元 → 1 个输出$f(x,y)$grid5表示每条样条激活函数的初始网格区间数为 5k3表示使用 3 阶三次B 样条。网格与阶数相关实现见 kan/KANLayer.py 中的KANLayer.__init__seed1固定随机种子保证实验可复现设备优先使用 CUDA无 GPU 时回退到 CPU。三、通过自动微分构造 PDE 残差损失KAN 作为可微网络其输出对输入的导数可由torch.autograd直接获得。示例在 Notebook 内自定义了batch_jacobian用于对批量输入逐样本计算 Jacobiandef batch_jacobian(func, x, create_graphFalse): # x in shape (Batch, Length) def _func_sum(x): return func(x).sum(dim0) return autograd.functional.jacobian(_func_sum, x, create_graphcreate_graph).permute(1,0,2)该函数的思想是先把批量输出按样本维求和再对输入求 Jacobian得到形状为(Batch, Length, Length)的张量其中每个样本对应一个完整的 Jacobian 矩阵。这与仓库中 kan/utils.py 提供的batch_jacobianmodevector分支实现完全一致说明该写法是 pykan 的标准做法。随后定义真解与源项方程右端项# define solution sol_fun lambda x: torch.sin(torch.pi*x[:,[0]])*torch.sin(torch.pi*x[:,[1]]) source_fun lambda x: -2*torch.pi**2 * torch.sin(torch.pi*x[:,[0]])*torch.sin(torch.pi*x[:,[1]])3.1 内部采样点内部点在 $[-1,1]^2$ 上采样支持两种模式sampling_mode random # random or mesh x_mesh torch.linspace(ranges[0],ranges[1],stepsnp_i) y_mesh torch.linspace(ranges[0],ranges[1],stepsnp_i) X, Y torch.meshgrid(x_mesh, y_mesh, indexingij) if sampling_mode mesh: #mesh x_i torch.stack([X.reshape(-1,), Y.reshape(-1,)]).permute(1,0) else: #random x_i torch.rand((np_i**2,2))*2-1 x_i x_i.to(device)mesh模式在 $21\times21441$ 个均匀网格点上求值random模式在 $[-1,1]^2$ 内随机采样 441 个点注意示例注释中radnom为原文笔误实际判断逻辑为mesh之外一律走随机分支。3.2 边界采样点边界点取自四条边$x-1$、$x1$、$y-1$、$y1$# boundary, 4 sides helper lambda X, Y: torch.stack([X.reshape(-1,), Y.reshape(-1,)]).permute(1,0) xb1 helper(X[0], Y[0]) xb2 helper(X[-1], Y[0]) xb3 helper(X[:,0], Y[:,0]) xb4 helper(X[:,0], Y[:,-1]) x_b torch.cat([xb1, xb2, xb3, xb4], dim0) x_b x_b.to(device)这里X[0]与Y[0]对应 $x-1$ 边X[-1]对应 $x1$ 边X[:,0]与Y[:,-1]对应 $y$ 方向的两条边四条边各 21 个点共 84 个边界点。四、训练循环L-BFGS 自定义 closure训练采用二阶优化器 L-BFGS并启用 strong Wolfe 线搜索steps 20 alpha 0.01 log 1 def train(): optimizer LBFGS(model.parameters(), lr1, history_size10, line_search_fnstrong_wolfe, tolerance_grad1e-32, tolerance_change1e-32, tolerance_ys1e-32) pbar tqdm(range(steps), descdescription, ncols100) for _ in pbar: def closure(): global pde_loss, bc_loss optimizer.zero_grad() # interior loss sol sol_fun(x_i) sol_D1_fun lambda x: batch_jacobian(model, x, create_graphTrue)[:,0,:] sol_D1 sol_D1_fun(x_i) sol_D2 batch_jacobian(sol_D1_fun, x_i, create_graphTrue)[:,:,:] lap torch.sum(torch.diagonal(sol_D2, dim11, dim22), dim1, keepdimTrue) source source_fun(x_i) pde_loss torch.mean((lap - source)**2) # boundary loss bc_true sol_fun(x_b) bc_pred model(x_b) bc_loss torch.mean((bc_pred-bc_true)**2) loss alpha * pde_loss bc_loss loss.backward() return loss if _ % 5 0 and _ 50: model.update_grid_from_samples(x_i) optimizer.step(closure) sol sol_fun(x_i) loss alpha * pde_loss bc_loss l2 torch.mean((model(x_i) - sol)**2) if _ % log 0: pbar.set_description(pde loss: %.2e | bc loss: %.2e | l2: %.2e % (pde_loss.cpu().detach().numpy(), bc_loss.cpu().detach().numpy(), l2.cpu().detach().numpy())) train()该训练循环包含几个值得深入理解的技术点1. 二阶导数的递推构造。先对model求一阶 Jacobian 得到梯度场 $(\partial f/\partial x, \partial f/\partial y)$再对这个梯度场函数继续求 Jacobian 得到 Hessian 矩阵取 Hessian 的对角线元素并求和即得到拉普拉斯算子 $\nabla^2 f f_{xx} f_{yy}$lap torch.sum(torch.diagonal(sol_D2, dim11, dim22), dim1, keepdimTrue)注意create_graphTrue必须保留否则第二次求导无法对第一次求导结果继续反向传播。2. 两项损失的加权组合。内部点损失约束方程残差pde_loss mean((lap - source)^2)边界点损失约束边界条件bc_loss mean((bc_pred - bc_true)^2)总损失为loss alpha * pde_loss bc_loss其中alpha 0.01用于平衡两项尺度差异。3. 网格自适应更新。每 5 步调用一次model.update_grid_from_samples(x_i)让样条网格根据当前输入样本的分布自动重排提升样条逼近精度。其底层实现在 kan/MultKAN.py先对样本做一次前向得到各层激活self.acts再逐层调用 kan/KANLayer.py 的update_grid_from_samples重排网格节点。4. L-BFGS 需要 closure。优化器在每次optimizer.step(closure)时多次调用 closure 以进行线搜索因此 closure 内必须完成清零梯度 → 计算损失 → 反向传播 → 返回损失的完整流程。该 L-BFGS 实现位于 kan/LBFGS.py内部实现了 strong Wolfe 条件线搜索_strong_wolfe并支持history_size、tolerance_grad、tolerance_change、tolerance_ys等参数。运行 20 步后的典型输出原文档记录在 CUDA 环境下cuda checkpoint directory created: ./model saving model version 0.0 pde loss: 2.23e00 | bc loss: 5.99e-03 | l2: 3.78e-03 : 100%|███████| 20/20 [00:2200:00, 1.11s/it]训练日志同时显示模型首次保存检查点到./model目录saving model version 0.0这是 pykan 自动保存机制auto_saveTrue在起作用每个版本对应 model/ 目录中的0.0_config.yml、0.0_state与0.0_cache_data文件。五、可视化训练结果训练完成后直接调用model.plot()可视化网络结构model.plot(beta10)该图展示了训练后 KAN 的各层激活函数形状样条曲线beta10控制激活函数曲线的颜色映射与线条粗细。plot的完整签名与参数说明见 kan/MultKAN.py。六、符号化解释fix_symbolic 与 symbolic_formula这是本示例最核心的亮点把数值网络翻译成解析公式。6.1 将激活函数固定为符号函数由于真解 $\sin(\pi x)\sin(\pi y)$ 是一元正弦函数与线性函数的组合示例将第一层 4 个激活函数全部固定为线性函数x第二层输出层固定为正弦函数sin示例代码中注释说明该步对超参数较敏感model.fix_symbolic(0,0,0,x) model.fix_symbolic(0,0,1,x) model.fix_symbolic(0,1,0,x) model.fix_symbolic(0,1,1,x)fix_symbolic的完整签名与参数语义见 kan/MultKAN.py参数含义默认值l层索引—i输入神经元索引—j输出神经元索引—fun_name符号函数名如x、sin、cos、exp等—fit_params_bool是否通过拟合确定仿射参数a, b, c, dTruea_range/b_range仿射参数a、b的扫描范围(-10, 10)verbose是否打印拟合信息Truerandom是否随机初始化仿射参数Falselog_history是否记录历史True调用时如果fit_params_boolTrue会取该激活的输入样本x与样条输出y即self.acts[l][:, i]与self.spline_postacts[l][:, j, i]通过 kan/utils.py 的fit_params在a_range/b_range内网格扫描拟合最优仿射参数并返回拟合优度r2。底层实现见 kan/Symbolic_KANLayer.py 的fix_symbolic。原文档记录的四次固定操作输出如下r2 is 0.8357976675033569 r2 is not very high, please double check if you are choosing the correct symbolic function. saving model version 0.1 r2 is 0.8300805687904358 r2 is not very high, please double check if you are choosing the correct symbolic function. saving model version 0.2 r2 is 0.8376883268356323 r2 is not very high, please double check if you are choosing the correct symbolic function. saving model version 0.3 r2 is 0.8372848629951477 r2 is not very high, please double check if you are choosing the correct symbolic function. saving model version 0.4可以看到单个激活替换后的r2约为 0.830.84并不算高——因为此时仿射参数尚未经过联合训练精调且每次替换后都会保存一个新版本检查点0.10.4。原文档随后输出tensor(0.8373)对应符号化后的整体拟合优度。这解释了文档中quite sensitive to hyperparams的告诫符号化环节需要后续训练配合才能收敛到机器精度。6.2 符号化后继续训练达到机器精度所有激活变为符号函数后仿射参数仍然是可训练的因此继续调用train()精调这些参数train()原文档记录此时前 10 步日志为pde loss: 1.71e01 | bc loss: 1.14e-02 | l2: 1.37e-01并展示了一段KeyboardInterrupt的 Traceback涉及 kan/LBFGS.py 中_strong_wolfe→_directional_evaluate→closure的调用链。这段 Traceback 并非错误而是作者手动中断了训练过程——它恰好揭示了 L-BFGS 在step内部通过_directional_evaluate反复调用用户 closure 进行强 Wolfe 线搜索的执行路径。原文档指出充分训练后模型可以达到机器精度machine precision即符号化后的 KAN 能精确复现真解。6.3 输出闭合解析公式最后打印符号化后的公式formula model.symbolic_formula()[0][0] ex_round(formula,6)symbolic_formula的实现见 kan/MultKAN.py它遍历每一层的符号激活函数与仿射参数 $(a, b, c, d)$用 sympy 表达式逐层组装出完整公式ex_round则将表达式中的浮点数统一四舍五入到指定位数。原文档最终得到的公式为$$ \displaystyle - 0.5 \sin{\left(3.141592 x_{1} 3.141593 x_{2} - 4.712389 \right)} 0.5 \sin{\left(3.141593 x_{1} - 3.141592 x_{2} 1.570797 \right)} $$利用三角恒等式 $\sin(A)-\sin(B)2\cos\frac{AB}{2}\sin\frac{A-B}{2}$ 可以化简令 $A \pi x_1 \pi x_2 - \frac{3\pi}{2}$$B \pi x_1 - \pi x_2 \frac{\pi}{2}$则 $\frac{AB}{2} \pi x_1 - \frac{\pi}{2}$$\frac{A-B}{2} \pi x_2 - \pi$于是 $-0.5\sin A 0.5\sin B \cos(\pi x_1 - \frac{\pi}{2})\sin(\pi x_2 - \pi) \sin(\pi x_1)\sin(\pi x_2)$。也就是说KAN 通过符号回归精确恢复了真解 $f(x,y)\sin(\pi x)\sin(\pi y)$——这正是本示例PDE 解释interpretation的含义所在。七、完整流程总结与实验要点阶段关键操作对应源码/文档位置建模KAN(width[2,2,1], grid5, k3, seed1)kan/MultKAN.py采样mesh / random 内部点 四边边界点docs/Example/Example_6_PDE_interpretation.rst损失自动微分求拉普拉斯 边界 MSE 加权batch_jacobian与 kan/utils.py 一致优化L-BFGS strong Wolfe 线搜索closure 模式kan/LBFGS.py网格每 5 步update_grid_from_sampleskan/MultKAN.py符号化fix_symbolic替换激活为x/sinkan/MultKAN.py解释symbolic_formulaex_round输出公式kan/MultKAN.py实操要点回顾create_graphTrue不能省略否则无法对二阶导数继续反传alpha平衡权重PDE 残差与边界条件的量纲不同alpha0.01在本文设定下效果良好实际问题中需按损失尺度调整符号化后必须继续训练fix_symbolic只是给出仿射参数初值只有联合精调才能逼近机器精度检查点自动保存每次fix_symbolic会以新版本号保存模型可通过model.checkout(version)回溯历史版本公式化简验证symbolic_formula输出的表达式可能包含冗余项如本例的相位偏移可结合 sympy 化简并与真解对照验证 KAN 是否学到了真实的物理规律。对于更复杂的 PDE 或高维问题可以复用本文的自动微分残差 L-BFGS 符号化三件套仅需替换source_fun、边界条件与采样点生成逻辑若希望自动挑选符号函数还可参考model.auto_symbolic()与model.suggest_symbolic()同样位于 kan/MultKAN.py它们基于r2与复杂度打分在预置函数库中自动搜索最佳符号候选将人工指定符号升级为自动符号发现。【免费下载链接】pykanKolmogorov Arnold Networks项目地址: https://gitcode.com/GitHub_Trending/pyk/pykan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/6 3:18:18

React Native集成YOLO11实现移动端实时物体检测

1. React Native与YOLO11结合的背景与价值移动端实时物体检测正在成为计算机视觉领域的重要应用方向。传统方案通常需要将图像数据上传至云端服务器进行处理,这种方式存在延迟高、隐私风险大、网络依赖性强等明显缺陷。而React Native作为跨平台移动开发框架&#x…

2026/11/6 6:19:59

Node.js+Vue+ECharts:学生课外活动管理系统可视化大屏实战

先用一句话讲清楚这个项目是干什么的:这是一套以 Node.js 做后端、Vue 做前端的学生课外活动管理系统,在完成报名、审核、积分等常规业务的同时,单独抽出一块“数据可视化大屏分析系统”,用图表方式把活动分布、参与热度、学院排名…

2026/11/7 11:13:49

电监电工证查询千万别踩坑 你知道合格标准和通过率吗

电监电工证查询千万别踩坑 你知道合格标准和通过率吗 怕考不过白交培训费?别急,这波操作你必须搞懂。电监电工证查询是不少电工从业者的刚需,但很多人因为不了解考试流程、合格标准,最终在培训费上吃了亏。本文就围绕【电监电工证查询】这个关键词,告诉…

2026/11/7 11:13:49

建设厅特种工都有哪些官方回应外省证书能否转回

建设厅特种工都有哪些官方回应外省证书能否转回 之前考的证在外省能不能转过来?你不是一个人,这个问题在建筑工人群体中普遍存在,特别是在驻马店这样的地级市,很多工人跨省务工后,常常面临证书归属地和使用地不一致的问题。 官方回应…

2026/11/7 11:13:49

电工证计算练习题官方回应怎么找?别再被中介坑了

电工证计算练习题官方回应怎么找?别再被中介坑了 你是不是也遇到过这种情况:想考电工证,网上一搜全是培训机构,价格五花八门,质量参差不齐,生怕一不小心就被中介坑了?别急,今天咱们就来聊聊【电工证计算练习题】的那些事儿,顺便说说怎么避坑,怎么找…

2026/11/7 11:13:49

电工证计算练习题保姆级教程:从考试到实操全掌握

电工证计算练习题保姆级教程:从考试到实操全掌握 之前考的证在外省能不能转过来?这个问题,几乎每个准备考电工证的小伙伴都会问。其实, 电工证计算练习题 不仅仅是考试的重点,更是你能否顺利上岗、避免被查出无证作业的关键。今天就从…

2026/11/7 11:13:49

城步考电工证怎么考不被坑 电子证书怎么查最靠谱

城步考电工证怎么考不被坑 电子证书怎么查最靠谱 你是不是也在城步这边,听说考电工证能找工作、能涨工资,但又担心不知道去哪报名,怕被中介坑?别急,咱们今天就从头聊透透,告诉你怎么 城步考电工证 ,怎么查 电子证书 ,还能避坑不花冤枉钱。…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/7 0:03:08

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科 实操考试心里没底怕挂科?你不是一个人。特别是在郑州这样的城市,很多施工企业负责人和一线作业人员在报考电工证和钳工证时都面临着同样的困惑。到底该考哪个证?哪个更适合自己?哪个证书…

2026/11/7 0:03:08

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱?

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到太多了,今天就拿广西电工证办理流程来具体说说,别再走弯路了。广西电工证的报考、复审、继续教育这些环节,如果你不了解,真的会吃大亏,尤其对于从…

2026/11/7 0:03:08

电气电工证都有哪些保姆级教程

电气电工证都有哪些保姆级教程 你是不是正愁不知道去哪报名,怕被中介坑?别急,这篇保姆级教程专为河南初次报考人员准备,帮你搞清楚 电气电工证都有哪些 ,以及如何避开那些坑。 电气电工证都有哪些?别被五花八门的证书搞懵了…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑