深度学习 GNN图神经网络(四)线性回归之ESOL数据集水溶性预测

本文主要是介绍深度学习 GNN图神经网络(四)线性回归之ESOL数据集水溶性预测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

线性回归之ESOL数据集水溶性预测

  • 一、前言
  • 二、ESOL数据集
  • 三、加载数据集
  • 四、数据拆分
  • 五、构造模型
  • 六、训练模型
  • 七、测试结果
  • 八、分类问题
  • 参考文献

一、前言

本文旨在使用化合物分子的SMILES字符串进行数据模型训练,对其水溶性的值进行预测。

之前的文章《深度学习 GNN图神经网络(三)模型思想及文献分类案例实战》引用的Cora数据集只有一张图,属于图神经网络的节点分类问题。本文介绍的是多图批量训练的线性回归问题,在文章最后也讨论了图分类问题。

二、ESOL数据集

本文使用的是ESOL数据集,在文章《如何将化学分子SMILES字符串转化为Pytorch图数据结构——ESOL分子水溶性数据集解析》中有详细介绍,在此不作详述。

三、加载数据集

from torch_geometric.datasets import MoleculeNetdataset = MoleculeNet(root="data", name="ESOL")print('num_features:',dataset.num_features)
print('num_classes:',dataset.num_classes)
print('num_node_features',dataset.num_node_features)
print("size:", len(dataset))d=dataset[10]
print("Sample:", d)
print("Sample y:", d.y)
print("Sample num_nodes:",d.num_nodes)
print("Sample num_edges:",d.num_edges)

这里可以得到数据集的一些基本信息:

num_features: 9
num_classes: 734
num_node_features 9
size: 1128
Sample: Data(x=[6, 9], edge_index=[2, 12], edge_attr=[12, 3], smiles='O=C1CCCN1', y=[1, 1])
Sample y: tensor([[1.0700]])
Sample num_nodes: 6
Sample num_edges: 12

四、数据拆分

将数据集拆分为训练数据和测试数据:

from torch_geometric.loader import DataLoader
data_size = len(dataset)
batch_size = 128
train_data=dataset[:int(data_size*0.8)]
test_data=dataset[int(data_size*0.8):]train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_data, batch_size=len(test_data))

五、构造模型

import torch
import torch.nn as nn
from torch_geometric.nn import GCNConv
import matplotlib.pyplot as plt
from torch_geometric.nn import global_mean_pooldevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")hidden_channels = 64class GNN(nn.Module):def __init__(self):# 初始化Pytorch父类super().__init__()self.conv1=GCNConv(dataset.num_node_features, hidden_channels)self.conv2=GCNConv(hidden_channels, hidden_channels)self.conv3 = GCNConv(hidden_channels, hidden_channels)self.conv4 = GCNConv(hidden_channels, hidden_channels)self.out = nn.Linear(hidden_channels, 1)# 创建损失函数,使用均方误差self.loss_function = nn.MSELoss()# 创建优化器,使用Adam梯度下降self.optimiser = torch.optim.Adam(self.parameters(), lr=0.005,weight_decay=5e-4)# 训练次数计数器self.counter = 0# 训练过程中损失值记录self.progress = []# 前向传播函数def forward(self, x, edge_index,batch):x=x.to(device)edge_index=edge_index.to(device)batch=batch.to(device)x=self.conv1(x, edge_index)x=x.relu()x=self.conv2(x, edge_index)x=x.relu()x=self.conv3(x, edge_index)x=x.relu()x=self.conv4(x, edge_index)x=x.relu()# 全局池化x = global_mean_pool(x, batch)  # [x, batch]out=self.out(x)return out# 训练函数def train(self, data):# 前向传播计算,获得网络输出outputs = self.forward(data.x.float(),data.edge_index,data.batch)# 计算损失值y=data.y.to(device)loss = self.loss_function(outputs, y)# 累加训练次数self.counter += 1# 每10次训练记录损失值if (self.counter % 10 == 0):self.progress.append(loss.item())# 每1000次输出训练次数   if (self.counter % 1000 == 0):print(f"counter={self.counter}, loss={loss.item()}")# 梯度清零, 反向传播, 更新权重self.optimiser.zero_grad()loss.backward()self.optimiser.step()# 测试函数def test(self, data):# 前向传播计算,获得网络输出outputs = self.forward(data.x.float(),data.edge_index,data.batch)# 把绝对值误差小于1的视为正确,计算准确度y=data.y.to(device)acc=sum(torch.abs(y-outputs)<1)/len(data.y)return acc# 绘制损失变化图def plot_progress(self):plt.plot(range(len(self.progress)),self.progress)

六、训练模型

model = GNN()
model.to(device)for i in range(1001):for data in train_loader:# print(data,'num_graphs:',data.num_graphs)model.train(data)
counter=1000, loss=1.4304862022399902
counter=2000, loss=0.9842458963394165
counter=3000, loss=0.27240827679634094
counter=4000, loss=0.23295772075653076
counter=5000, loss=0.38499030470848083
counter=6000, loss=1.470423698425293
counter=7000, loss=0.845589816570282
counter=8000, loss=0.15707021951675415

绘制损失值变化图::

model.plot_progress()

在这里插入图片描述

七、测试结果

#torch.set_printoptions(precision=4,sci_mode=False) #pytorch不使用科学计数法显示for data in test_loader:acc=model.test(data)print(acc)
tensor([0.8186], device='cuda:0')

可以看到,预测值误差小于1的占了81.86%,效果还行。

八、分类问题

对于图分类问题,其实也差不多。只需要修改下Linear网络层:

self.out = Linear(hidden_channels, dataset.num_classes)

这样预测结果就会有num_classes个,取最大值的下标索引即可。
伪代码为:

pred=outputs.argmax(dim=1)
correct += int((pred == data.y).sum())

参考文献

[1] https://pytorch-geometric.readthedocs.io/en/latest/get_started/colabs.html
[2] https://zhuanlan.zhihu.com/p/504978470

这篇关于深度学习 GNN图神经网络(四)线性回归之ESOL数据集水溶性预测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/337187

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Redis的数据过期策略和数据淘汰策略

《Redis的数据过期策略和数据淘汰策略》本文主要介绍了Redis的数据过期策略和数据淘汰策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录一、数据过期策略1、惰性删除2、定期删除二、数据淘汰策略1、数据淘汰策略概念2、8种数据淘汰策略

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

Python给Excel写入数据的四种方法小结

《Python给Excel写入数据的四种方法小结》本文主要介绍了Python给Excel写入数据的四种方法小结,包含openpyxl库、xlsxwriter库、pandas库和win32com库,具有... 目录1. 使用 openpyxl 库2. 使用 xlsxwriter 库3. 使用 pandas 库

SpringBoot定制JSON响应数据的实现

《SpringBoot定制JSON响应数据的实现》本文主要介绍了SpringBoot定制JSON响应数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录前言一、如何使用@jsonView这个注解?二、应用场景三、实战案例注解方式编程方式总结 前言

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

在Mysql环境下对数据进行增删改查的操作方法

《在Mysql环境下对数据进行增删改查的操作方法》本文介绍了在MySQL环境下对数据进行增删改查的基本操作,包括插入数据、修改数据、删除数据、数据查询(基本查询、连接查询、聚合函数查询、子查询)等,并... 目录一、插入数据:二、修改数据:三、删除数据:1、delete from 表名;2、truncate

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下