当前位置:   article > 正文

图神经网络应用:预测分子溶解度_溶解度模型和神经网络

溶解度模型和神经网络

ChatGPT狂飙160天,世界已经不是之前的样子。

新建了人工智能中文站https://ai.weoknow.com
每天给大家更新可用的国内可用chatGPT资源


图片

在本篇博客中,我们将探讨如何使用化学结构来估计溶解度。这是一个回归问题,我们将提供SMILES字符串作为输入,并预测相应的溶解度。为了实现这个目标,我们将使用PyTorch Geometric构建图神经网络,并使用RDKit处理分子数据。

首先,我们需要安装PyTorch、PyTorch Geometric和RDKit。您可以使用以下命令通过pip进行安装:

  1. pip install torch
  2. pip install torch-geometric
  3. pip install rdkit

数据集介绍

在接下来的内容中,我们将使用PyTorch Geometric的数据集库中的一个数据集。我们将使用MoleculeNet数据集中的ESOL数据集。ESOL数据集包含了1128种不同化学物质在水中的溶解度信息。该数据集被用于训练模型,通过直接从化学结构(以SMILES字符串编码)计算溶解度。由于溶解度通常是分子的特征,而不是特定构象的特征,因此这些结构不包括3D坐标。

我们的任务是研究溶质在溶剂中的溶解度。让我们先来看一下分子的SMILES表示。

图片

加载数据集

  1. import rdkit
  2. from torch_geometric.datasets import MoleculeNet
  3. # 加载ESOL数据集
  4. data = MoleculeNet(root=".", name="ESOL")
  5. data

获取数据集信息

  1. print("Dataset type: "type(data))
  2. print("Dataset features: "data.num_features)
  3. print("Dataset target: "data.num_classes)
  4. print("Dataset length: "data.len)
  5. print("Dataset sample: "data[0])
  6. print("Sample  nodes: "data[0].num_nodes)
  7. print("Sample  edges: "data[0].num_edges)
  1. Dataset type:  <class 'torch_geometric.datasets.molecule_net.MoleculeNet'>
  2. Dataset features:  9
  3. Dataset target:  734
  4. Dataset length:  <bound method InMemoryDataset.len of ESOL(1128)>
  5. Dataset sample:  Data(x=[329], edge_index=[268], edge_attr=[683], y=[11], smiles='OCC3OC(OCC2OC(OC(C#N)c1ccccc1)C(O)C(O)C2O)C(O)C(O)C3O ')
  6. Sample  nodes:  32
  7. Sample  edges:  68

ESOL数据集包含了734个图,每个图代表一个化合物。图中的每个节点表示一个原子,边表示化学键。每个节点具有9个特征,目标维度也是734,表示每个图对应一个溶解度值。

  1. # 查看图中节点的特征
  2. data[0].x
  3. # 查看边的信息(以稀疏COO格式表示)
  4. # 形状为 [2, num_edges]
  5. data[0].edge_index.t()
  6. # 查看 data[0] 的目标值
  7. data[0].y

在图级别上进行预测意味着我们要预测每个图所代表的化合物的溶解度值,而不是预测单个节点级别的属性。接下来,我们将把SMILES表示的分子转换为RDKit分子对象,并进行可视化。

图片

data[0]["smiles"]
OCC3OC(OCC2OC(OC(C#N)c1ccccc1)C(O)C(O)C2O)C(O)C(O)C3O 

分子可视化

  1. from rdkit import Chem
  2. from rdkit.Chem.Draw import IPythonConsole
  3. molecule = Chem.MolFromSmiles(data[0]["smiles"])
  4. molecule

图片

要使用RDKit从分子中提取特征,您可以利用RDKit提供的各种功能,例如提取边信息、原子属性等。在我们的情况下,由于数据集已经提供了所需的信息,因此使用RDKit提取特征更加简单。我们可以使用原子属性来计算节点特征。

图神经网络的实现

创建图神经网络的过程与创建卷积神经网络(Convolutional Neural Network)非常相似,只是我们添加了更多的层。图卷积网络(GCN)继承自torch.nn.Module。GCNConv是一个常用的图卷积层,它需要以下参数:

  • in_channels:输入样本的大小。

  • out_channels:输出样本的大小。

我们将使用三个图卷积层,这意味着我们可以获取三个邻居跳数的信息。为了进行图级别的预测,我们还会应用一个池化层来混合来自各个节点的数据。为了完成我们的任务,我们将使用PyTorch和PyTorch Geometric库。

以下是使用PyTorch和PyTorch Geometric实现图神经网络的示例代码:

  1. import torch
  2. from torch.nn import Linear
  3. import torch.nn.functional as F 
  4. from torch_geometric.nn import GCNConv, TopKPooling, global_mean_pool
  5. from torch_geometric.nn import global_mean_pool as gap, global_max_pool as gmp
  6. embedding_size = 64
  7. class GCN(torch.nn.Module):
  8.     def __init__(self):
  9.         # Init parent
  10.         super(GCN, self).__init__()
  11.         torch.manual_seed(42)
  12.         # GCN layers
  13.         self.initial_conv = GCNConv(data.num_features, embedding_size)
  14.         self.conv1 = GCNConv(embedding_size, embedding_size)
  15.         self.conv2 = GCNConv(embedding_size, embedding_size)
  16.         self.conv3 = GCNConv(embedding_size, embedding_size)
  17.         # Output layer
  18.         self.out = Linear(embedding_size*21)
  19.     def forward(self, x, edge_index, batch_index):
  20.         # First Conv layer
  21.         hidden = self.initial_conv(x, edge_index)
  22.         hidden = F.tanh(hidden)
  23.         # Other Conv layers
  24.         hidden = self.conv1(hidden, edge_index)
  25.         hidden = F.tanh(hidden)
  26.         hidden = self.conv2(hidden, edge_index)
  27.         hidden = F.tanh(hidden)
  28.         hidden = self.conv3(hidden, edge_index)
  29.         hidden = F.tanh(hidden)
  30.         # Global Pooling (stack different aggregations)
  31.         hidden = torch.cat([gmp(hidden, batch_index), 
  32.                             gap(hidden, batch_index)], dim=1)
  33.         # Apply a final (linear) classifier.
  34.         out = self.out(hidden)
  35.         return out, hidden
  36. model = GCN()
  37. print(model)
  38. print("Number of parameters: "sum(p.numel() for p in model.parameters()))
  1. GCN(
  2.   (initial_conv): GCNConv(964)
  3.   (conv1): GCNConv(6464)
  4.   (conv2): GCNConv(6464)
  5.   (conv3): GCNConv(6464)
  6.   (out): Linear(in_features=128, out_features=1, bias=True)
  7. )
  8. Number of parameters:  13249
  • 考虑到我们拥有大量的分子数据,我们选择使用64维的嵌入向量来表示它们,而不是将它们进行最小化处理。

  • 随着我们逐渐增加网络层数,我们将能够更好地理解图的结构和特征。

  • 为了解决回归问题,我们采用线性层作为最终的输出层。

  • 尽管我们的样本数量只有大约1,000个,但我们致力于使用尽可能少的参数来实现高效的模型训练和预测。

训练神经网络

  1. from torch_geometric.data import DataLoader
  2. import warnings
  3. warnings.filterwarnings("ignore")
  4. # Root mean squared error
  5. loss_fn = torch.nn.MSELoss()
  6. optimizer = torch.optim.Adam(model.parameters(), lr=0.0007)  
  7. Use GPU for training
  8. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  9. model = model.to(device)
  10. # Wrap data in a data loader
  11. data_size = len(data)
  12. NUM_GRAPHS_PER_BATCH = 64
  13. loader = DataLoader(data[:int(data_size * 0.8)], 
  14.                     batch_size=NUM_GRAPHS_PER_BATCH, shuffle=True)
  15. test_loader = DataLoader(data[int(data_size * 0.8):], 
  16.                          batch_size=NUM_GRAPHS_PER_BATCH, shuffle=True)
  17. def train(data):
  18.     # Enumerate over the data
  19.     for batch in loader:
  20.       # Use GPU
  21.       batch.to(device)  
  22.       # Reset gradients
  23.       optimizer.zero_grad() 
  24.       # Passing the node features and the connection info
  25.       pred, embedding = model(batch.x.float(), batch.edge_index, batch.batch) 
  26.       # Calculating the loss and gradients
  27.       loss = loss_fn(pred, batch.y)     
  28.       loss.backward()  
  29.       # Update using the gradients
  30.       optimizer.step()   
  31.     return loss, embedding
  32. print("Starting training...")
  33. losses = []
  34. for epoch in range(2000):
  35.     loss, h = train(data)
  36.     losses.append(loss)
  37.     if epoch % 100 == 0:
  38.       print(f"Epoch {epoch} | Train Loss {loss}")
  1. Starting training...
  2. Epoch 0 | Train Loss 3.377596378326416
  3. Epoch 100 | Train Loss 0.9617947340011597
  4. Epoch 200 | Train Loss 1.0771363973617554
  5. Epoch 300 | Train Loss 0.6295697093009949
  6. Epoch 400 | Train Loss 0.37517455220222473
  7. Epoch 500 | Train Loss 0.465716689825058
  8. Epoch 600 | Train Loss 0.5129485726356506
  9. Epoch 700 | Train Loss 0.21677978336811066
  10. Epoch 800 | Train Loss 0.33871856331825256
  11. Epoch 900 | Train Loss 0.3640660345554352
  12. Epoch 1000 | Train Loss 0.20501013100147247
  13. Epoch 1100 | Train Loss 0.18023353815078735
  14. Epoch 1200 | Train Loss 0.2812242805957794
  15. Epoch 1300 | Train Loss 0.18207958340644836
  16. Epoch 1400 | Train Loss 0.1321338415145874
  17. Epoch 1500 | Train Loss 0.18665631115436554
  18. Epoch 1600 | Train Loss 0.1817774772644043
  19. Epoch 1700 | Train Loss 0.09456530958414078
  20. Epoch 1800 | Train Loss 0.23615044355392456
  21. Epoch 1900 | Train Loss 0.11381624639034271

可视化学习过程

  1. import seaborn as sns
  2. losses_float = [float(loss.cpu().detach().numpy()) for loss in losses] 
  3. loss_indices = [i for i,l in enumerate(losses_float)
  4. plt = sns.lineplot(loss_indices, losses_float)
  5. plt

测试集上进行预测

  1. import pandas as pd 
  2. # Analyze the results for one batch
  3. test_batch = next(iter(test_loader))
  4. with torch.no_grad():
  5.     test_batch.to(device)
  6.     pred, embed = model(test_batch.x.float(), test_batch.edge_indextest_batch.batch) 
  7.     df = pd.DataFrame()
  8.     df["y_real"= test_batch.y.tolist()
  9.     df["y_pred"= pred.tolist()
  10. df["y_real"= df["y_real"].apply(lambda row: row[0])
  11. df["y_pred"= df["y_pred"].apply(lambda row: row[0])
  12. df

图片

下面是可视化y_pred与y_original的代码:

  1. plt = sns.scatterplot(data=df, x="y_real", y="y_pred")
  2. plt.set(xlim=(-72))
  3. plt.set(ylim=(-72))
  4. plt

图片

以上是我们应用第一个GNN的示例代码。


ChatGPT狂飙160天,世界已经不是之前的样子。

新建了人工智能中文站https://ai.weoknow.com
每天给大家更新可用的国内可用chatGPT资源

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/213398
推荐阅读
相关标签
  

闽ICP备14008679号