热传导仿真-主题065-物理信息神经网络求解热方程
主题065:物理信息神经网络(PINN)求解热方程
Physics-Informed Neural Networks for Solving Heat Conduction Equations
一、引言
1.1 背景与动机
在工程仿真领域,热传导问题的数值求解一直是一个核心课题。传统的数值方法,如有限差分法(FDM)、有限元法(FEM)和有限体积法(FVM),虽然在工程实践中取得了巨大成功,但它们也面临着一些固有的挑战:网格生成复杂、高维问题"维度灾难"、逆问题求解困难等。
近年来,深度学习技术的飞速发展为科学计算带来了新的范式。物理信息神经网络(Physics-Informed Neural Networks, PINN) 作为一种融合物理定律与数据驱动的方法,正在 revolutionize 我们求解偏微分方程(PDE)的方式。PINN 的核心思想是将物理方程作为约束嵌入神经网络的损失函数中,使得网络在拟合数据的同时,严格满足物理定律。


1.2 什么是 PINN?
PINN 是由 Raissi 等人于 2019 年系统提出的一种深度学习方法。其基本框架包含三个关键要素:
- 神经网络近似:使用深度神经网络 NN(x,t;θ)NN(x, t; \theta)NN(x,t;θ) 来近似未知函数 u(x,t)u(x, t)u(x,t)
- 自动微分求导:利用深度学习框架(如 PyTorch、TensorFlow)的自动微分功能,计算网络输出的各阶导数
- 物理约束损失:将 PDE 残差、初始条件和边界条件纳入损失函数
1.3 PINN 的优势
相比传统数值方法,PINN 具有以下显著优势:
| 特性 | 传统方法 | PINN |
|---|---|---|
| 网格需求 | 需要离散网格 | 无网格,连续解 |
| 维度扩展 | 维度灾难 | 高维问题友好 |
| 逆问题 | 需要迭代求解 | 端到端求解 |
| 数据融合 | 难以结合实验数据 | 自然融合数据与物理 |
| 计算效率 | 单次求解快 | 训练慢,推理快 |
1.4 本教程学习目标
通过本教程的学习,读者将能够:
- 理解 PINN 的基本原理和数学框架
- 掌握使用 PyTorch 实现基础 PINN 的方法
- 学会处理硬约束边界条件
- 实现自适应权重策略平衡多任务学习
- 将 PINN 扩展到二维稳态问题
- 使用 PINN 求解逆问题(参数辨识)
二、理论基础
2.1 热传导方程回顾
一维非稳态热传导方程(扩散方程)的标准形式为:
∂T∂t=α∂2T∂x2 \frac{\partial T}{\partial t} = \alpha \frac{\partial^2 T}{\partial x^2} ∂t∂T=α∂x2∂2T
其中:
- T(x,t)T(x, t)T(x,t) 是温度场
- α\alphaα 是热扩散系数
- x∈[0,L]x \in [0, L]x∈[0,L] 是空间坐标
- t∈[0,tfinal]t \in [0, t_{final}]t∈[0,tfinal] 是时间
为了获得唯一解,需要指定:
初始条件(Initial Condition, IC):
T(x,0)=T0(x)T(x, 0) = T_0(x)T(x,0)=T0(x)
边界条件(Boundary Condition, BC):
- Dirichlet 条件:T(0,t)=TLT(0, t) = T_LT(0,t)=TL, T(L,t)=TRT(L, t) = T_RT(L,t)=TR
- Neumann 条件:∂T∂x∣x=0=qL\frac{\partial T}{\partial x}\big|_{x=0} = q_L∂x∂T x=0=qL
- Robin 条件:−k∂T∂x∣x=0=h(T−T∞)-k\frac{\partial T}{\partial x}\big|_{x=0} = h(T - T_\infty)−k∂x∂T x=0=h(T−T∞)
2.2 PINN 的数学框架
2.2.1 神经网络近似
设神经网络 N N(x,t;θ)N\!N(x, t; \theta)NN(x,t;θ) 以空间坐标 xxx 和时间 ttt 为输入,输出温度预测值 T^\hat{T}T^。网络参数 θ\thetaθ 包括所有层的权重和偏置。
2.2.2 自动微分计算导数
利用自动微分(Automatic Differentiation, AD),我们可以精确计算网络输出的各阶导数:
T^t=∂N N∂t,T^x=∂N N∂x,T^xx=∂2N N∂x2 \hat{T}_t = \frac{\partial N\!N}{\partial t}, \quad \hat{T}_x = \frac{\partial N\!N}{\partial x}, \quad \hat{T}_{xx} = \frac{\partial^2 N\!N}{\partial x^2} T^t=∂t∂NN,T^x=∂x∂NN,T^xx=∂x2∂2NN
2.2.3 损失函数构造
PINN 的损失函数由三部分组成:
L(θ)=λresLres+λicLic+λbcLbc \mathcal{L}(\theta) = \lambda_{res} \mathcal{L}_{res} + \lambda_{ic} \mathcal{L}_{ic} + \lambda_{bc} \mathcal{L}_{bc} L(θ)=λresLres+λicLic+λbcLbc
PDE 残差损失:
Lres=1Nres∑i=1Nres∣T^t(xi,ti)−αT^xx(xi,ti)∣2\mathcal{L}_{res} = \frac{1}{N_{res}} \sum_{i=1}^{N_{res}} \left| \hat{T}_t(x_i, t_i) - \alpha \hat{T}_{xx}(x_i, t_i) \right|^2Lres=Nres1i=1∑Nres
T^t(xi,ti)−αT^xx(xi,ti)
2
初始条件损失:
Lic=1Nic∑i=1Nic∣T^(xi,0)−T0(xi)∣2\mathcal{L}_{ic} = \frac{1}{N_{ic}} \sum_{i=1}^{N_{ic}} \left| \hat{T}(x_i, 0) - T_0(x_i) \right|^2Lic=Nic1i=1∑Nic
T^(xi,0)−T0(xi)
2
边界条件损失:
Lbc=1Nbc∑i=1Nbc∣T^(xbc,ti)−Tbc(ti)∣2\mathcal{L}_{bc} = \frac{1}{N_{bc}} \sum_{i=1}^{N_{bc}} \left| \hat{T}(x_{bc}, t_i) - T_{bc}(t_i) \right|^2Lbc=Nbc1i=1∑Nbc
T^(xbc,ti)−Tbc(ti)
2
2.3 网络架构设计
对于热传导问题,常用的网络架构包括:
全连接网络(Fully Connected Network, FCN):
输入层 (x, t) → 隐藏层1 (64神经元) → 隐藏层2 (64神经元) → 隐藏层3 (64神经元) → 输出层 (T)
激活函数选择:
- Tanh:平滑可导,适合 PINN
- Sin:周期性问题的良好选择
- Swish:在某些情况下表现更好
网络深度与宽度:
- 深度:通常 3-8 层隐藏层
- 宽度:每层 32-256 神经元
- 问题越复杂,网络规模越大
2.4 训练策略
2.4.1 采样策略
残差点采样:
- 均匀网格采样:规则但可能遗漏关键区域
- 随机采样:简单但分布不均
- 自适应采样:根据残差大小动态调整
边界/初始点采样:
- 在边界和初始时刻密集采样
- 通常比内部残差点更密集
2.4.2 优化算法
Adam 优化器:
- 学习率:通常 10−310^{-3}10−3 到 10−410^{-4}10−4
- 学习率衰减:每 1000-5000 轮衰减 0.5-0.9 倍
L-BFGS 精调:
- 在 Adam 收敛后使用
- 二阶优化,收敛更精确
2.4.3 损失权重调优
不同损失项的量级可能差异巨大,需要合理设置权重:
λres:λic:λbc=1:10:10∼1:100:100 \lambda_{res} : \lambda_{ic} : \lambda_{bc} = 1 : 10 : 10 \sim 1 : 100 : 100 λres:λic:λbc=1:10:10∼1:100:100
三、环境准备
3.1 依赖库安装
# 创建虚拟环境(推荐)
conda create -n pinn python=3.9
conda activate pinn
# 安装核心依赖
pip install torch numpy matplotlib scipy
# 可选:安装 Jupyter 用于交互式开发
pip install jupyter notebook
3.2 硬件要求
- CPU:任何现代 CPU 均可运行
- GPU:推荐 NVIDIA GPU 加速训练(CUDA 支持)
- 内存:建议 8GB 以上
3.3 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import grad
# 设置随机种子保证可重复性
torch.manual_seed(42)
np.random.seed(42)
# 设备配置
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"使用设备: {device}")
四、案例实战
案例1:基础 PINN 求解 1D 非稳态热方程
4.1.1 问题描述
考虑一维热传导问题:
- 域:x∈[0,1]x \in [0, 1]x∈[0,1], t∈[0,0.5]t \in [0, 0.5]t∈[0,0.5]
- 热扩散系数:α=0.1\alpha = 0.1α=0.1
- 初始条件:T(x,0)=sin(πx)T(x, 0) = \sin(\pi x)T(x,0)=sin(πx)
- 边界条件:T(0,t)=T(1,t)=0T(0, t) = T(1, t) = 0T(0,t)=T(1,t)=0
解析解:
T(x,t)=sin(πx)e−απ2tT(x, t) = \sin(\pi x) e^{-\alpha \pi^2 t}T(x,t)=sin(πx)e−απ2t
4.1.2 网络定义
class BasicPINN(nn.Module):
"""基础PINN网络结构"""
def __init__(self, layers):
super(BasicPINN, self).__init__()
self.layers = nn.ModuleList()
for i in range(len(layers) - 1):
self.layers.append(nn.Linear(layers[i], layers[i+1]))
if i < len(layers) - 2:
self.layers.append(nn.Tanh())
def forward(self, x, t):
"""前向传播"""
inputs = torch.cat([x, t], dim=1)
for layer in self.layers:
inputs = layer(inputs)
return inputs
4.1.3 训练过程详解
def basic_pinn_solver():
# 问题参数
L = 1.0
T_final = 0.5
alpha = 0.1
# 创建网络 [2, 64, 64, 64, 1]
layers = [2, 64, 64, 64, 1]
model = BasicPINN(layers).to(device)
# 优化器配置
optimizer = optim.Adam(model.parameters(), lr=0.001)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=2000, gamma=0.5)
# 训练循环
n_epochs = 10000
for epoch in range(n_epochs):
model.train()
optimizer.zero_grad()
# 1. 内部残差点采样
x_res = torch.rand(5000, 1, device=device) * L
t_res = torch.rand(5000, 1, device=device) * T_final
x_res.requires_grad_(True)
t_res.requires_grad_(True)
# 计算网络输出和导数
T_res = model(x_res, t_res)
T_t = grad(T_res, t_res, grad_outputs=torch.ones_like(T_res),
create_graph=True)[0]
T_x = grad(T_res, x_res, grad_outputs=torch.ones_like(T_res),
create_graph=True)[0]
T_xx = grad(T_x, x_res, grad_outputs=torch.ones_like(T_x),
create_graph=True)[0]
# PDE残差损失
residual = T_t - alpha * T_xx
loss_res = torch.mean(residual**2)
# 2. 初始条件损失
x_ic = torch.rand(200, 1, device=device) * L
t_ic = torch.zeros(200, 1, device=device)
T_ic_pred = model(x_ic, t_ic)
T_ic_true = torch.sin(np.pi * x_ic)
loss_ic = torch.mean((T_ic_pred - T_ic_true)**2)
# 3. 边界条件损失
t_bc = torch.rand(200, 1, device=device) * T_final
x_bc_left = torch.zeros(200, 1, device=device)
x_bc_right = torch.ones(200, 1, device=device) * L
T_bc_left = model(x_bc_left, t_bc)
T_bc_right = model(x_bc_right, t_bc)
loss_bc = torch.mean(T_bc_left**2) + torch.mean(T_bc_right**2)
# 总损失
loss = loss_res + 10.0 * loss_ic + 10.0 * loss_bc
loss.backward()
optimizer.step()
scheduler.step()
4.1.4 代码深度解析
关键步骤1:自动微分计算导数
T_t = grad(T_res, t_res, grad_outputs=torch.ones_like(T_res), create_graph=True)[0]
这行代码使用 PyTorch 的自动微分功能计算 ∂T∂t\frac{\partial T}{\partial t}∂t∂T。create_graph=True 允许二阶导数的计算。
关键步骤2:PDE 残差计算
residual = T_t - alpha * T_xx
loss_res = torch.mean(residual**2)
计算 PDE 的残差,理想情况下残差应为零。通过最小化残差平方和,网络学习满足物理方程。
关键步骤3:多任务损失加权
loss = loss_res + 10.0 * loss_ic + 10.0 * loss_bc
不同损失项的量级可能不同,需要通过权重平衡。通常边界和初始条件的权重更大。
4.1.5 运行结果
训练完成后,模型达到以下精度:
- L2 相对误差:8.38×10−48.38 \times 10^{-4}8.38×10−4
- 训练轮数:10,000
- 最终损失:4.02×10−54.02 \times 10^{-5}4.02×10−5
可视化结果包括:
- 训练损失曲线(对数坐标)
- PINN 预测的温度场分布
- 解析解对比
- 绝对误差分布
- 不同时刻的温度剖面对比
- PDE 残差分布

案例2:硬约束 PINN(精确满足边界条件)
4.2.1 问题与动机
在基础 PINN 中,边界条件是通过软约束(损失函数)实现的。这存在两个问题:
- 边界处可能存在误差
- 需要额外的损失项和权重调优
硬约束 PINN 通过数学构造,使网络输出自动满足边界条件。
4.2.2 硬约束构造方法
对于齐次 Dirichlet 边界条件 T(0,t)=T(L,t)=0T(0, t) = T(L, t) = 0T(0,t)=T(L,t)=0,可以构造:
T(x,t)=x(1−x)⋅NN(x,t)T(x, t) = x(1-x) \cdot NN(x, t)T(x,t)=x(1−x)⋅NN(x,t)
这样,无论神经网络 NNNNNN 输出什么值,边界处 x=0x=0x=0 和 x=1x=1x=1 的温度自动为零。
4.2.3 网络实现
class HardConstrainedPINN(nn.Module):
"""硬约束PINN - 通过构造自动满足边界条件"""
def __init__(self, layers):
super(HardConstrainedPINN, self).__init__()
self.net = BasicPINN(layers)
def forward(self, x, t):
"""
硬约束构造: T(x,t) = x*(1-x)*NN(x,t)
自动满足: T(0,t)=0, T(1,t)=0
"""
nn_output = self.net(x, t)
T = x * (1 - x) * nn_output
return T
4.2.4 训练简化
由于边界条件已自动满足,损失函数只需包含:
# 仅需PDE残差和初始条件
loss = loss_res + 10.0 * loss_ic
4.2.5 结果对比
| 指标 | 基础PINN | 硬约束PINN |
|---|---|---|
| L2相对误差 | 8.38×10−48.38 \times 10^{-4}8.38×10−4 | 7.65×10−57.65 \times 10^{-5}7.65×10−5 |
| 边界误差 | 软约束 | 精确为零 |
| 损失项数 | 3项 | 2项 |
| 收敛速度 | 标准 | 更快 |
硬约束 PINN 的精度提高了约 10倍!

案例3:自适应权重 PINN
4.3.1 问题背景
在多任务学习中,不同损失项的梯度量级可能差异巨大:
- PDE 残差损失:可能很小(网络已较好满足方程)
- 初始条件损失:可能需要更多关注
- 边界条件损失:可能需要调整
固定权重难以适应训练过程中的动态变化。
4.3.2 自适应权重策略
核心思想:动态调整权重,使各损失项对梯度的贡献平衡。
更新规则:
λi∝1∣∇θLi∣\lambda_i \propto \frac{1}{|\nabla_{\theta} \mathcal{L}_i|}λi∝∣∇θLi∣1
具体实现:
def update_weights(self, loss_res, loss_ic, loss_bc):
# 获取各损失的当前值(近似梯度)
grad_res = loss_res.item()
grad_ic = loss_ic.item()
grad_bc = loss_bc.item()
# 计算自适应权重
total = grad_res + grad_ic + grad_bc + 1e-8
self.lambda_res = total / (grad_res + 1e-8)
self.lambda_ic = total / (grad_ic + 1e-8)
self.lambda_bc = total / (grad_bc + 1e-8)
# 归一化
sum_lambda = self.lambda_res + self.lambda_ic + self.lambda_bc
self.lambda_res /= sum_lambda
self.lambda_ic /= sum_lambda
self.lambda_bc /= sum_lambda
4.3.3 训练过程
class AdaptiveWeightPINN:
def __init__(self, layers, alpha=0.1):
self.model = BasicPINN(layers).to(device)
self.alpha = alpha
self.optimizer = optim.Adam(self.model.parameters(), lr=0.001)
# 初始化权重
self.lambda_res = 1.0
self.lambda_ic = 1.0
self.lambda_bc = 1.0
def train(self, n_epochs=10000):
for epoch in range(n_epochs):
# 计算各损失分量
loss_res, loss_ic, loss_bc = self.compute_losses(...)
# 每1000轮更新权重
if epoch % 1000 == 0 and epoch > 0:
self.update_weights(loss_res, loss_ic, loss_bc)
# 加权总损失
loss = (self.lambda_res * loss_res +
self.lambda_ic * loss_ic +
self.lambda_bc * loss_bc)
loss.backward()
self.optimizer.step()
4.3.4 权重演化分析
训练过程中,权重自适应调整:
- 初始阶段:各权重相对均衡
- 中期阶段:根据损失变化动态调整
- 后期阶段:收敛到稳定比例
典型权重演化:
Epoch 2000: λ_res=0.105, λ_ic=0.629, λ_bc=0.267
Epoch 4000: λ_res=0.010, λ_ic=0.761, λ_bc=0.230
Epoch 6000: λ_res=0.444, λ_ic=0.378, λ_bc=0.178
Epoch 8000: λ_res=0.013, λ_ic=0.938, λ_bc=0.049
4.3.5 方法优势
- 自动平衡:无需手动调参
- 适应性强:适应不同训练阶段
- 提高稳定性:避免某一损失项主导
- 改善收敛:各损失项同步下降

案例4:二维稳态热传导 PINN
4.4.1 问题描述
考虑二维 Laplace 方程:
∇2T=∂2T∂x2+∂2T∂y2=0\nabla^2 T = \frac{\partial^2 T}{\partial x^2} + \frac{\partial^2 T}{\partial y^2} = 0∇2T=∂x2∂2T+∂y2∂2T=0
在域 [0,1]×[0,1][0, 1] \times [0, 1][0,1]×[0,1] 上,边界条件:
- T(0,y)=0T(0, y) = 0T(0,y)=0, T(1,y)=0T(1, y) = 0T(1,y)=0
- T(x,0)=sin(πx)T(x, 0) = \sin(\pi x)T(x,0)=sin(πx), T(x,1)=0T(x, 1) = 0T(x,1)=0
解析解:
T(x,y)=sin(πx)sinh(π(1−y))sinh(π)T(x, y) = \sin(\pi x) \frac{\sinh(\pi(1-y))}{\sinh(\pi)}T(x,y)=sin(πx)sinh(π)sinh(π(1−y))
4.4.2 网络架构
class PINN2DSteady(nn.Module):
"""二维稳态热传导PINN"""
def __init__(self, layers):
super(PINN2DSteady, self).__init__()
self.net = BasicPINN(layers)
def forward(self, x, y):
inputs = torch.cat([x, y], dim=1)
return self.net(inputs[:, 0:1], inputs[:, 1:2])
4.4.3 损失函数构造
# 内部残差
T_res = model(x_res, y_res)
T_x = grad(T_res, x_res, grad_outputs=torch.ones_like(T_res), create_graph=True)[0]
T_y = grad(T_res, y_res, grad_outputs=torch.ones_like(T_res), create_graph=True)[0]
T_xx = grad(T_x, x_res, grad_outputs=torch.ones_like(T_x), create_graph=True)[0]
T_yy = grad(T_y, y_res, grad_outputs=torch.ones_like(T_y), create_graph=True)[0]
residual = T_xx + T_yy # Laplace方程
loss_res = torch.mean(residual**2)
# 四条边界的条件
loss_bc_left = torch.mean(model(torch.zeros(N, 1), y_bc)**2)
loss_bc_right = torch.mean(model(torch.ones(N, 1), y_bc)**2)
loss_bc_bottom = torch.mean((model(x_bc, torch.zeros(N, 1)) - torch.sin(np.pi * x_bc))**2)
loss_bc_top = torch.mean(model(x_bc, torch.ones(N, 1))**2)
loss_bc = loss_bc_left + loss_bc_right + loss_bc_bottom + loss_bc_top
loss = loss_res + 10.0 * loss_bc
4.4.4 可视化结果
二维问题的可视化包括:
- 温度场等高线图
- 三维表面图
- 中心线温度分布对比
- 误差分布图
4.4.5 扩展到复杂几何
对于复杂几何域,可以使用:
- 距离函数:T=ϕ(x,y)⋅NN(x,y)+TbcT = \phi(x, y) \cdot NN(x, y) + T_{bc}T=ϕ(x,y)⋅NN(x,y)+Tbc,其中 ϕ\phiϕ 是到边界的距离
- 区域采样:仅在域内采样
- 水平集方法:隐式表示边界
案例5:逆问题 PINN(参数辨识)
4.5.1 逆问题定义
正问题:已知参数 α\alphaα,求解温度场 T(x,t)T(x, t)T(x,t)
逆问题:从观测数据 {xi,ti,Tiobs}\{x_i, t_i, T_i^{obs}\}{xi,ti,Tiobs} 辨识参数 α\alphaα
4.5.2 逆问题 PINN 框架
将待辨识参数作为可训练变量:
class InversePINN(nn.Module):
def __init__(self, layers):
super(InversePINN, self).__init__()
self.net = BasicPINN(layers)
# 待辨识的参数
self.alpha = nn.Parameter(torch.tensor([0.05]))
def forward(self, x, t):
return self.net(x, t)
4.5.3 损失函数设计
逆问题需要三类损失:
# 1. PDE残差(物理约束)
residual = T_t - model.alpha * T_xx
loss_res = torch.mean(residual**2)
# 2. 初始条件
loss_ic = torch.mean((T_ic_pred - T_true)**2)
# 3. 数据拟合(驱动参数更新)
T_data_pred = model(x_obs, t_obs)
loss_data = torch.mean((T_data_pred - T_obs)**2)
# 总损失
loss = loss_res + 10.0 * loss_ic + 100.0 * loss_data
4.5.4 数据生成(模拟实验)
def generate_observation_data(alpha, n_points=100, noise_level=0.02):
"""生成带噪声的合成观测数据"""
np.random.seed(42)
x_obs = np.random.uniform(0.1, 0.9, n_points)
t_obs = np.random.uniform(0.05, T_final, n_points)
# 解析解
T_exact = np.sin(np.pi * x_obs) * np.exp(-alpha * np.pi**2 * t_obs)
# 添加噪声
noise = np.random.normal(0, noise_level * np.max(np.abs(T_exact)), n_points)
T_obs = T_exact + noise
return x_obs, t_obs, T_obs, T_exact
4.5.5 辨识结果
| 参数 | 数值 |
|---|---|
| 真实值 | 0.1000 |
| 初始猜测 | 0.0500 |
| 辨识结果 | 0.0987 |
| 相对误差 | 1.3% |
参数收敛曲线显示,经过约 8000 轮训练,辨识值收敛到真实值附近。
4.5.6 应用价值
逆问题 PINN 在工程中具有重要价值:
- 材料热物性测量:从温度响应反推导热系数
- 无损检测:识别材料内部缺陷
- 数字孪生:实时校准模型参数
- 故障诊断:监测设备运行状态
五、高级主题
5.1 网络架构改进
5.1.1 残差连接(ResNet)
class ResidualBlock(nn.Module):
def __init__(self, width):
super().__init__()
self.fc1 = nn.Linear(width, width)
self.fc2 = nn.Linear(width, width)
self.activation = nn.Tanh()
def forward(self, x):
residual = x
out = self.activation(self.fc1(x))
out = self.fc2(out)
return self.activation(out + residual)
5.1.2 Fourier 特征嵌入
对于高频问题,使用 Fourier 特征映射:
class FourierFeature(nn.Module):
def __init__(self, input_dim, mapping_size=256, scale=10):
super().__init__()
self.B = torch.randn((input_dim, mapping_size)) * scale
def forward(self, x):
x_proj = 2 * np.pi * x @ self.B
return torch.cat([torch.sin(x_proj), torch.cos(x_proj)], dim=-1)
5.2 训练技巧
5.2.1 学习率调度
# 余弦退火
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10000, eta_min=1e-6)
# 预热 + 衰减
scheduler = optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.01,
total_steps=10000)
5.2.2 梯度裁剪
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
5.2.3 混合精度训练
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
loss = compute_loss(...)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
5.3 误差分析与验证
5.3.1 相对 L2 误差
def relative_l2_error(pred, true):
return torch.norm(pred - true) / torch.norm(true)
5.3.2 残差可视化
# 计算残差分布
residual = T_t - alpha * T_xx
plt.contourf(X, T, np.abs(residual), levels=50, cmap='YlOrRd')
plt.colorbar(label='|Residual|')
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)