PyTorch物理信息神经网络批量输出值一致问题求助
物理信息神经网络(PINN)输出批量样本值全相同问题排查
我用PyTorch实现了一个物理信息神经网络(PINN),输入是距离x和时间t,输出是h和q的预测值。现在遇到一个问题:神经网络对批量内的每个输入样本,输出的h和q值完全相同。
训练过程中,输出值会随迭代次数变化,损失值也在持续降低,说明训练循环本身是正常运行的。怀疑问题出在数据预处理或网络架构的编码上。
训练步骤0和1000的输出结果(值随迭代变化):

神经网络架构定义
import torch.nn as nn class FCN(nn.Module): def __init__(self, N_INPUT, N_OUTPUT, N_HIDDEN, N_LAYERS): super().__init__() activation = nn.Tanh self.fcs = nn.Sequential( nn.Linear(N_INPUT, N_HIDDEN), activation() ) self.fch = nn.Sequential(*[ nn.Sequential( nn.Linear(N_HIDDEN, N_HIDDEN), activation() ) for _ in range(N_LAYERS - 1) ]) self.fce = nn.Linear(N_HIDDEN, N_OUTPUT) # Output layer def forward(self, x, t): inputs = torch.cat([x, t], axis = 1) inputs = self.fcs(inputs) inputs = self.fch(inputs) outputs = self.fce(inputs) return outputs pinn = FCN(2, 2, 9, 12)
输入定义
import torch x_colloc = torch.linspace(0, 300, 500).view(-1,1).requires_grad_(True) t_colloc = torch.linspace(0, 10, 500).view(-1,1).requires_grad_(True)
输入x范围是0到300,t范围是0到10,但每次迭代中,批量内所有样本的输出值均相同,如上述图表所示。
训练循环定义
for i in range (200000): optimiser.zero_grad() colloc_output = pinn(x_colloc, t_colloc) h_hat, q_hat = colloc_output[:,0], colloc_output[:,1] dq_dt = torch.autograd.grad(q_hat, t_colloc, torch.ones_like(q_hat), create_graph=True)[0] dq_dx = torch.autograd.grad(q_hat, x_colloc, torch.ones_like(q_hat), create_graph=True)[0] dh_dt = torch.autograd.grad(h_hat, t_colloc, torch.ones_like(h_hat), create_graph=True)[0] dh_dx = torch.autograd.grad(h_hat, x_colloc, torch.ones_like(h_hat), create_graph=True)[0] F1 = Cs_A * dq_dt + q_hat * dq_dx + g * Cs_A**2 * dh_dx + f * (torch.abs(q_hat) * q_hat) / (2 * diam) F2 = Cs_A * dh_dt + q_hat * dh_dx + a**2/g * dq_dx loss_pde = torch.mean(F1**2 + F2**2) train_output = pinn(x_train_rand, t_train_rand) loss_data = torch.mean((hq_tr - torch.squeeze(train_output))**2) loss = w_f * loss_pde + loss_data loss.backward() optimiser.step()
数据预处理定义
x_train = torch.tensor(x_inp.values).to(dtype=torch.float32) t_train = torch.tensor(t_inp.values).to(dtype=torch.float32) h_train = torch.tensor(h_inp.values).to(dtype=torch.float32) q_train = torch.tensor(q_inp.values).to(dtype=torch.float32) n_samples = len(x_train) perm_indicies = torch.randperm(n_samples) x_train_rand = x_train[perm_indicies].view(-1,1) t_train_rand = t_train[perm_indicies].view(-1,1) h_train_rand = h_train[perm_indicies].view(-1,1) q_train_rand = q_train[perm_indicies].view(-1,1)
可能的原因及解决方法
输入尺度差异过大,未做归一化
x的范围是0-300,t是0-10,两者尺度差异会导致网络难以捕捉输入变化。建议将输入缩放到[-1,1]或[0,1]区间:# 对配置点输入归一化 x_colloc = (x_colloc - x_colloc.min()) / (x_colloc.max() - x_colloc.min()) t_colloc = (t_colloc - t_colloc.min()) / (t_colloc.max() - t_colloc.min()) # 训练数据执行相同归一化 x_train = (x_train - x_train.min()) / (x_train.max() - x_train.min()) t_train = (t_train - t_train.min()) / (t_train.max() - t_train.min())网络层数过多导致激活函数饱和
12层隐藏层搭配Tanh激活函数,容易因输入绝对值过大进入饱和区,导致梯度消失,网络无法学习输入差异。可尝试减少隐藏层数量(如3-5层),或改用LeakyReLU等非饱和激活函数。自动求导与维度匹配问题
检查torch.autograd.grad调用是否正确,确保对x和t的求导针对每个样本。同时验证hq_tr与train_output的维度是否匹配,torch.squeeze可能意外压缩维度,建议打印维度排查:print("train_output shape:", train_output.shape) print("hq_tr shape:", hq_tr.shape)权重初始化过于一致
Linear层默认初始化可能导致网络初始状态同质化,可手动用Xavier或He初始化优化:def init_weights(m): if isinstance(m, nn.Linear): nn.init.xavier_uniform_(m.weight) nn.init.zeros_(m.bias) pinn.apply(init_weights)
内容的提问来源于stack exchange,提问作者Felix Spiers
相关产品推荐
相关产品推荐

