深度学习 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

相关文章

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I