Skip to content

how to train physics-informed neural network with TorchGA? #4

@xgxgnpu

Description

@xgxgnpu

Hi, thank you for your nice repository! I am trying recently to use TorchGA for training physics-informed neural network but failed. My
code is as follows.
`

#!pip install pygad

#!pip install pyDOE

import torch

import numpy as np
import pygad.torchga
import pygad

import time
import scipy.io
import math

from pyDOE import lhs

CUDA support

if torch.cuda.is_available():
device = torch.device('cuda')
else:
device = torch.device('cpu')

"""# neural network"""

the deep neural network

import torch

import torch.nn as nn
from collections import OrderedDict

class FNN(torch.nn.Module):
def init(self, layers):
super(FNN, self).init()
# parameters
self.depth = len(layers) - 1
self.activation = torch.nn.Tanh
layer_list = list()
for i in range(self.depth - 1):
layer_list.append(
('layer_%d' % i, torch.nn.Linear(layers[i], layers[i+1]))
)
layer_list.append(('activation_%d' % i, self.activation()))
layer_list.append(
('layer_%d' % (self.depth - 1), torch.nn.Linear(layers[-2], layers[-1]))
)
layerDict = OrderedDict(layer_list)
# deploy layers
self.layers = torch.nn.Sequential(layerDict)

def forward(self, x):
out = self.layers(x)
return out

"""# Res_func"""

predictions = pygad.torchga.predict(model=model,

solution=solution,

data=data_inputs)

def net_f(model, inputs, solution):

u = model(inputs)
x = inputs[:,0:1]
t = inputs[:,1:2]

u_x = torch.autograd.grad(
u, x,
grad_outputs=torch.ones_like(u),
retain_graph=True,
create_graph=True,
allow_unused=True
)[0]

u_xx = torch.autograd.grad(
u_x, x,
grad_outputs=torch.ones_like(u),
retain_graph=True,
create_graph=True,
allow_unused=True
)[0]

u_t = torch.autograd.grad(
u, t,
grad_outputs=torch.ones_like(u),
retain_graph=True,
create_graph=True,
allow_unused=True
)[0]

f_u = u_t + u*u_x - (0.01/torch.tensor(math.pi))*u_xx

return f_u

"""# forword pass"""

Forward pass for stream-pressure formulation

def net_u(model, inputs):

u = model(inputs)

return u

def net_u_x(model, inputs):

u = model(inputs)
x = inputs[:,0:1]
t = inputs[:,1:2]

u_x = torch.autograd.grad(
u, x,
grad_outputs=torch.ones_like(u),
retain_graph=True,
create_graph=True,
allow_unused=True
)[0]

return u, u_x

"""# loss_func"""

def loss_fn(model, input_f, input_xt_0, ouptput_u_0, input_xt_lb, input_xt_ub, solution):

f_u_pred = net_f(model, input_f, solution)
u0_pred = net_u(model, input_xt_0, solution)
u_lb_pred, _ = net_u_x(model, input_xt_lb, solution)
u_ub_pred, _ = net_u_x(model, input_xt_ub, solution)

mse_0_u = torch.mean(torch.square(1.0*(ouptput_u_0 - u0_pred)))

mse_b_u = torch.mean(torch.square(u_lb_pred - 0)) +
torch.mean(torch.square(u_ub_pred - 0)) #since ub/lb is 0

mse_f_u = torch.mean(torch.square(1.0*f_u_pred))

Total loss

loss_bic = mse_0_u + mse_b_u
loss_res = mse_f_u
loss = loss_bic + loss_res

return loss

构建适应度函数,类似于损失函数

def fitness_func(solution, sol_idx):

global input_f, input_xt_0, ouptput_u_0, input_xt_lb, input_xt_ub, model

# 这里的预测是否可以换成model直接前向传播????
# ========================================================
loss_total = loss_fn(model, input_f, input_xt_0, ouptput_u_0, input_xt_lb, input_xt_ub, solution)

loss_total_numpy = loss_total.detach().numpy() + 0.00000001

solution_fitness = 1.0 / loss_total_numpy

return solution_fitness

构建打印函数

def callback_generation(ga_instance):
print("Generation = {generation}".format(generation=ga_instance.generations_completed))
print("Fitness = {fitness}".format(fitness=ga_instance.best_solution()[1]))

layers = [2] + [20]*5 + [1]

model = FNN(layers)

print(model)

print(model.state_dict)

lb = np.array([-1.0]) #x upper boundary
ub = np.array([1.0]) #x lower boundary

N0 = 100
N_b = 25 #25 per upper and lower boundary, so 50 total
N_f = 10000

#load data, from Raissi et. al

data = scipy.io.loadmat('burgers_shock.mat')

t = data['t'].flatten()[:,None]
x = data['x'].flatten()[:,None]
Exact = data['usol']
Exact_u = np.real(Exact)

#grab random points off the initial condition
idx_x = np.random.choice(x.shape[0], N0, replace=False)

x0 = x[idx_x,:]
u0 = Exact_u[idx_x,0:1]

idx_t = np.random.choice(t.shape[0], N_b, replace=False)
tb = t[idx_t,:]

=========== 残差采样点 =====================

X_f = lb + (ub-lb)*lhs(2, N_f)

时间不能为负数:细节

x_f = X_f[:,0:1]
t_f = np.abs(X_f[:,1:2])

#generate point vectors for training
X0 = np.concatenate((x0, 0x0), 1) # (x0, 0)
X_lb = np.concatenate((0
tb + lb[0], tb), 1) # (lb[0], tb)
X_ub = np.concatenate((0*tb + ub[0], tb), 1) # (ub[0], tb)

#seperate point vectors
x0 = X0[:,0:1]
t0 = X0[:,1:2]

x_lb = X_lb[:,0:1]
t_lb = X_lb[:,1:2]

x_ub = X_ub[:,0:1]
t_ub = X_ub[:,1:2]

x_f_tf = torch.tensor(x_f, requires_grad=True).float()
t_f_tf = torch.tensor(t_f, requires_grad=True).float()

x_0_tf = torch.tensor(x0).float()
t_0_tf = torch.tensor(t0).float()
u_0_tf = torch.tensor(u0).float()

x_lb_tf = torch.tensor(x_lb, requires_grad=True).float()
t_lb_tf = torch.tensor(t_lb, requires_grad=True).float()

x_ub_tf = torch.tensor(x_ub, requires_grad=True).float()
t_ub_tf = torch.tensor(t_ub, requires_grad=True).float()

input_f = torch.cat([x_f_tf, t_f_tf], 1)

input_xt_0 = torch.cat([x_0_tf, t_0_tf], 1)
ouptput_u_0 = u_0_tf

input_xt_lb = torch.cat([x_lb_tf, t_lb_tf], 1)
input_xt_ub = torch.cat([x_ub_tf, t_ub_tf], 1)

Create an instance of the pygad.torchga.TorchGA class to build the initial population.

torch_ga = pygad.torchga.TorchGA(model=model,
num_solutions=10)

Prepare the PyGAD parameters. Check the documentation for more information: https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#pygad-ga-class

num_generations = 250 # Number of generations.
num_parents_mating = 5 # Number of solutions to be selected as parents in the mating pool.
initial_population = torch_ga.population_weights # Initial population of network weights

ga_instance = pygad.GA(num_generations=num_generations,
num_parents_mating=num_parents_mating,
initial_population=initial_population,
fitness_func=fitness_func,
on_generation=callback_generation)

ga_instance.run()

`

then i get an error like this, but i have no idea how to fix it. Could you please give some advice about it?Thank you in advance
`
TypeError Traceback (most recent call last)
in ()
----> 1 ga_instance.run()
2

5 frames
/usr/local/lib/python3.7/dist-packages/pygad/pygad.py in run(self)
1190
1191 # Measuring the fitness of each chromosome in the population. Save the fitness in the last_generation_fitness attribute.
-> 1192 self.last_generation_fitness = self.cal_pop_fitness()
1193
1194 best_solution, best_solution_fitness, best_match_idx = self.best_solution(pop_fitness=self.last_generation_fitness)

/usr/local/lib/python3.7/dist-packages/pygad/pygad.py in cal_pop_fitness(self)
1157 fitness = self.previous_generation_fitness[parent_idx]
1158 else:
-> 1159 fitness = self.fitness_func(sol, sol_idx)
1160 if type(fitness) in GA.supported_int_float_types:
1161 pass

in fitness_func(solution, sol_idx)
8 # 这里的预测是否可以换成model直接前向传播????
9 # ========================================================
---> 10 loss_total = loss_fn(model, input_f, input_xt_0, ouptput_u_0, input_xt_lb, input_xt_ub, solution)
11
12 loss_total_numpy = loss_total.detach().numpy() + 0.00000001

in loss_fn(model, input_f, input_xt_0, ouptput_u_0, input_xt_lb, input_xt_ub, solution)
2 def loss_fn(model, input_f, input_xt_0, ouptput_u_0, input_xt_lb, input_xt_ub, solution):
3
----> 4 f_u_pred = net_f(model, input_f, solution)
5 u0_pred = net_u(model, input_xt_0, solution)
6 u_lb_pred, _ = net_u_x(model, input_xt_lb, solution)

in net_f(model, inputs, solution)
25 retain_graph=True,
26 create_graph=True,
---> 27 allow_unused=True
28 )[0]
29

/usr/local/lib/python3.7/dist-packages/torch/autograd/init.py in grad(outputs, inputs, grad_outputs, retain_graph, create_graph, only_inputs, allow_unused, is_grads_batched)
236 for your use case. Defaults to False.
237 """
--> 238 outputs = (outputs,) if isinstance(outputs, torch.Tensor) else tuple(outputs)
239 inputs = (inputs,) if isinstance(inputs, torch.Tensor) else tuple(inputs)
240 overridable_args = outputs + inputs

TypeError: 'NoneType' object is not iterable
`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions