GNN
图神经网络。
分类器
属性 labels_
为图的每个节点分配一个标签。
- class sknetwork.gnn.GNNClassifier(dims: int | Iterable | None = None, layer_types: str | Iterable = 'Conv', activations: str | Iterable = 'ReLu', use_bias: bool | list = True, normalizations: str | Iterable = 'both', self_embeddings: bool | Iterable = True, sample_sizes: int | list = 25, loss: BaseLoss | str = 'CrossEntropy', layers: Iterable | None = None, optimizer: BaseOptimizer | str = 'Adam', learning_rate: float = 0.01, early_stopping: bool = True, patience: int = 10, verbose: bool = False)[source]
用于节点分类的图神经网络。
- 参数:
dims (iterable or int) – 每一层输出的维度(在正向方向)。如果为整数,则为输出层的维度(没有隐藏层)。如果指定了
layers
,则可选。layer_types (iterable or str) – 层类型(在正向方向)。如果为字符串,则在每一层使用相同的类型。可以为
'Conv'
,图卷积层(默认)或'Sage'
(GraphSage)。activations (iterable or str) – 激活函数(在正向方向)。如果为字符串,则在每一层使用相同的激活函数。可以是
'Identity'
,'Relu'
,'Sigmoid'
或'Softmax'
(默认 ='Relu'
)。use_bias (iterable or bool) – 是否在每一层添加偏置项(在正向方向)。如果为
True
,则在每一层使用偏置项。normalizations (iterable or str) – 用于消息传递的邻接矩阵的规范化(在正向方向)。如果为字符串,则在每一层使用相同类型的规范化。可以是
'left'
(按度进行左规范化),'right'
(按度进行右规范化),'both'
(按度的平方根进行对称规范化,默认)或None
(不规范化)。self_embeddings (iterable or str) – 是否为消息传递添加每个节点的嵌入(在正向方向)。如果为
True
,则在每一层添加自嵌入。sample_sizes (iterable or int) – 为每个节点采样的邻域的大小(在正向方向)。如果为整数,则在每一层使用相同的采样大小。仅用于
'Sage'
层类型。loss (str (default =
'CrossEntropy'
) or BaseLoss) – 损失函数的名称或自定义损失函数。layers (iterable or None) – 自定义层(在正向方向)。如果使用,则忽略之前的参数。
optimizer (str or optimizer) –
'Adam'
,基于随机梯度的优化器(默认)。'GD'
,梯度下降。
learning_rate (float) – 学习率。
early_stopping (bool (default =
True
)) – 是否使用提前停止来结束训练。如果为True
,则当验证分数在 patience 个 epoch 内没有改善时,训练就会终止。patience (int (default = 10)) – 在停止拟合之前等待没有改进的迭代次数。
verbose (bool) – 详细模式。
- 变量:
conv1 (conv2, ...,) – 图卷积层。
output (np.ndarray) – GNN 的输出。
labels (np.ndarray) – 预测的节点标签。
history (dict) – 每个 epoch 的训练历史:{
'embedding'
,'loss'
,'train_accuracy'
,'val_accuracy'
}。
示例
>>> from sknetwork.gnn.gnn_classifier import GNNClassifier >>> from sknetwork.data import karate_club >>> from numpy.random import randint >>> graph = karate_club(metadata=True) >>> adjacency = graph.adjacency >>> labels_true = graph.labels >>> labels = {i: labels_true[i] for i in [0, 1, 33]} >>> features = adjacency.copy() >>> gnn = GNNClassifier(dims=1, early_stopping=False) >>> labels_pred = gnn.fit_predict(adjacency, features, labels, random_state=42) >>> round(np.mean(labels_pred == labels_true), 2) 0.88
- backward(features: csr_matrix, labels: ndarray, mask: ndarray)
计算反向传播。
- 参数:
features (sparse.csr_matrix) – 特征,形状为 (n_nodes, n_features) 的数组。
labels (np.ndarray) – 标签,形状为 (n_nodes,) 的数组。
mask (np.ndarray) – 布尔掩码,形状为 (n_nodes,) 的数组。
- fit(adjacency: csr_matrix | ndarray, features: csr_matrix | ndarray, labels: ndarray, n_epochs: int = 100, validation: float = 0, reinit: bool = False, random_state: int | None = None) GNNClassifier [source]
将模型拟合到数据并存储训练参数。
- 参数:
adjacency (sparse.csr_matrix) – 图的邻接矩阵。
features (sparse.csr_matrix, np.ndarray) – 输入特征,形状为 \((n, d)\),其中 \(n\) 是图中节点的数量,\(d\) 是特征空间的大小。
labels (dict, np.ndarray) – 已知标签。负值被忽略。
n_epochs (int (default = 100)) – 迭代次数(遍历整个图的次数)。
validation (float) – 用于验证的训练集比例(介于 0 和 1 之间)。
reinit (bool (default =
False
)) – 如果为True
,则重新初始化 GNN 的可训练参数(权重和偏差)。random_state (int) – 随机种子,用于在多次运行中获得可重复的结果。
- fit_predict(*args, **kwargs) ndarray
将算法拟合到数据并返回标签。与
fit
方法的参数相同。- 返回值:
labels – 节点的标签。
- 返回类型:
np.ndarray
- fit_predict_proba(*args, **kwargs) ndarray
将算法拟合到数据并返回标签的分布。与
fit
方法的参数相同。- 返回值:
probs – 标签的概率分布。
- 返回类型:
np.ndarray
- fit_transform(*args, **kwargs) ndarray
将算法拟合到数据并返回节点的嵌入。与
fit
方法的参数相同。- 返回值:
embedding – 节点的嵌入。
- 返回类型:
np.ndarray
- forward(adjacency: list | csr_matrix, features: csr_matrix | ndarray) ndarray [source]
在图上执行前向传递并返回输出。
- 参数:
adjacency (Union[list, sparse.csr_matrix]) – 邻接矩阵或采样邻接矩阵列表。
features (sparse.csr_matrix, np.ndarray) – 特征,形状为 (n_nodes, n_features) 的数组。
- 返回值:
output – GNN 的输出。
- 返回类型:
np.ndarray
- get_params()
以字典形式获取参数。
- 返回值:
params – 算法的参数。
- 返回类型:
dict
- predict()
返回预测的标签。
- predict_proba()
返回标签的概率分布。
- print_log(*args)
用文本填充日志。
- set_params(params: dict) Algorithm
设置算法的参数。
- 参数:
params (dict) – 算法的参数。
- 返回值:
self
- 返回类型:
Algorithm
- transform()
返回节点的嵌入。
卷积层
- class sknetwork.gnn.Convolution(layer_type: str, out_channels: int, activation: BaseActivation | str | None = 'Relu', use_bias: bool = True, normalization: str = 'both', self_embeddings: bool = True, sample_size: int | None = None, loss: BaseLoss | str | None = None)[source]
图卷积层。
将以下函数应用于嵌入 \(X\)
\(\sigma(\bar AXW + b)\),
其中 \(\bar A\) 是归一化的邻接矩阵(可能包含插入的自嵌入),\(W\),\(b\) 是可训练参数,\(\sigma\) 是激活函数。
- 参数:
layer_type (str) – 层类型。可以是
'Conv'
,卷积运算符如 [1] 中所述,或'Sage'
,如 [2] 中所述。out_channels (int) – 输出的维度。
激活函数 (str (默认 =
'Relu'
) 或自定义激活函数。) – 激活函数。如果为字符串,可以是'Identity'
、'Relu'
、'Sigmoid'
或'Softmax'
。使用偏差 (bool (默认 = True)) – 如果
True
,则添加偏差向量。归一化 (str (默认 =
'both'
)) – 用于消息传递的邻接矩阵的归一化。可以是 ‘left’` (根据度进行左归一化)、'right'
(根据度进行右归一化)、'both'
(根据度的平方根进行对称归一化,默认) 或None
(不进行归一化)。自嵌入 (bool (默认 = True)) – 如果
True
,则除了图中每个节点的邻居嵌入之外,还要考虑自嵌入。样本大小 (int (默认 = 25)) – 每个节点采样的邻域的大小。仅用于
'Sage'
层。
- 变量:
权重 (np.ndarray,) – 可训练的权重矩阵。
偏差 (np.ndarray) – 偏差向量。
嵌入 (np.ndarray) – 节点的嵌入 (在激活之前)。
输出 (np.ndarray) – 层的输出 (在激活之后)。
参考资料
[1] Kipf, T., & Welling, M. (2017). 使用图卷积网络进行半监督分类。 第五届国际学习表征大会。
[2] Hamilton, W. Ying, R., & Leskovec, J. (2017) 大型图上的归纳式表示学习。 NIPS
激活函数
- class sknetwork.gnn.BaseActivation(name: str = 'custom')[source]
激活函数的基类。:param name: 激活函数的名称。:type name: str
损失函数
- class sknetwork.gnn.BaseLoss(name: str = 'custom')[source]
损失函数的基类。
- static gradient(signal: ndarray, direction: ndarray) ndarray
激活函数的梯度。
- 参数:
信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。
方向 (np.ndarray, shape (n_samples, n_channels)) – 获取梯度的方向。
- 返回值:
梯度 – 梯度。
- 返回类型:
np.ndarray,shape (n_samples, n_channels)
- static loss(signal: ndarray, labels: ndarray) float [source]
获取损失值。
- 参数:
signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。
labels (np.ndarray, shape (n_samples)) – 真实标签。
- static loss_gradient(signal: ndarray, labels: ndarray) ndarray [source]
损失函数的梯度。
- 参数:
信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。
labels (np.ndarray, shape (n_samples,)) – 真实标签。
- 返回值:
梯度 – 梯度。
- 返回类型:
np.ndarray,shape (n_samples, n_channels)
- static output(signal: ndarray) ndarray
激活函数的输出。
- 参数:
信号 (np.ndarray, shape (n_samples, n_channels)) – 输入信号。
- 返回值:
输出 – 输出信号。
- 返回类型:
np.ndarray,shape (n_samples, n_channels)
- class sknetwork.gnn.CrossEntropy[source]
带softmax激活的交叉熵损失。
对于一个值为 \(x\)、真实标签为 \(y\) 的单个样本,交叉熵损失为
\(-\sum_i 1_{\{y=i\}} \log (p_i)\)
其中
\(p_i = e^{x_i} / \sum_j e^{x_j}\).
对于 \(n\) 个样本,返回平均损失。
- static gradient(signal: ndarray, direction: ndarray) ndarray
softmax 函数的梯度。
- static loss(signal: ndarray, labels: ndarray) float [source]
获取损失值。
- 参数:
signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。通道数必须至少为2。
labels (np.ndarray, shape (n_samples)) – 真实标签。
- 返回值:
value – 损失值。
- 返回类型:
float
- static loss_gradient(signal: ndarray, labels: ndarray) ndarray [source]
获取损失函数的梯度(包括激活)。
- 参数:
signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。
labels (np.ndarray, shape (n_samples)) – 真实标签。
- 返回值:
gradient – 损失函数的梯度。
- 返回类型:
float
- static output(signal: ndarray) ndarray
softmax 函数的输出 (行和为 1)。
- class sknetwork.gnn.BinaryCrossEntropy[source]
带sigmoid激活的二元交叉熵损失。
对于一个真实标签为 \(y\)、预测概率为 \(p\) 的单个样本,二元交叉熵损失为
\(-y \log (p) - (1-y) \log (1 - p).\)
对于 \(n\) 个样本,返回平均损失。
- static gradient(signal: ndarray, direction: ndarray) ndarray
sigmoid 函数的梯度。
- static loss(signal: ndarray, labels: ndarray) float [source]
获取损失值。
- 参数:
signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。通道数必须至少为2。
labels (np.ndarray, shape (n_samples)) – 真实标签。
- 返回值:
value – 损失值。
- 返回类型:
float
- static loss_gradient(signal: ndarray, labels: ndarray) ndarray [source]
获取损失函数的梯度(包括激活)。
- 参数:
signal (np.ndarray, shape (n_samples, n_channels)) – 输入信号(激活前)。
labels (np.ndarray, shape (n_samples)) – 真实标签。
- 返回值:
gradient – 损失函数的梯度。
- 返回类型:
float
- static output(signal: ndarray) ndarray
sigmoid 函数的输出。
优化器
- class sknetwork.gnn.BaseOptimizer(learning_rate)[source]
优化器的基类。
- 参数:
learning_rate (float (default = 0.01)) – 用于更新权重的学习率。
- class sknetwork.gnn.ADAM(learning_rate: float = 0.01, beta1: float = 0.9, beta2: float = 0.999, eps: float = 1e-08)[source]
Adam 优化器。
- 参数:
learning_rate (float (default = 0.01)) – 用于更新权重的学习率。
beta1 (float) – 用于计算梯度运行平均值的系数。
beta2 (float) – 用于计算梯度运行平均值的系数。
eps (float (默认值 = 1e-8)) – 添加到分母的项,以提高稳定性。
参考资料
Kingma, D. P. 和 Ba, J. (2014)。Adam: 一种随机优化方法。 第 3 届国际学习表征会议。