Python精选200Tips:196-200

运行系统:macOS Sequoia 15.0
Python编译器:PyCharm 2024.1.4 (Community Edition)
Python版本:3.12
TensorFlow版本:2.17.0
Pytorch版本:2.4.1

往期链接:

1-56-1011-2021-3031-4041-50
51-60:函数61-70:类71-80:编程范式及设计模式
81-90:Python编码规范91-100:Python自带常用模块-1
101-105:Python自带模块-2106-110:Python自带模块-3
111-115:Python常用第三方包-频繁使用116-120:Python常用第三方包-深度学习
121-125:Python常用第三方包-爬取数据126-130:Python常用第三方包-为了乐趣
131-135:Python常用第三方包-拓展工具1136-140:Python常用第三方包-拓展工具2

Python项目实战

141-145146-150151-155156-160161-165166-170171-175
176-180:卷积结构181-182:卷积结构(续)183-185:时间、序列数据1186-190:时间、序列数据2191-195:Python资源

前言–图神经网络(Graph Neural Networks, GNNs)

定义

图神经网络是一类专门处理图结构数据的深度学习模型。图是一种数据结构,由节点(顶点)和边(连接节点的关系)组成,广泛应用于社交网络、推荐系统、知识图谱、生物信息学等领域。GNN 通过节点的特征和图的拓扑结构来学习节点、边或整个图的表示。

图的基本概念

  • 节点:图中的基本单元,表示对象。
  • 边:连接节点的关系,可以是有向的或无向的,表示节点之间的交互。
  • 图结构:图的整体形状和连接模式,决定了节点之间的信息传递方式。

GNN 的工作原理

GNN 通过迭代更新节点的表示(embedding),利用其邻居节点的信息来增强自身的特征表示。基本步骤如下:

  • 消息传递(Message Passing):
    • 每个节点从其邻居节点接收特征信息。
    • 通过聚合(aggregation)操作,汇总邻居节点的信息。
  • 更新(Update):
    • 根据接收到的信息更新节点的表示。
    • 更新过程通常使用非线性函数(如 ReLU)和可学习的参数。
  • 读取(Readout):
    • 在图的任务(如图分类)中,最终会将节点表示整合为图的整体表示。

GNN 的类型

  • 图卷积网络(GCN):
    通过局部卷积操作聚合邻居节点信息,从而学习节点表示。
  • 图注意力网络(GAT):
    通过自注意力机制,动态地为邻居节点分配不同的权重,增强重要节点的影响。
  • 图同构网络(GIN):
    通过设计强大的聚合函数,使模型在图同构性方面表现更佳。

应用领域

  • 社交网络分析:预测用户行为、推荐好友等。
  • 推荐系统:基于用户和物品的图结构,提供个性化推荐。
  • 生物信息学:药物发现、蛋白质交互预测等。
  • 自然语言处理:知识图谱的构建和推理。

优势与挑战

  • 优势
    • 处理复杂结构:GNN 能够有效处理图数据中复杂的结构信息。
    • 利用邻居信息:通过聚合邻居节点的特征,提升节点表示的质量。
  • 挑战
    • 计算复杂性:在大规模图中,消息传递和聚合操作可能导致计算开销增大。
    • 图的动态性:如何处理动态变化的图结构仍然是一个研究难点。

P196-- Graph Convolutional Networks (GCNs)

模型说明

Thomas Kipf 和 Max Welling 在2016年提出了论文《Semi-Supervised Classification with Graph Convolutional Networks》,这是 GCN 的基础理论。

核心思想:
通过卷积操作在图结构上进行特征学习,尤其适用于半监督学习任务。

基本架构:
(1)GCN 使用层次化的结构,允许节点通过其邻居的信息进行特征更新。
(2)提出了通过邻接矩阵的归一化来处理图的稀疏性。

影响:
(1)GCN 成为众多图神经网络的基础,为后来的研究奠定了重要的理论基础。
(2)其思想和框架被广泛应用于节点分类、图分类、链接预测等任务。

模型主要特征

  • 局部特征聚合:
    GCN 通过邻居节点的特征聚合来更新目标节点的特征,实现信息传递。
  • 谱图卷积:
    使用谱图理论,计算图的拉普拉斯矩阵,从频域上进行卷积操作。
  • 半监督学习能力:
    GCN 可以在部分标签数据的情况下进行学习,适合大规模图数据。
  • 可扩展性:
    GCN 通过层次化的方法,能够有效处理大规模图,避免了全图计算的高昂成本。
  • 简单易用:
    GCN 的结构相对简单,易于实现和扩展,成为后续研究的基础模型。

Python示例

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import GCNConv
import torch.optim as optim

# 定义 GCN 模型
class GCN(torch.nn.Module):
    def __init__(self, num_node_features, num_classes):
        super(GCN, self).__init__()
        self.conv1 = GCNConv(num_node_features, 16)
        self.conv2 = GCNConv(16, num_classes)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = self.conv2(x, edge_index)
        return F.log_softmax(x, dim=1)

# 加载数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

# 初始化模型、损失函数和优化器
model = GCN(num_node_features=dataset.num_node_features, num_classes=dataset.num_classes)
optimizer = optim.Adam(model.parameters(), lr=0.01)
criterion = F.nll_loss

# 训练模型
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 测试模型
def test():
    model.eval()
    with torch.no_grad():
        out = model(data)
    pred = out.argmax(dim=1)  # 获取预测的类别
    correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()  # 计算正确预测的数量
    accuracy = int(correct) / int(data.test_mask.sum())  # 计算准确率
    return accuracy

# 训练和测试循环
num_epochs = 200
for epoch in range(num_epochs):
    loss = train()
    if (epoch + 1) % 20 == 0:
        acc = test()
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss:.4f}, Test Accuracy: {acc:.4f}')

# 最终测试
final_accuracy = test()
print(f'Final Test Accuracy: {final_accuracy:.4f}')

首次运行会下载程序所用的数据集。

Epoch [20/200], Loss: 0.1071, Test Accuracy: 0.7800
Epoch [40/200], Loss: 0.0086, Test Accuracy: 0.7750
Epoch [60/200], Loss: 0.0035, Test Accuracy: 0.7750
Epoch [80/200], Loss: 0.0024, Test Accuracy: 0.7750
Epoch [100/200], Loss: 0.0019, Test Accuracy: 0.7770
Epoch [120/200], Loss: 0.0015, Test Accuracy: 0.7780
Epoch [140/200], Loss: 0.0013, Test Accuracy: 0.7800
Epoch [160/200], Loss: 0.0011, Test Accuracy: 0.7830
Epoch [180/200], Loss: 0.0009, Test Accuracy: 0.7830
Epoch [200/200], Loss: 0.0008, Test Accuracy: 0.7830
Final Test Accuracy: 0.7830

P197-- Graph Attention Networks (GATs)

模型说明

GAT 由 Petar Veličković 等人在2018年的论文《Graph Attention Networks》中提出,首次引入了图中的自注意力机制。GAT 通过自注意力机制为不同邻居节点分配不同的权重,从而增强信息聚合的灵活性和有效性。

模型主要特征

  • 自注意力机制:
    GAT 通过计算节点之间的注意力权重,允许模型在聚合邻居特征时自适应地关注不同的邻居。
  • 节点特征聚合:
    每个节点在更新特征时考虑其邻居节点的特征及其权重,实现信息的动态聚合。
  • 多头注意力:
    GAT 引入了多头注意力机制,允许模型在不同的子空间中学习多个注意力分布,从而提高特征表达能力。
  • 灵活性:
    GAT 可以处理不同类型的图和动态变化的图结构,适用于多种实际场景。
  • 无须图的全局结构:
    与传统的图卷积网络不同,GAT 不需要全局的图结构信息,能够在局部范围内进行有效的特征学习。

Python示例

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import GATConv
import torch.optim as optim

# 定义 GAT 模型
class GAT(torch.nn.Module):
    def __init__(self, num_node_features, num_classes):
        super(GAT, self).__init__()
        self.conv1 = GATConv(num_node_features, 8, heads=8)  # 第一层
        self.conv2 = GATConv(8 * 8, num_classes, heads=1, concat=False)  # 第二层

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        x = self.conv1(x, edge_index)
        x = F.elu(x)  # 使用 ELU 激活函数
        x = self.conv2(x, edge_index)
        return F.log_softmax(x, dim=1)

# 加载数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

# 初始化模型、损失函数和优化器
model = GAT(num_node_features=dataset.num_node_features, num_classes=dataset.num_classes)
optimizer = optim.Adam(model.parameters(), lr=0.005)
criterion = F.nll_loss

# 训练模型
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 测试模型
def test():
    model.eval()
    with torch.no_grad():
        out = model(data)
    pred = out.argmax(dim=1)  # 获取预测的类别
    correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()  # 计算正确预测的数量
    accuracy = int(correct) / int(data.test_mask.sum())  # 计算准确率
    return accuracy

# 训练和测试循环
num_epochs = 200
for epoch in range(num_epochs):
    loss = train()
    if (epoch + 1) % 20 == 0:
        acc = test()
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss:.4f}, Test Accuracy: {acc:.4f}')

# 最终测试
final_accuracy = test()
print(f'Final Test Accuracy: {final_accuracy:.4f}')

结果

Epoch [20/200], Loss: 0.0281, Test Accuracy: 0.7520
Epoch [40/200], Loss: 0.0012, Test Accuracy: 0.7290
Epoch [60/200], Loss: 0.0005, Test Accuracy: 0.7240
Epoch [80/200], Loss: 0.0004, Test Accuracy: 0.7220
Epoch [100/200], Loss: 0.0003, Test Accuracy: 0.7230
Epoch [120/200], Loss: 0.0003, Test Accuracy: 0.7220
Epoch [140/200], Loss: 0.0002, Test Accuracy: 0.7220
Epoch [160/200], Loss: 0.0002, Test Accuracy: 0.7210
Epoch [180/200], Loss: 0.0002, Test Accuracy: 0.7210
Epoch [200/200], Loss: 0.0002, Test Accuracy: 0.7200
Final Test Accuracy: 0.7200

P198-- GraphSAGE (Graph Sample and Aggregation)

模型说明

GraphSAGE 由 William L. Hamilton 等人在2017年的论文《Inductive Representation Learning on Large Graphs》中提出,首次引入了基于采样的图卷积网络。GraphSAGE 旨在处理大规模图,并允许模型在未见过的节点上进行归纳学习。通过采样邻居节点来聚合特征,实现高效学习。
GraphSAGE 的设计使其能够在新节点上进行推理,这对于动态和不断变化的图结构非常重要。GraphSAGE 提出了多种聚合方法,如均值聚合、LSTM 聚合和池化聚合,以适应不同的应用场景。

模型的主要特征

  • 采样邻居:
    GraphSAGE 使用采样技术,从每个节点的邻居中随机选择一部分进行特征聚合,避免了全图计算的高昂成本。
  • 多种聚合函数:
    支持多种聚合函数(如均值、LSTM、池化等),可根据具体任务选择最合适的聚合方式。
  • 归纳学习能力:
    能够在未见过的节点上进行推理,适合动态变化的图结构。
  • 可扩展性:
    适合大规模图,具有良好的计算效率和存储效率。
  • 灵活性:
    可以轻松适应各种类型的图数据,包括异构图和动态图。

Python示例

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import SAGEConv
import torch.optim as optim

# 定义 GraphSAGE 模型
class GraphSAGE(torch.nn.Module):
    def __init__(self, num_node_features, num_classes):
        super(GraphSAGE, self).__init__()
        self.conv1 = SAGEConv(num_node_features, 16)  # 第一层
        self.conv2 = SAGEConv(16, num_classes)  # 第二层

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        x = self.conv1(x, edge_index)
        x = F.relu(x)  # 使用 ReLU 激活函数
        x = self.conv2(x, edge_index)
        return F.log_softmax(x, dim=1)

# 加载数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

# 初始化模型、损失函数和优化器
model = GraphSAGE(num_node_features=dataset.num_node_features, num_classes=dataset.num_classes)
optimizer = optim.Adam(model.parameters(), lr=0.01)
criterion = F.nll_loss

# 训练模型
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 测试模型
def test():
    model.eval()
    with torch.no_grad():
        out = model(data)
    pred = out.argmax(dim=1)  # 获取预测的类别
    correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()  # 计算正确预测的数量
    accuracy = int(correct) / int(data.test_mask.sum())  # 计算准确率
    return accuracy

# 训练和测试循环
num_epochs = 200
for epoch in range(num_epochs):
    loss = train()
    if (epoch + 1) % 20 == 0:
        acc = test()
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss:.4f}, Test Accuracy: {acc:.4f}')

# 最终测试
final_accuracy = test()
print(f'Final Test Accuracy: {final_accuracy:.4f}')

结果

Epoch [20/200], Loss: 0.0025, Test Accuracy: 0.7230
Epoch [40/200], Loss: 0.0001, Test Accuracy: 0.7250
Epoch [60/200], Loss: 0.0001, Test Accuracy: 0.7250
Epoch [80/200], Loss: 0.0001, Test Accuracy: 0.7290
Epoch [100/200], Loss: 0.0000, Test Accuracy: 0.7290
Epoch [120/200], Loss: 0.0000, Test Accuracy: 0.7280
Epoch [140/200], Loss: 0.0000, Test Accuracy: 0.7260
Epoch [160/200], Loss: 0.0000, Test Accuracy: 0.7280
Epoch [180/200], Loss: 0.0000, Test Accuracy: 0.7280
Epoch [200/200], Loss: 0.0000, Test Accuracy: 0.7330
Final Test Accuracy: 0.7330

P199-- ChebNet

模型说明

ChebNet 由 Michaël Defferrard 等人在2016年的论文《Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering》中提出,首次引入了图卷积的谱方法。ChebNet 通过切比雪夫多项式来近似图卷积操作,提供了一种高效的计算方式,避免了昂贵的特征计算。ChebNet 采用谱图卷积的思想,利用图拉普拉斯算子及其特征分解,进行特征提取和卷积操作。
通过切比雪夫多项式,ChebNet 能够实现高效的局部化图卷积,同时减少计算复杂度,使得大规模图的处理成为可能。

模型主要特征

  • 切比雪夫多项式:
    ChebNet 使用切比雪夫多项式来近似卷积操作,提供了快速的局部化滤波。
  • 谱图卷积:
    通过将卷积操作转化到谱域,ChebNet 实现了对图数据的有效特征提取。
  • 局部化特征提取:
    ChebNet 能够在图的局部结构中提取特征,适合处理大规模稀疏图。
  • 高效计算:
    相较于传统的谱方法,ChebNet 在计算上更为高效,适用于实时和大规模应用。
  • 灵活性:
    ChebNet 可以轻松适应不同类型的图数据,并在多种任务中表现良好。

Python示例

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import ChebConv
import torch.optim as optim

# 定义 ChebNet 模型
class ChebNet(torch.nn.Module):
    def __init__(self, num_node_features, num_classes, K=3):
        super(ChebNet, self).__init__()
        self.conv1 = ChebConv(num_node_features, 16, K)  # 第一层
        self.conv2 = ChebConv(16, num_classes, K)  # 第二层

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        x = self.conv1(x, edge_index)
        x = F.relu(x)  # 使用 ReLU 激活函数
        x = self.conv2(x, edge_index)
        return F.log_softmax(x, dim=1)

# 加载数据集
dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

# 初始化模型、损失函数和优化器
model = ChebNet(num_node_features=dataset.num_node_features, num_classes=dataset.num_classes)
optimizer = optim.Adam(model.parameters(), lr=0.01)
criterion = F.nll_loss

# 训练模型
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 测试模型
def test():
    model.eval()
    with torch.no_grad():
        out = model(data)
    pred = out.argmax(dim=1)  # 获取预测的类别
    correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()  # 计算正确预测的数量
    accuracy = int(correct) / int(data.test_mask.sum())  # 计算准确率
    return accuracy

# 训练和测试循环
num_epochs = 200
for epoch in range(num_epochs):
    loss = train()
    if (epoch + 1) % 20 == 0:
        acc = test()
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss:.4f}, Test Accuracy: {acc:.4f}')

# 最终测试
final_accuracy = test()
print(f'Final Test Accuracy: {final_accuracy:.4f}')

结果

Epoch [20/200], Loss: 0.0002, Test Accuracy: 0.7730
Epoch [40/200], Loss: 0.0000, Test Accuracy: 0.7710
Epoch [60/200], Loss: 0.0000, Test Accuracy: 0.7770
Epoch [80/200], Loss: 0.0000, Test Accuracy: 0.7770
Epoch [100/200], Loss: 0.0000, Test Accuracy: 0.7810
Epoch [120/200], Loss: 0.0000, Test Accuracy: 0.7820
Epoch [140/200], Loss: 0.0000, Test Accuracy: 0.7830
Epoch [160/200], Loss: 0.0000, Test Accuracy: 0.7790
Epoch [180/200], Loss: 0.0000, Test Accuracy: 0.7800
Epoch [200/200], Loss: 0.0000, Test Accuracy: 0.7810
Final Test Accuracy: 0.7810

P200-- Relational Graph Convolutional Networks (R-GCNs)

模型说明

R-GCN 由 Schlichtkrull 等人在2017年的论文《Modeling Relational Data with Graph Convolutional Networks》中提出,首次引入了针对多关系图的卷积网络。R-GCN 扩展了传统的图卷积网络(GCN),能够有效处理具有多种关系类型的图数据(如知识图谱),并通过使用不同的权重矩阵来学习每种关系的重要性。R-GCN 提出了针对不同关系类型的聚合方式,使得模型能够学习到更丰富的节点表示。

模型主要特征

  • 多关系处理:
    R-GCN 设计了专门的机制来处理多种类型的边(关系),每种关系都有独立的权重矩阵。
  • 局部聚合:
    与 GCN 类似,R-GCN 使用局部聚合的方式更新节点特征,避免全图计算的高昂成本。
  • 归一化机制:
    R-GCN 引入了归一化机制,以防止邻居节点数量不同所带来的影响,保证特征聚合的稳定性。
  • 可扩展性:
    R-GCN 能够处理大规模图数据,适合用于动态和复杂的关系网络。
  • 灵活性:
    能够应用于多种任务,包括节点分类、链接预测和图分类等。

Python示例

import torch
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import RGCNConv
import torch.optim as optim

# 定义 R-GCN 模型
class RGCN(torch.nn.Module):
    def __init__(self, num_node_features, num_classes, num_relations):
        super(RGCN, self).__init__()
        self.conv1 = RGCNConv(num_node_features, 16, num_relations)  # 第一层
        self.conv2 = RGCNConv(16, num_classes, num_relations)  # 第二层

    def forward(self, data):
        x, edge_index, edge_type = data.x, data.edge_index, data.edge_type
        x = self.conv1(x, edge_index, edge_type)
        x = F.relu(x)  # 使用 ReLU 激活函数
        x = self.conv2(x, edge_index, edge_type)
        return F.log_softmax(x, dim=1)

# 加载数据集(以 Cora 为例)
dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

# 由于 Cora 是无关系图,这里我们简单模拟关系
data.edge_type = torch.zeros(data.edge_index.size(1), dtype=torch.long)

# 初始化模型、损失函数和优化器
num_relations = 1  # Cora 数据集仅有一种关系
model = RGCN(num_node_features=dataset.num_node_features, num_classes=dataset.num_classes, num_relations=num_relations)
optimizer = optim.Adam(model.parameters(), lr=0.01)
criterion = F.nll_loss

# 训练模型
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 测试模型
def test():
    model.eval()
    with torch.no_grad():
        out = model(data)
    pred = out.argmax(dim=1)  # 获取预测的类别
    correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()  # 计算正确预测的数量
    accuracy = int(correct) / int(data.test_mask.sum())  # 计算准确率
    return accuracy

# 训练和测试循环
num_epochs = 200
for epoch in range(num_epochs):
    loss = train()
    if (epoch + 1) % 20 == 0:
        acc = test()
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss:.4f}, Test Accuracy: {acc:.4f}')

# 最终测试
final_accuracy = test()
print(f'Final Test Accuracy: {final_accuracy:.4f}')

结果

Epoch [20/200], Loss: 0.0023, Test Accuracy: 0.7490
Epoch [40/200], Loss: 0.0001, Test Accuracy: 0.7520
Epoch [60/200], Loss: 0.0001, Test Accuracy: 0.7520
Epoch [80/200], Loss: 0.0001, Test Accuracy: 0.7500
Epoch [100/200], Loss: 0.0001, Test Accuracy: 0.7490
Epoch [120/200], Loss: 0.0000, Test Accuracy: 0.7480
Epoch [140/200], Loss: 0.0000, Test Accuracy: 0.7500
Epoch [160/200], Loss: 0.0000, Test Accuracy: 0.7520
Epoch [180/200], Loss: 0.0000, Test Accuracy: 0.7500
Epoch [200/200], Loss: 0.0000, Test Accuracy: 0.7480
Final Test Accuracy: 0.7480
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AnFany

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

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

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

打赏作者

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

抵扣说明:

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

余额充值