MindSpore Elec代码架构及应用案例介绍
为了让开发者更好地使用MindSpore Elec,本节重点介绍MindSpore Elec代码架构及应用案例撰写。
MindSpore Elec代码架构
MindSpore Elec代码路径为https://gitee.com/mindspore/mindscience/tree/master/MindElec,
其工程目录结构如下:
└─MindElec
├── cmake // 第三方库构建脚本
├── examples // 典型案例
├── mindelec // 架构核心代码
│ ├── architecture // 神经网络基础架构
│ ├── ccsrc // CAD数据前处理
│ ├── common // 学习率设置
│ ├── data // 数据采样和加载
│ ├── geometry // CSG几何建模
│ ├── loss // 损失函数
│ ├── operators // 高阶梯度计算
│ ├── solver // 训练和推理
│ └── vision // 可视化工具
├── CMakeLists.txt // 构建脚本
├── README.md // 使用说明
├── build.sh // whl包编译脚本
└── setup.py // whl包配置文件
MindSpore Elec的安装方式有两种,分别是whl包直接安装,以及bash build.sh源码编译生成whl包再安装。MindSpore Elec的核心代码中包含了CSG几何建模、CAD数据前处理、训练和推理以及可视化等模块。下面以物理驱动的电磁仿真模型为例,对API部分接口进行介绍。
MindSpore Elec案例撰写
创建数据集
可以通过geometry模块生成圆形、矩形等几何体,并且几何体之间可以进行并集、补集等逻辑运算。
from mindelec.data import Dataset
from mindelec.geometry import Disk, Rectangle, TimeDomain, GeometryWithTime
# 激励源区域
disk = Disk("src", disk_origin, disk_radius)
# 非激励源区域
rectangle = Rectangle("rect", coord_min, coord_max)
diff = rectangle – disk
# 时间范围
time_interval = TimeDomain("time", 0.0, config["range_t"])
...
# 最终采样区域
geom_dict = {src_region : ["domain", "IC"],
no_src_region : ["domain", "IC"],
boundary : ["BC"]}
MindSpore Elec的Dataset接口可以将不同的采样数据合并为统一训练数据集。
# create dataset for train
elec_train_dataset = Dataset(geom_dict)
train_dataset = elec_train_dataset.create_dataset(batch_size=config["train_batch_size"],
shuffle=True,
prebatched_data=True,
drop_remainder=True)
模型构建
定义控制方程及初边值条件:用户可以继承Problem类,快速定义控制方程governing_equation、边界条件boundary_conditon、初始条件initial_condition等,其中对于方程中的一阶微分可以调用梯度接口Grad来实现,相应的二阶微分可以调用接口SecondOrderGrad来完成。
# 2D TE波(2阶Mur边界条件)
class Maxwell2DMur(Problem):
def __init__(self, model, config, domain_name=None, bc_name=None, ic_name=None):
super(Maxwell2DMur, self).__init__()
@ms_function
def governing_equation(self, *output, **kwargs):
"""TE电磁波"""
u = output[0]
# 输入数据
data = kwargs[self.domain_name]
x = self.reshape(data[:, 0], (-1, 1))
y = self.reshape(data[:, 1], (-1, 1))
t = self.reshape(data[:, 2], (-1, 1))
# 梯度计算
dex_dxyt = self.grad(data, None, 0, u)
...
# 控制方程的损失函数
loss_a1 = (self.s_hz * dhz_dy) / (self.s_ex * self.s_t * self.eps_x)
loss_a2 = dex_dt / self.s_t
pde_r1 = loss_a1 - loss_a2
...
@ms_function
def boundary_condition(self, *output, **kwargs):
"""2阶Mur边界条件"""
# network input and output
u = output[0]
data = kwargs[self.bc_name]
...
# 左边界条件
bc_r1 = dhz_dx / self.s_x - dhz_dt / (self.light_speed * self.s_x) + \
self.s_ex * self.light_speed * self.eps_x / (2 * self.s_hz * self.s_x) * dex_dy
...
@ms_function
def initial_condition(self, *output, **kwargs):
"""初始条件: u = 0"""
u = output[0]
return u
Constraint将用户定义的控制方程转成MindSpore可以识别的计算图。
# 定义方程约束
train_prob = {}
for dataset in elec_train_dataset.all_datasets:
train_prob[dataset.name] = Maxwell2DMur(model=model, config=config,
domain_name=dataset.name + "_points",
ic_name=dataset.name + "_points",
bc_name=dataset.name + "_points")
train_constraints = Constraints(elec_train_dataset, train_prob)
构建神经网络:本例中所使用多通道残差网络并结合Sin激活函数,在该问题的模拟中取得了相比其他方法更高的精度。
model = MultiScaleFCCell(config["input_size"],
config["output_size"],
layers=config["layers"],
neurons=config["neurons"],
input_scale=config["input_scale"],
residual=config["residual"],
weight_init=HeUniform(negative_slope=math.sqrt(5)),
act="sin",
num_scales=config["num_scales"],
amp_factor=config["amp_factor"],
scale_factor=config["scale_factor"])
模型训练
MindSpore Elec提供的Solver类是模型训练和推理的接口。输入优化器、网络模型、PDE的约束(train_constraints)和可选参数(如自适应加权算法模块)。
# 优化器
lr_scheduler = MultiStepLR(config["lr"], config["milestones"], config["lr_gamma"], steps_per_epoch, config["train_epoch"])
lr = lr_scheduler.get_lr()
optim = nn.Adam(params, learning_rate=Tensor(lr))
# 求解器
solver = Solver(model,
optimizer=optim,
mode="PINNs",
train_constraints=train_constraints,
test_constraints=None,
metrics={'l2': L2(), 'distance': nn.MAE()},
loss_fn='smooth_l1_loss',
loss_scale_manager=DynamicLossScaleManager(init_loss_scale=2 ** 10, scale_window=2000),
mtl_weighted_cell=mtl)
#训练
solver.train(config["train_epoch"],train_dataset, callbacks=callbacks, dataset_sink_mode=True)
更多的应用和参考如下:
教程:https://www.mindspore.cn/mindscience/docs/zh-CN/master/mindelec/point_cloud.html;
API接口:https://www.mindspore.cn/mindscience/api/zh-CN/r0.1/mindelec.html;
代码仓:https://gitee.com/mindspore/mindscience/tree/master/MindElec。