©PaperWeekly 原创 · 作者|张玮玮

学校|东北大学硕士

研究方向|情绪识别

论文标题:

Crystal Graph Neural Networks for Data Mining in Materials Science

论文链接:

https://storage.googleapis.com/rimcs_cgnn/cgnn_matsci_May_27_2019.pdf

代码链接:

https://github.com/Tony-Y/cgnn

OQMD 数据库(这个数据库比较大,提供 python API 与晶体结构可视化,可以使用 MySQL 读入):OQMD [2]

晶体材料性质一般通过输入晶胞内的原子数目、原子分子坐标、晶格常数利用密度泛函理论(DFT)计算得出。机器学习方法在加速新材料设计方面正变得越来越流行,其预测材料性能的准确性接近从头算计算,但计算速度要快数量级。最近有人提出用称为晶体图来表示晶体材料 [1],适应于晶体图的卷积神经网络利用平衡键距作为空间信息成功地预测了材料的体积特性。

预备知识

1.1 晶格常数(点阵常数

晶胞三个棱的常数以及这三个棱之间的夹角 6 个参数组成。按晶格常数的不同可以分为七大晶系。在本文中点阵矢量定义为














































1.2 原子坐标

原子坐标有两种表示形式:分数坐标和笛卡尔坐标。分数坐标是把点阵矢量看成是单位矢量下确定原子位置; 笛卡尔坐标是绝对坐标,是直角坐标系与斜角坐标系的统称,考虑点阵常数的大小。本文利用的是原子的分数坐标






































。笛卡尔坐标可以和分数坐标相互转换,在




定义的晶胞中,第




个原子的笛卡尔位置计算为








,单元格体积












必须大于 0。

1.3 晶体性质

晶体材料的总能量取决于晶体结构












,并且可以使用 DFT 来近似计算,其中,原子数目为


































。近似能量表示为:
















,可以通过最小化总能量来得到平衡结构:
















表示平衡能的最小值。DFT 计算也给出体积特性,如形成能







、单位单元体积







、带隙







和总磁化强度







1.4 数据集

现有的理论材料数据库包含了无机晶体材料的松弛结构及其性能。The Materials Project(MP)数据库拥有 86k 条目,大多与实验观察到的结构有关。The Open Quantum Materials Database(OQMD v1.2)包含 563k 个与实验和假设化合物相关的条目。

晶体图神经网络

晶体图神经网络(CGNNs)引入了一种比例不变的图协调器(Crystal Graph Coordinator)来构成晶体图,用于在 OQMD 数据集上训练 CGNN 模型。CGNN模型对每一种测试材料的形成能、单元体积、带隙和总磁化强度等体积特性进行了预测,其平均误差小于数据库中相应的误差。将预测的带隙和总磁化率用于金属绝缘体和非磁-磁材料二元分类。

CGNN 框架如图 1 所示,CG-Gen 是原子序数的函数,会产生平衡结构下的晶体图















是有向边的集合



































。P-CGNN 是一个预测平衡特性的多任务模型,






































。S-CGNN 是在














条件下,推导出晶胞形状







和原子分数坐标




。本文通过预测的晶胞体积来缩放







来获得平衡晶胞
























2.1 The Crystal Graph Coordinator

为了训练 CGNN 和 CG-Gen,框架需要一组由平衡结构组成的晶体图。在晶体学中,用泰森多边形找出原子的最近邻居,参考文献 [1] 运用了该方法。CGNN 引入了一种晶体图协调器,它通过聚类来连接原子间的原子间距。由于使用了体积校正因子和缩放距离,晶体图在单位单元的任何均匀变形下都具有不变性。伪代码如下图所示:

源代码如下所示:

def get_neighbors(geom):elems = [Element.from_Z(z) for z in geom.atomic_numbers]#通过原子序数来得到元素种类;OQMD数据库共有89种化学元素,原子序数为1到83,89到94 radii = np.array([get_radius(e) for e in elems])#原子半径是从PyMatGen库获得cutoff = radii[:,np.newaxis] + radii[np.newaxis, :]#将任意两个原子的半径相加,比如有4种原子,则返回一个4*4的矩阵。vol_atom = (4 * np.pi / 3) * np.array([r**3 for r in radii]).sum()#将晶胞内的原子体积相加factor_vol = (geom.volume / vol_atom)**(1.0/3.0)#体积校正因子通过晶胞体积和原子体积之和得来factor = factor_vol * RADIUS_FACTORcutoff *= factor#得到截止半径candidates = get_nbrs(geom.cart_coords, geom.lattice.matrix, cutoff)#这部分代码函数在下文提供,主要是将原子的笛卡尔坐标转换为分子坐标并且得到当前原子小于截止半径范围内的候选邻居原子。neighbors = []for j in range(len(candidates)):dists = []for nbr in candidates[j]:i = nbr[0]#第一维表示原子索引d = nbr[1]#第二维表示距离r = nbr[2]dists.append(d / cutoff[j,i])#距离归一到[0,1],以便进行后续的聚类X = np.array(dists).reshape((-1, 1))nnc_nbrs = get_nnc_loop(X)#得到最近邻居原子的位置索引neighbors.append([candidates[j][i][0] for i in nnc_nbrs])return neighbors
def get_nbrs(crystal_xyz, crystal_lat, R_max):A = np.transpose(crystal_lat)B = np.linalg.inv(A)crystal_red = np.matmul(crystal_xyz, np.transpose(B))#笛卡尔坐标系转换为分数坐标系crystal_nbrs = pbc.get_shortest_distances(crystal_red, A, R_max,crdn_only=True)#得到当前原子小于截止半径范围内的候选邻居原子return crystal_nbrs

得到的晶体图如下例所示:

2.2 Crystal Graph Neural Networks

作者对模型结构的介绍可以见 Architectures-CGNN(tony-y.github.io)[3]

CGNN 体系结构从原子序数

























的嵌入层开始构造,得到初始隐藏状态:




























T 个卷积块会产生一系列更高维的隐藏特征:




























。卷积块由边神经网络 (EdgeNet)、门控卷积和多层全连接神经网络(MFCNet)组成,如图 3(b) 所示。图 3(c) 所示的 EdgeNet 可以表示为:

本文设计了 EdgeNet 层的三个变体:Original EdgeNet Layer,Fast EdgeNet Layer,Aggregate EdgeNet Layer。

门控卷积表示为 ,MFCNet 各层使用












权值矩阵。graph-level 表示











是由所有的隐藏层状态


































,按照以下步骤进行:在每一步中,隐藏状态使用 Gated Pooling 机制汇合为:

然后,graph-level 状态表示为




















被加权平均为:



























送入 graph-level MFCNet 输出

























,最后层的输出作为线性回归模型的输入来预测目标值。

class GGNN(nn.Module):"""Gated Graph Neural NetworksNodes -> Embedding -> Gated Convolutions -> Graph Pooling -> Full Connections -> Linear Regression"""def __init__(self, n_node_feat, n_hidden_feat, n_graph_feat, n_conv, n_fc,activation, use_batch_norm, node_activation, use_node_batch_norm,edge_activation, use_edge_batch_norm, n_edge_net_feat, n_edge_net_layers,edge_net_activation, use_edge_net_batch_norm, use_fast_edge_network,fast_edge_network_type, use_aggregated_edge_network, edge_net_cardinality,edge_net_width, use_edge_net_shortcut, n_postconv_net_layers,postconv_net_activation, use_postconv_net_batch_norm, conv_type,conv_bias=False, edge_net_bias=False, postconv_net_bias=False,full_pooling=False, gated_pooling=False,use_extension=False):super(GGNN, self).__init__()
#设置激活函数,论文共设置了softplus,ssp,elu,relu,selu,celu六种激活函数act_fn = get_activation(activation)if node_activation is not None:node_act_fn = get_activation(node_activation)else:node_act_fn = Noneif edge_activation is not None:edge_act_fn = get_activation(edge_activation)else:edge_act_fn = Nonepostconv_net_act_fn = get_activation(postconv_net_activation)
#EdgeNet层的三个变体if n_edge_net_layers < 1:edge_nets = [None for i in range(n_conv)]else:edge_net_act_fn = get_activation(edge_net_activation)if use_aggregated_edge_network:#AggregatedEdgeNetworkedge_nets = [AggregatedEdgeNetwork(n_hidden_feat, n_edge_net_feat,n_edge_net_layers, cardinality=edge_net_cardinality,width=edge_net_width, activation=edge_net_act_fn,use_batch_norm=use_edge_net_batch_norm,bias=edge_net_bias,use_shortcut=use_edge_net_shortcut)for i in range(n_conv)]elif use_fast_edge_network:#FastEdgeNetworkedge_nets = [FastEdgeNetwork(n_hidden_feat, n_edge_net_feat,n_edge_net_layers, activation=edge_net_act_fn,net_type=fast_edge_network_type,use_batch_norm=use_edge_net_batch_norm,bias=edge_net_bias,use_shortcut=use_edge_net_shortcut)for i in range(n_conv)]else:#Original EdgeNet Layeredge_nets = [EdgeNetwork(n_hidden_feat, n_edge_net_feat,n_edge_net_layers, activation=edge_net_act_fn,use_batch_norm=use_edge_net_batch_norm,bias=edge_net_bias,use_shortcut=use_edge_net_shortcut)for i in range(n_conv)]if n_postconv_net_layers < 1:postconv_nets = [None for i in range(n_conv)]else:postconv_nets = [PostconvolutionNetwork(n_hidden_feat, n_hidden_feat,n_postconv_net_layers,activation=postconv_net_act_fn,use_batch_norm=use_postconv_net_batch_norm,bias=postconv_net_bias)for i in range(n_conv)]self.embedding = NodeEmbedding(n_node_feat, n_hidden_feat)#节点嵌入层,使用线性层self.convs = [GatedGraphConvolution(n_hidden_feat, n_hidden_feat,node_activation=node_act_fn,edge_activation=edge_act_fn,use_node_batch_norm=use_node_batch_norm,use_edge_batch_norm=use_edge_batch_norm,bias=conv_bias,conv_type=conv_type,edge_network=edge_nets[i],postconv_network=postconv_nets[i])for i in range(n_conv)]#门卷积层self.convs = nn.ModuleList(self.convs)if full_pooling:n_steps = n_convif gated_pooling:self.pre_poolings = [GatedPooling(n_hidden_feat)for _ in range(n_conv)]else:self.pre_poolings = [LinearPooling(n_hidden_feat)for _ in range(n_conv)]else:n_steps = 1self.pre_poolings = [None for _ in range(n_conv-1)]if gated_pooling:self.pre_poolings.append(GatedPooling(n_hidden_feat))else:self.pre_poolings.append(LinearPooling(n_hidden_feat))self.pre_poolings = nn.ModuleList(self.pre_poolings)#门pooling层self.pooling = GraphPooling(n_hidden_feat, n_steps, activation=act_fn,use_batch_norm=use_batch_norm)#多层全连接神经网络self.fcs = [FullConnection(n_hidden_feat, n_graph_feat,activation=act_fn, use_batch_norm=use_batch_norm)]self.fcs += [FullConnection(n_graph_feat, n_graph_feat,activation=act_fn, use_batch_norm=use_batch_norm)for i in range(n_fc-1)]self.fcs = nn.ModuleList(self.fcs)#线性回归self.regression = LinearRegression(n_graph_feat)if use_extension:self.extension = Extension()else:self.extension = Nonedef forward(self, input):#模型顺序如下:Nodes -> Embedding -> Gated Convolutions -> Graph Pooling -> Full Connections -> Linear Regressionx = self.embedding(input.nodes)y = []for conv, pre_pooling in zip(self.convs, self.pre_poolings):x = conv(x, input.edge_sources, input.edge_targets)if pre_pooling is not None:y.append(pre_pooling(x, input.graph_indices, input.node_counts))x = self.pooling(y)for fc in self.fcs:x = fc(x)x = self.regression(x)if self.extension is not None:x = self.extension(x, input.node_counts)return x

实验结果

研究使用的数据集包括从 OQMD 的 561,888 个不同条目中提取的松弛结构、形成能、晶胞体积、带隙和总磁化率。P-GCNN 模型分别进行了形成能预测、晶胞体积预测、带隙预测,其预测结果如下所示:

测试集中非磁体有 30,299 个,磁体有 25,629 个。非磁体组的总磁化率几乎为零,占检测组总磁化率的 54.2%,而磁性组的均值为












/atom,标准差为












/atom,最大值为












/atom。与带隙数据一样,全题磁化数据在零处非负偏置,但磁数据具有大于 1 的正偏度 1.66 和 4.72 的高峰度,表明具有重尾分布。金属绝缘体和非磁-磁材料分类结果如下:

结果与讨论

对于 OQMD 测试集中的每一种材料,P-CGNN 模型成功地预测了其形成能、单元体积、带隙和总磁化强度,并将其分为金属和绝缘体、非磁体和磁体。重要的是,预测没有使用空间距离键长信息。并且 CGNN 模型提供了与基于 DFT 的材料性质预测的准确性。

当 CG-Gen 从适当的材料数据库中几乎完全学习了晶体图上的合成化学时,就可以实现材料数据挖掘。由于晶体图形序列是由对应的图形转换序列生成的,因此整个图形转换序列集合可以看作是存储了材料合成的完整信息的物质基因组,就像人类基因组是人类核酸序列的完整集合一样。

参考文献

[1] Xie T, Grossman J C. Crystal graph convolutional neural networks for an accurate and interpretable prediction of material properties[J]. Physical review letters, 2018, 120(14): 145301.

[2] http://www.oqmd.org/

[3] https://tony-y.github.io/cgnn/architectures/

更多阅读

#投 稿 通 道#

 让你的论文被更多人看到 

如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。

总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。

PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学习心得技术干货。我们的目的只有一个,让知识真正流动起来。

???? 来稿标准:

• 稿件确系个人原创作品,来稿需注明作者个人信息(姓名+学校/工作单位+学历/职位+研究方向)

• 如果文章并非首发,请在投稿时提醒并附上所有已发布链接

• PaperWeekly 默认每篇文章都是首发,均会添加“原创”标志

???? 投稿邮箱:

• 投稿邮箱:hr@paperweekly.site

• 所有文章配图,请单独在附件中发送

• 请留下即时联系方式(微信或手机),以便我们在编辑发布时和作者沟通

????

现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧

关于PaperWeekly

PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。

材料科学中的数据挖掘:晶体图神经网络解读与代码解析相关推荐

  1. 【GNN报告】腾讯AI Lab机器学习中心荣钰:图神经网络最新范式的探索

    目录 1.简介 2.图神经网络最新范式的探索 背景 存在不足 Geometrically Equivariant Graph Neural Networks: A Survey Equivariant ...

  2. 单目标跟踪算法:Siamese RPN论文解读和代码解析

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者:周威 | 来源:知乎 https://zhuanlan.zhihu.com/p/16198364 ...

  3. 同构和异构经典图神经网络汇总+pytorch代码

    收集一些讲解比较好的博客或者知乎文档,以及对应的代码 1.同构图神经网络-GCN/GAT/GraphSAGE 图卷积:从GCN到GAT.GraphSAGE图卷积:从GCN到GAT.GraphSAGE ...

  4. Longformer论文解读和代码解析

    前言 这篇博文记录了longformer论文的主要思想.代码实现和结果复现方面的一些工作,相关链接如下: 原longformer论文地址 github上原作者公开的代码 huggingface上原作者 ...

  5. 【Vue】Vue中传值的几种方法,案例代码解析

    目录 一.反向传值(子组件传值给父组件) 二.$refs 三.$parent 四.$children 五.$attrs/$listeners -----多层传值 六.$root ----根组件 七.依 ...

  6. Inception V3论文解读和代码解析

    目录 论文解读 代码解析 小结 论文解读 在介绍inception V2时提到过,inception V3的论文依据是Rethinking the Inception Architecture for ...

  7. YOLOv7来临:论文解读附代码解析

    前言: 是一份关于YOLOv7的论文解读,首发于[GiantPandaCV]公众号,写的不是很好,望大佬们包涵! 2022年7月,YOLOv7来临, 论文链接:https://arxiv.org/ab ...

  8. PointNet论文解读和代码解析

    目录 一.论文动机 现有的问题: 作者的思路及面临的问题: 二.论文方法 如何解决点云无序性问题?作者提出了三种想法. 针对点云的刚体运动不变性 三.网络结构 四.代码阅读 五.Reference(两 ...

  9. monodepth无监督卷积神经网络深度估计代码解析(一)

    论文解析:https://blog.csdn.net/bofu_sun/article/details/89206531 近期在做深度估计相关的毕业设计,发现monodepth项目比较不错,决定尝试一 ...

最新文章

  1. 中国平安“豪赌”科技?从产险业务IT变形计聊起
  2. Struts中乱码问题解决
  3. Java 8中HashMap冲突解决
  4. Boost::context模块callcc的stack测试程序
  5. mysql 6.17_2020 6/17 mysql数据的增删改查
  6. linux内核之kfifo队列
  7. 使用百度云加速防apache的ab测试
  8. vr的延迟和渲染效率优化与Nvidia VRWorks
  9. 哔哩哔哩2019年Q4及全年财报:全年营收67.8亿元,同比增长64%
  10. 在linux下进行嵌入式系统设计,一种应用于测控系统的基于Linux的嵌入式系统的设计...
  11. linux mv时间,简介Linux中cp和mv搭配{,}在shel_l当中的用法
  12. 如何选择InstallShield工程类型
  13. 智能优化算法:旗鱼优化算法-附代码
  14. LabVIEW用高速数据流盘
  15. Ubuntu 16下Linaro 交叉编译器的安装
  16. android Wifi热点启动流程,[android]WIFI热点启动流程分析
  17. 超火壁纸!隐藏 Dock 栏+AirTag 渐变
  18. shell 补齐路径_Linux中10个有用的命令行补全例子
  19. Choco求解器的安装
  20. log+android+bp,第二章:Android.bp语法

热门文章

  1. php get 返回源码,php源码 fsockopen获取网页内容实例详解
  2. springboot加载外部xml_Springboot引用外部配置文件的方法步骤
  3. netty获取玩家chanel_Netty中的Channel
  4. mac电脑开机键盘和鼠标失灵
  5. BZOJ 1968 [Ahoi2005]COMMON 约数研究
  6. spark发行版笔记9
  7. .net 基元类型,引用类型和值类型
  8. 真我闪博,闪靓自我!
  9. .net访问PostgreSQL数据库发生“找不到函数名”的问题追踪
  10. 一个 .Net Hashtable 的锁的疑惑和解决