GCN:图卷积神经网络算法的深度探索

第一章 GCN简介与发展背景

1.1 图神经网络的诞生

随着数据科学的发展,越来越多的数据呈现出图结构形式,比如社交网络中的用户关系、知识图谱中的实体连接、生物信息学中的分子结构等。图结构数据相较于传统的欧式数据(如图片、文本、音频)更加复杂且不规则。

传统的神经网络,如卷积神经网络(CNN)和循环神经网络(RNN),擅长处理规则网格状数据,但难以直接应用于图结构数据。为了有效地学习图数据的表示,图神经网络(Graph Neural Networks,GNNs)被提出。

GNNs能够捕获节点的局部结构信息,通过节点及其邻居节点的特征聚合,学习每个节点的嵌入向量,广泛应用于图分类、节点分类、链接预测等任务。

1.2 GCN的提出与意义

图卷积网络(Graph Convolutional Network,GCN)是GNN的一种核心架构,由Thomas Kipf和Max Welling于2017年提出。GCN基于谱图理论,通过图拉普拉斯矩阵的谱分解定义卷积操作,极大地推动了图深度学习领域的发展。

GCN的重要贡献是提出了简洁高效的近似卷积方法,解决了谱方法计算复杂度高、扩展性差的问题。GCN不仅能捕捉节点自身信息,还能有效整合邻居节点信息,广泛应用于社交网络分析、推荐系统、生物信息分析等领域。

1.3 文章目标与结构

本文旨在系统、深入地介绍GCN算法原理及实现细节,帮助读者从零开始理解并掌握GCN的核心技术。内容涵盖:

  • 图神经网络基础与图卷积概念
  • GCN数学推导与模型实现
  • 训练与优化技巧
  • 典型应用场景及实战案例
  • 最新研究进展与未来方向

通过理论与实践相结合,配合丰富的代码示例和图解,帮助你全面掌握GCN技术。


第二章 图神经网络基础

2.1 图的基本概念

在深入GCN之前,我们需要理解图的基础知识。

  • 节点(Node):图中的元素,也称为顶点,通常表示实体,比如社交网络中的用户。
  • 边(Edge):连接两个节点的关系,可以是有向或无向,也可以带权重,表示关系强弱。
  • 邻接矩阵(Adjacency Matrix,A):用一个矩阵来表示图的连接关系。对于有n个节点的图,A是一个n×n的矩阵,其中元素A\_ij表示节点i和j是否有边相连(1表示有边,0表示无边,或带权重的值)。

举例:

节点数 n=3
A = [[0, 1, 0],
     [1, 0, 1],
     [0, 1, 0]]

表示节点1和节点2相连,节点2和节点3相连。

2.2 图的表示方法

  • 邻接矩阵(A):如上所示,清晰表达节点之间的连接。
  • 度矩阵(D):对角矩阵,D\_ii表示节点i的度(即连接数)。
  • 特征矩阵(X):每个节点的特征表示,形状为n×f,其中f是特征维度。

例如,假设三个节点的特征为二维向量:

X = [[1, 0],
     [0, 1],
     [1, 1]]

2.3 传统图算法回顾

  • 图遍历:BFS和DFS常用于图的搜索,但不能直接用于节点表示学习。
  • 谱分解:图拉普拉斯矩阵的谱分解是GCN理论基础,将图信号转到频域处理。

2.4 图拉普拉斯矩阵

图拉普拉斯矩阵L定义为:

$$ L = D - A $$

其中D是度矩阵,A是邻接矩阵。L用于描述图的结构和属性,具有良好的数学性质。

归一化拉普拉斯矩阵为:

$$ L_{norm} = I - D^{-1/2} A D^{-1/2} $$

其中I是单位矩阵。


第三章 图卷积操作详解

3.1 什么是图卷积

传统卷积神经网络(CNN)中的卷积操作,适用于规则的二维网格数据(如图像),通过卷积核滑动实现局部特征提取。图卷积则是在图结构数据中定义的一种卷积操作,目的是在节点及其邻居之间进行信息聚合和传递,从而学习节点的特征表示。

图卷积的关键思想是:每个节点的新特征通过其邻居节点的特征加权求和得到,实现邻域信息的聚合。


3.2 谱域卷积定义

图卷积最早基于谱理论定义。谱方法使用图拉普拉斯矩阵的特征分解:

$$ L = U \Lambda U^T $$

  • $L$ 是图拉普拉斯矩阵
  • $U$ 是特征向量矩阵
  • $\Lambda$ 是特征值对角矩阵

图信号$x \in \mathbb{R}^n$在频域的表达为:

$$ \hat{x} = U^T x $$

定义图卷积为:

$$ g_\theta \ast x = U g_\theta(\Lambda) U^T x $$

其中,$g_\theta$是过滤器函数,作用于频域特征。


3.3 Chebyshev多项式近似

直接计算谱卷积需要特征分解,计算复杂度高。Chebyshev多项式近似方法避免了特征分解:

$$ g_\theta(\Lambda) \approx \sum_{k=0}^K \theta_k T_k(\tilde{\Lambda}) $$

  • $T_k$ 是Chebyshev多项式
  • $\tilde{\Lambda} = 2\Lambda / \lambda_{max} - I$ 是特征值归一化

这样,谱卷积转化为多项式形式,可通过递归计算实现高效卷积。


3.4 简化的图卷积网络(GCN)

Kipf和Welling提出的GCN进一步简化:

  • 设$K=1$
  • 对邻接矩阵加自环:$\tilde{A} = A + I$
  • 归一化处理:$\tilde{D}_{ii} = \sum_j \tilde{A}_{ij}$

得到归一化邻接矩阵:

$$ \hat{A} = \tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2} $$

GCN层的卷积操作为:

$$ H^{(l+1)} = \sigma\left(\hat{A} H^{(l)} W^{(l)}\right) $$

  • $H^{(l)}$是第$l$层节点特征矩阵(初始为输入特征$X$)
  • $W^{(l)}$是可训练权重矩阵
  • $\sigma$是非线性激活函数

3.5 空间域卷积

除谱方法外,空间域方法直接定义邻居特征聚合,如:

$$ h_i^{(l+1)} = \sigma\left( \sum_{j \in \mathcal{N}(i) \cup \{i\}} \frac{1}{c_{ij}} W^{(l)} h_j^{(l)} \right) $$

其中,$\mathcal{N}(i)$是节点$i$的邻居集合,$c_{ij}$是归一化常数。

空间域直观且易于扩展至大规模图。


3.6 图解说明

graph LR
    A(Node i)
    B(Node j)
    C(Node k)
    D(Node l)
    A --> B
    A --> C
    B --> D

    subgraph 聚合邻居特征
    B --> A
    C --> A
    end

节点i通过邻居j和k的特征聚合生成新的表示。


第四章 GCN数学原理与推导

4.1 标准GCN层公式

GCN的核心是利用归一化的邻接矩阵对节点特征进行变换和聚合,标准GCN层的前向传播公式为:

$$ H^{(l+1)} = \sigma\left(\tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2} H^{(l)} W^{(l)}\right) $$

其中:

  • $\tilde{A} = A + I$ 是加了自环的邻接矩阵
  • $\tilde{D}$ 是 $\tilde{A}$ 的度矩阵,即 $\tilde{D}_{ii} = \sum_j \tilde{A}_{ij}$
  • $H^{(l)}$ 是第 $l$ 层的节点特征矩阵,初始为输入特征矩阵 $X$
  • $W^{(l)}$ 是第 $l$ 层的权重矩阵
  • $\sigma(\cdot)$ 是激活函数,如 ReLU

4.2 加自环的必要性

  • 原始邻接矩阵 $A$ 只包含节点间的连接关系,没有包含节点自身的特征信息。
  • 通过加上单位矩阵 $I$,即 $\tilde{A} = A + I$,确保节点在聚合时也考虑自身特征。
  • 这避免信息在多层传播时过快衰减。

4.3 归一化邻接矩阵的意义

  • 简单地使用 $\tilde{A}$ 进行聚合可能导致特征尺度不稳定,特别是度数差异较大的节点。
  • 使用对称归一化

$$ \hat{A} = \tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2} $$

保证聚合后特征的尺度稳定。

  • 对称归一化保持了矩阵的对称性,有利于理论分析和稳定训练。

4.4 从谱卷积推导简化GCN

GCN的数学推导源于谱图卷积:

  1. 谱卷积定义:

$$ g_\theta \ast x = U g_\theta(\Lambda) U^T x $$

  1. Chebyshev多项式近似简化:

通过对滤波器函数进行多项式近似,降低计算复杂度。

  1. 一阶近似:

只保留一阶邻居信息,得到

$$ g_\theta \ast x \approx \theta (I + D^{-1/2} A D^{-1/2}) x $$

  1. 加入参数矩阵和非线性激活,得到GCN层公式。

4.5 计算过程示意

  • 输入特征矩阵 $H^{(l)}$,通过矩阵乘法先聚合邻居节点特征: $\hat{A} H^{(l)}$。
  • 再通过线性变换矩阵 $W^{(l)}$ 转换特征空间。
  • 最后通过激活函数 $\sigma$ 增加非线性。

4.6 权重共享与参数效率

  • 权重矩阵 $W^{(l)}$ 在所有节点间共享,类似CNN卷积核共享参数。
  • 参数量远小于全连接层,避免过拟合。

4.7 多层堆叠与信息传播

  • 多层GCN堆叠后,节点特征可以融合更远距离邻居的信息。
  • 但层数过深可能导致过平滑,节点特征趋同。

4.8 图解:GCN单层计算流程

graph LR
    X[节点特征H^(l)]
    A[归一化邻接矩阵 \\ \hat{A}]
    W[权重矩阵W^(l)]
    Z[输出特征Z]
    sigma[激活函数σ]

    X -->|矩阵乘法| M1[H_agg = \hat{A} H^(l)]
    M1 -->|矩阵乘法| M2[Z_pre = H_agg W^(l)]
    M2 -->|激活| Z

第五章 GCN模型实现代码示例

5.1 代码环境准备

本章示例基于Python的深度学习框架PyTorch进行实现。
建议使用PyTorch 1.7及以上版本,并安装必要的依赖:

pip install torch numpy

5.2 邻接矩阵归一化函数

在训练前,需对邻接矩阵加自环并做对称归一化。

import numpy as np
import torch

def normalize_adj(A):
    """
    对邻接矩阵A进行加自环并对称归一化
    A: numpy二维数组,邻接矩阵
    返回归一化后的torch.FloatTensor矩阵
    """
    I = np.eye(A.shape[0])  # 单位矩阵,添加自环
    A_hat = A + I
    D = np.diag(np.sum(A_hat, axis=1))
    D_inv_sqrt = np.linalg.inv(np.sqrt(D))
    A_norm = D_inv_sqrt @ A_hat @ D_inv_sqrt
    return torch.from_numpy(A_norm).float()

5.3 GCN单层实现

定义GCN的核心层,实现邻居特征聚合与线性变换。

import torch.nn as nn
import torch.nn.functional as F

class GCNLayer(nn.Module):
    def __init__(self, in_features, out_features):
        super(GCNLayer, self).__init__()
        self.linear = nn.Linear(in_features, out_features)

    def forward(self, X, A_hat):
        """
        X: 节点特征矩阵,shape (N, in_features)
        A_hat: 归一化邻接矩阵,shape (N, N)
        """
        out = torch.matmul(A_hat, X)  # 聚合邻居特征
        out = self.linear(out)        # 线性变换
        return F.relu(out)            # 激活

5.4 构建完整GCN模型

堆叠两层GCNLayer实现一个简单的GCN模型。

class GCN(nn.Module):
    def __init__(self, n_features, n_hidden, n_classes):
        super(GCN, self).__init__()
        self.gcn1 = GCNLayer(n_features, n_hidden)
        self.gcn2 = GCNLayer(n_hidden, n_classes)

    def forward(self, X, A_hat):
        h = self.gcn1(X, A_hat)
        h = self.gcn2(h, A_hat)
        return F.log_softmax(h, dim=1)

5.5 示例:数据准备与训练流程

# 生成示例邻接矩阵和特征
A = np.array([[0, 1, 0],
              [1, 0, 1],
              [0, 1, 0]])
X = np.array([[1, 0],
              [0, 1],
              [1, 1]])

A_hat = normalize_adj(A)
X = torch.from_numpy(X).float()

# 标签示例,3个节点,2个类别
labels = torch.tensor([0, 1, 0])

# 初始化模型、优化器和损失函数
model = GCN(n_features=2, n_hidden=4, n_classes=2)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
criterion = nn.NLLLoss()

# 训练循环
for epoch in range(100):
    model.train()
    optimizer.zero_grad()
    output = model(X, A_hat)
    loss = criterion(output, labels)
    loss.backward()
    optimizer.step()

    if epoch % 10 == 0:
        pred = output.argmax(dim=1)
        acc = (pred == labels).float().mean()
        print(f"Epoch {epoch}, Loss: {loss.item():.4f}, Accuracy: {acc:.4f}")

5.6 代码说明

  • normalize_adj 对邻接矩阵进行预处理。
  • 模型输入为节点特征矩阵和归一化邻接矩阵。
  • 使用两层GCN,每层后接ReLU激活。
  • 最后一层输出对数概率,适合分类任务。
  • 训练时使用负对数似然损失函数(NLLLoss)。

第六章 GCN训练策略与优化方法

6.1 损失函数选择

GCN的输出通常为每个节点的类别概率分布,常用的损失函数有:

  • 交叉熵损失(Cross-Entropy Loss):适用于多分类任务,目标是最大化正确类别概率。
  • 负对数似然损失(NLLLoss):PyTorch中常用,与softmax配合使用。

示例代码:

criterion = nn.NLLLoss()
loss = criterion(output, labels)

6.2 优化器选择

常用的优化器有:

  • Adam:自适应学习率,收敛速度快,适合多数场景。
  • SGD:带动量的随机梯度下降,适合大规模训练,需调参。

示例:

optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

6.3 防止过拟合技巧

  • Dropout:随机丢弃神经元,防止模型过度拟合。
  • 权重正则化(L2正则化):限制权重大小,避免过拟合。

示例添加Dropout:

class GCNLayer(nn.Module):
    def __init__(self, in_features, out_features, dropout=0.5):
        super(GCNLayer, self).__init__()
        self.linear = nn.Linear(in_features, out_features)
        self.dropout = nn.Dropout(dropout)

    def forward(self, X, A_hat):
        out = torch.matmul(A_hat, X)
        out = self.dropout(out)
        out = self.linear(out)
        return F.relu(out)

6.4 学习率调整策略

  • 学习率衰减:逐步降低学习率,有助于训练后期收敛。
  • 早停(Early Stopping):监控验证集损失,若不再下降则停止训练,防止过拟合。

6.5 批量训练与采样技术

GCN默认一次性处理整个图,对于大规模图计算成本高。常用方法有:

  • 邻居采样(如GraphSAGE):每次采样部分邻居节点,减少计算量。
  • 子图训练:将大图拆分为小子图,分批训练。

6.6 多GPU并行训练

利用多GPU并行加速训练,提高模型训练效率,适合大型图和深层GCN。


6.7 监控指标与调试

  • 监控训练/验证损失、准确率。
  • 使用TensorBoard等工具可视化训练过程。
  • 检查梯度消失或爆炸问题,调节网络结构和学习率。

第七章 GCN在图分类与节点分类的应用

7.1 应用概述

GCN因其对图结构数据的优越建模能力,广泛应用于多种图任务,尤其是:

  • 节点分类(Node Classification):预测图中每个节点的类别。
  • 图分类(Graph Classification):预测整个图的类别。

这两类任务在社交网络分析、化学分子研究、推荐系统等领域都有重要价值。


7.2 节点分类案例

7.2.1 任务描述

给定图及部分带标签的节点,预测未标注节点的类别。例如,在社交网络中预测用户兴趣类别。

7.2.2 数据集示例

  • Cora数据集:学术论文引用网络,节点为论文,边为引用关系,任务是论文分类。
  • PubMedCiteseer也是经典节点分类数据集。

7.2.3 方法流程

  • 输入节点特征和邻接矩阵。
  • 训练GCN模型学习节点表示。
  • 输出每个节点的类别概率。

7.2.4 代码示范

# 见第5章模型训练代码示例,使用Cora数据集即可

7.3 图分类案例

7.3.1 任务描述

预测整个图的类别,比如判断化合物的活性。

7.3.2 方法流程

  • 对每个图分别构建邻接矩阵和特征矩阵。
  • 使用GCN提取节点特征后,通过图级聚合(如全局池化)生成图表示。
  • 使用分类层预测图类别。

7.3.3 典型方法

  • 全局平均池化(Global Average Pooling):对所有节点特征取平均。
  • 全局最大池化(Global Max Pooling)
  • Set2SetSort Pooling等高级方法。

7.3.4 示例代码片段

class GCNGraphClassifier(nn.Module):
    def __init__(self, n_features, n_hidden, n_classes):
        super().__init__()
        self.gcn1 = GCNLayer(n_features, n_hidden)
        self.gcn2 = GCNLayer(n_hidden, n_hidden)
        self.classifier = nn.Linear(n_hidden, n_classes)

    def forward(self, X, A_hat):
        h = self.gcn1(X, A_hat)
        h = self.gcn2(h, A_hat)
        h = h.mean(dim=0)  # 全局平均池化
        return F.log_softmax(self.classifier(h), dim=0)

7.4 其他应用场景

  • 推荐系统:通过用户-物品图预测用户偏好。
  • 知识图谱:实体和关系的分类与推断。
  • 生物信息学:蛋白质交互网络、分子属性预测。

7.5 实际挑战与解决方案

  • 数据规模大:采样和分布式训练。
  • 异构图结构:使用异构图神经网络(Heterogeneous GNN)。
  • 动态图处理:动态图神经网络(Dynamic GNN)技术。

第八章 GCN扩展变种与最新进展

8.1 传统GCN的局限性

尽管GCN模型结构简洁、效果显著,但在实际应用中也存在一些限制:

  • 固定的邻居聚合权重:GCN对邻居节点赋予均一权重,缺乏灵活性。
  • 无法处理异构图:传统GCN仅适用于同质图结构。
  • 过度平滑问题:多层堆叠导致节点特征趋同,信息丢失。
  • 难以扩展大规模图:全图训练计算复杂度高。

针对这些问题,研究者提出了多种扩展变种。


8.2 GraphSAGE(采样和聚合)

8.2.1 核心思想

GraphSAGE通过采样固定数量的邻居节点进行聚合,解决大规模图计算瓶颈。

8.2.2 采样聚合方法

支持多种聚合函数:

  • 平均聚合(Mean)
  • LSTM聚合
  • 最大池化(Max Pooling)

8.2.3 应用示例

通过采样限制邻居数量,显著降低计算开销。


8.3 GAT(图注意力网络)

8.3.1 核心思想

引入注意力机制,根据邻居节点的重要性动态分配权重,增强模型表达能力。

8.3.2 关键公式

注意力系数计算:

$$ \alpha_{ij} = \frac{\exp\left(\text{LeakyReLU}\left(a^T [Wh_i \| Wh_j]\right)\right)}{\sum_{k \in \mathcal{N}(i)} \exp\left(\text{LeakyReLU}\left(a^T [Wh_i \| Wh_k]\right)\right)} $$

其中:

  • $W$是线性变换矩阵
  • $a$是注意力向量
  • $\|$表示向量拼接

8.4 ChebNet(切比雪夫网络)

使用切比雪夫多项式对谱卷积进行更高阶近似,捕获更远邻居信息。


8.5 异构图神经网络(Heterogeneous GNN)

针对包含多种节点和边类型的图,设计专门模型:

  • R-GCN:关系型图卷积网络,支持多种关系。
  • HAN:异构注意力网络,结合多头注意力机制。

8.6 动态图神经网络

处理时间变化的图结构,实现节点和边的时序建模。


8.7 多模态图神经网络

结合图结构与图像、文本等多模态信息,提升模型表达力。


8.8 最新研究进展

  • 图神经网络可解释性研究
  • 图生成模型结合GCN
  • 大规模图预训练模型

第九章 实战案例:使用PyTorch Geometric实现GCN

9.1 PyTorch Geometric简介

PyTorch Geometric(简称PyG)是基于PyTorch的图深度学习库,提供高效的图数据处理和多种图神经网络模型,极大简化了图神经网络的开发流程。

  • 支持稀疏邻接矩阵存储
  • 内置多种图神经网络层和采样算法
  • 兼容PyTorch生态

安装命令:

pip install torch-geometric

9.2 环境准备

确保已安装PyTorch和PyG,且版本兼容。

pip install torch torchvision torchaudio
pip install torch-scatter torch-sparse torch-cluster torch-spline-conv torch-geometric

9.3 数据加载

PyG提供多个常用图数据集的加载接口,如Cora、CiteSeer、PubMed。

from torch_geometric.datasets import Planetoid

dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]
  • data.x:节点特征矩阵
  • data.edge_index:边索引,形状为[2, num\_edges]
  • data.y:节点标签

9.4 GCN模型实现

利用PyG内置的GCNConv层实现两层GCN。

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv

class GCN(torch.nn.Module):
    def __init__(self, num_features, hidden_channels, num_classes):
        super(GCN, self).__init__()
        self.conv1 = GCNConv(num_features, hidden_channels)
        self.conv2 = GCNConv(hidden_channels, 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 = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)
        return F.log_softmax(x, dim=1)

9.5 训练与测试代码

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GCN(dataset.num_features, 16, dataset.num_classes).to(device)
data = data.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
criterion = torch.nn.NLLLoss()

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()
    out = model(data)
    pred = out.argmax(dim=1)
    accs = []
    for mask in [data.train_mask, data.val_mask, data.test_mask]:
        correct = pred[mask].eq(data.y[mask]).sum().item()
        acc = correct / mask.sum().item()
        accs.append(acc)
    return accs

for epoch in range(1, 201):
    loss = train()
    train_acc, val_acc, test_acc = test()
    if epoch % 20 == 0:
        print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, Train Acc: {train_acc:.4f}, Val Acc: {val_acc:.4f}, Test Acc: {test_acc:.4f}')

9.6 代码说明

  • GCNConv 实现了图卷积的核心操作,自动处理邻接信息。
  • data.train_maskdata.val_maskdata.test_mask分别表示训练、验证、测试节点掩码。
  • 训练过程中采用Dropout和权重衰减防止过拟合。

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日