QM9数据集示例项目学习图神经网络

下面所有博客是个人对EEG脑电的探索,项目代码是早期版本不完整,需要完整项目代码和资料请私聊。


数据集
1、脑电项目探索和实现(EEG) (上):研究数据集选取和介绍SEED
相关论文阅读分析:
1、EEG-SEED数据集作者的—基线论文阅读和分析
2、图神经网络EEG论文阅读和分析:《EEG-Based Emotion Recognition Using Regularized Graph Neural Networks》
3、EEG-GNN论文阅读和分析:《EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks》
4、论文阅读和分析:Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification
5、论文阅读和分析:《DeepGCNs: Can GCNs Go as Deep as CNNs?》
6、论文阅读和分析: “How Attentive are Graph Attention Networks?”
7、论文阅读和分析:Simplifying Graph Convolutional Networks
8、论文阅读和分析:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
9、图神经网络汇总和总结
相关实验和代码实现:
1、用于图神经网络的脑电数据处理实现_图神经网络 脑电
2、使用GCN训练和测试EEG的公开SEED数据集
3、使用GAT训练和测试EEG公开的SEED数据集
4、使用SGC训练和测试SEED数据集
5、使用Transformer训练和测试EEG的公开SEED数据集_eeg transformer
6、使用RGNN训练和测试EEG公开的SEED数据集
辅助学习资料:
1、官网三个简单Graph示例说明三种层次的应用_graph 简单示例
2、PPI数据集示例项目学习图神经网络
3、geometric库的数据处理详解
4、NetworkX的dicts of dicts以及解决Seven Bridges of Königsberg问题
5、geometric源码阅读和分析:MessagePassin类详解和使用
6、cora数据集示例项目学习图神经网络
7、Graph 聚合
8、QM9数据集示例项目学习图神经网络
9、处理图的开源库

QM9数据集:

QM9为小有机分子的相关的、一致的和详尽的化学空间提供量子化学特征,该数据库可用于现有方法的基准测试,新方法的开发,如混合量子力学/机器学习,以及结构-性质关系的系统识别。

新药物和新材料的计算从头设计需要对化合物空间进行严格和公正的探索。然而,由于其大小与分子大小相结合,大量未知领域仍然存在。报告计算了由CHONF组成的134k稳定有机小分子的几何、能量、电子和热力学性质。这些分子对应于GDB-17化学宇宙中1660亿个有机分子中所有133,885个含有多达9个重原子(CONF)的物种的子集。报告了能量最小的几何,相应的谐波频率,偶极矩,极化率,以及能量,焓,和原子化的自由能。所有性质都是在量子化学的B3LYP/6-31G(2df,p)水平上计算的。此外,对于主要的化学计量,C7H10O2,在134k分子中有6095个组成异构体。在更精确的G4MP2理论水平上报告了所有这些原子化的能量、焓和自由能。因此,该数据集为相关、一致和全面的小有机分子化学空间提供了量子化学性质。该数据库可用于现有方法的基准测试,新方法的开发,如混合量子力学/机器学习,以及结构-性质关系的系统识别。

一些有机分子如下:

在这里插入图片描述

数据集中的分子可视化:

在这里插入图片描述
文件XYZ格式:

对于每个分子,原子坐标和计算属性存储在名为dataset_index.xyz的文件中。XYZ格式(最初由明尼苏达超级计算机中心为XMol程序开发)是一种广泛使用的纯文本格式,用于编码分子的笛卡尔坐标,没有正式的规范。它包含一个标题行(na)、一个注释行和na行(na行包含元素类型和原子坐标),每行一个原子。我们扩展了这种格式,如表2所示。现在,注释行用于存储所有标量属性

QM9数据提取的特征:

能量最小的几何空间结构、相应的谐波频率、偶极矩、极化率、能量、焓、原子化的自由能等

在这里插入图片描述

网络结构的设计

Set2Set的聚合方式:

Set2Set指的是一种序列到序列的一种扩展。许多情况下,可变大小的输入和/或输出可能不会自然地表示为序列,但是有一些数据不是序列形式的,Set2Set可以是从集合到集合。

注意:输出通道数是输入通道数的两倍
q t = L S T M ( q t − 1 ∗ ) α i , t = s o f t m a x ( x i ⋅ q t ) r t = ∑ i = 1 N α i , t x i q t ∗ = q t   ∥   r t , \begin{align}\begin{aligned}\mathbf{q}_t &= \mathrm{LSTM}(\mathbf{q}^{*}_{t-1})\\\alpha_{i,t} &= \mathrm{softmax}(\mathbf{x}_i \cdot \mathbf{q}_t)\\\mathbf{r}_t &= \sum_{i=1}^N \alpha_{i,t} \mathbf{x}_i\\\mathbf{q}^{*}_t &= \mathbf{q}_t \, \Vert \, \mathbf{r}_t,\end{aligned}\end{align} qtαi,trtqt=LSTM(qt1)=softmax(xiqt)=i=1Nαi,txi=qtrt,

set2set = Set2Set(dim, processing_steps=3)

out = self.set2set(out, data.batch)

GRU:
r t = σ ( W i r x t + b i r + W h r h ( t − 1 ) + b h r ) z t = σ ( W i z x t + b i z + W h z h ( t − 1 ) + b h z ) n t = tanh ⁡ ( W i n x t + b i n + r t ∗ ( W h n h ( t − 1 ) + b h n ) ) h t = ( 1 − z t ) ∗ n t + z t ∗ h ( t − 1 ) r_t = \sigma(W_{ir} x_t + b_{ir} + W_{hr} h_{(t-1)} + b_{hr}) \\ z_t = \sigma(W_{iz} x_t + b_{iz} + W_{hz} h_{(t-1)} + b_{hz}) \\ n_t = \tanh(W_{in} x_t + b_{in} + r_t * (W_{hn} h_{(t-1)}+ b_{hn})) \\ h_t = (1 - z_t) * n_t + z_t * h_{(t-1)} rt=σ(Wirxt+bir+Whrh(t1)+bhr)zt=σ(Wizxt+biz+Whzh(t1)+bhz)nt=tanh(Winxt+bin+rt(Whnh(t1)+bhn))ht=(1zt)nt+zth(t1)

rnn = nn.GRU(10, 20, 2)
input = torch.randn(5, 3, 10)
h0 = torch.randn(2, 3, 20)
output, hn = rnn(input, h0)

官网示例代码注释:

GitHub - pyg-team/pytorch_geometric: Graph Neural Network Library for PyTorch

import os.path as osp

import networkx as nx
import torch
import torch.nn.functional as F
from torch.nn import GRU, Linear, ReLU, Sequential

import torch_geometric.transforms as T
from torch_geometric.datasets import QM9
from torch_geometric.loader import DataLoader
from torch_geometric.nn import NNConv
from torch_geometric.nn.aggr import Set2Set
from torch_geometric.utils import remove_self_loops, to_networkx
import pylab

target = 0
dim = 64


class MyTransform(object):
    def __call__(self, data):
        # Specify target.
        data.y = data.y[:, target]
        return data


class Complete(object):
    def __call__(self, data):
        device = data.edge_index.device

        row = torch.arange(data.num_nodes, dtype=torch.long, device=device)
        col = torch.arange(data.num_nodes, dtype=torch.long, device=device)

        row = row.view(-1, 1).repeat(1, data.num_nodes).view(-1)
        col = col.repeat(data.num_nodes)
        edge_index = torch.stack([row, col], dim=0)

        edge_attr = None
        if data.edge_attr is not None:
            idx = data.edge_index[0] * data.num_nodes + data.edge_index[1]
            size = list(data.edge_attr.size())
            size[0] = data.num_nodes * data.num_nodes
            edge_attr = data.edge_attr.new_zeros(size)
            edge_attr[idx] = data.edge_attr

        edge_index, edge_attr = remove_self_loops(edge_index, edge_attr)
        data.edge_attr = edge_attr
        data.edge_index = edge_index

        return data


path = osp.join(osp.dirname(osp.realpath(__file__)), '..', 'data', 'QM9')
transform = T.Compose([MyTransform(), Complete(), T.Distance(norm=False)])
dataset = QM9(path, transform=transform).shuffle()

# 可视化分子
one_data = dataset[0]
G = to_networkx(one_data)
nx.draw(G)
pylab.show()

# Normalize targets to mean = 0 and std = 1.
mean = dataset.data.y.mean(dim=0, keepdim=True)
std = dataset.data.y.std(dim=0, keepdim=True)
dataset.data.y = (dataset.data.y - mean) / std
mean, std = mean[:, target].item(), std[:, target].item()

# Split datasets.
test_dataset = dataset[:10000]
val_dataset = dataset[10000:20000]
train_dataset = dataset[20000:]
test_loader = DataLoader(test_dataset, batch_size=128, shuffle=False)
val_loader = DataLoader(val_dataset, batch_size=128, shuffle=False)
train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True)


class Net(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.lin0 = torch.nn.Linear(dataset.num_features, dim)

        nn = Sequential(Linear(5, 128), ReLU(), Linear(128, dim * dim))
        self.conv = NNConv(dim, dim, nn, aggr='mean')
        self.gru = GRU(dim, dim)

        # Set2Set是一种将集合到集合用LSTM时序模型进行映射的聚合方式,注意out_channels = 2 * in_channels
        self.set2set = Set2Set(dim, processing_steps=3)
        self.lin1 = torch.nn.Linear(2 * dim, dim)
        self.lin2 = torch.nn.Linear(dim, 1)

    def forward(self, data):
        out = F.relu(self.lin0(data.x))
        h = out.unsqueeze(0)

        for i in range(3):
            m = F.relu(self.conv(out, data.edge_index, data.edge_attr))
            out, h = self.gru(m.unsqueeze(0), h)
            out = out.squeeze(0)
        # (2325,64)
        out = self.set2set(out, data.batch)
        # (128,128)
        out = F.relu(self.lin1(out))
        out = self.lin2(out)
        return out.view(-1)


device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min',
                                                       factor=0.7, patience=5,
                                                       min_lr=0.00001)


def train(epoch):
    model.train()
    loss_all = 0

    for data in train_loader:
        data = data.to(device)
        optimizer.zero_grad()
        loss = F.mse_loss(model(data), data.y)
        loss.backward()
        loss_all += loss.item() * data.num_graphs
        optimizer.step()
    return loss_all / len(train_loader.dataset)


def test(loader):
    model.eval()
    error = 0

    for data in loader:
        data = data.to(device)
        error += (model(data) * std - data.y * std).abs().sum().item()  # MAE
    return error / len(loader.dataset)


best_val_error = None
for epoch in range(1, 301):
    lr = scheduler.optimizer.param_groups[0]['lr']
    loss = train(epoch)
    val_error = test(val_loader)
    scheduler.step(val_error)

    if best_val_error is None or val_error <= best_val_error:
        test_error = test(test_loader)
        best_val_error = val_error

    print(f'Epoch: {epoch:03d}, LR: {lr:7f}, Loss: {loss:.7f}, '
          f'Val MAE: {val_error:.7f}, Test MAE: {test_error:.7f}')

参考:

1、Quantum-Machine.org: Datasets

2、Quantum chemistry structures and properties of 134 kilo molecules (figshare.com)

3、GitHub - pyg-team/pytorch_geometric: Graph Neural Network Library for PyTorch

4、Quantum chemistry structures and properties of 134 kilo molecules | Scientific Data (nature.com)

5、《ORDER MATTERS: SEQUENCE TO SEQUENCE FOR SETS》

6、GRU — PyTorch 1.13 documentation

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我理解了你的问题。您可以按照以下步骤使用QM7b数据集实现VGAE编码: 1. 下载QM7b数据集并将其放置在适当的文件夹中。 2. 使用PyTorch加载数据集。您可以使用以下代码: ``` from torch_geometric.datasets import QM7bDataset dataset = QM7bDataset(root='/path/to/dataset', transform=None) ``` 3. 构建形。您可以使用以下代码: ``` from torch_geometric.data import DataLoader loader = DataLoader(dataset, batch_size=32, shuffle=True) ``` 4. 定义模型。您可以使用以下代码: ``` import torch import torch.nn as nn from torch_geometric.nn import VGAE class MyModel(nn.Module): def __init__(self, in_channels, hidden_channels): super(MyModel, self).__init__() self.conv1 = GCNConv(in_channels, hidden_channels) self.conv2 = GCNConv(hidden_channels, hidden_channels) self.conv_mu = GCNConv(hidden_channels, hidden_channels) self.conv_logstd = GCNConv(hidden_channels, hidden_channels) self.vgae = VGAE(self.conv_mu, self.conv_logstd) def forward(self, x, edge_index): x = F.relu(self.conv1(x, edge_index)) x = F.relu(self.conv2(x, edge_index)) z = self.vgae.encode(x, edge_index) return z ``` 5. 训练模型。您可以使用以下代码: ``` import torch.optim as optim device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = MyModel(dataset.num_features, hidden_channels=16).to(device) optimizer = optim.Adam(model.parameters(), lr=0.01) criterion = nn.MSELoss() model.train() for epoch in range(10): total_loss = 0 for data in loader: data = data.to(device) optimizer.zero_grad() z = model(data.x, data.edge_index) loss = criterion(z, data.y) loss.backward() optimizer.step() total_loss += loss.item() * data.num_graphs total_loss /= len(dataset) print(f'Epoch {epoch}, Loss {total_loss:.4f}') ``` 这就是使用QM7b数据集实现VGAE编码的基本步骤。请注意,这只是一个示例,您可能需要根据模型和数据的特定要求进行更改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KPer_Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值