理论与实践中的梯度提升(第二部分)
原文:
towardsdatascience.com/gradient-boosting-from-theory-to-practice-part-2-25c8b7ca566b
使用 Scikit-Learn 中的梯度提升类解决不同的分类和回归问题
·发布于Towards Data Science ·阅读时间 12 分钟·2023 年 7 月 19 日
–
照片由Luca Bravo拍摄,来源于Unsplash
在第一部分中,我们介绍了梯度提升算法,并展示了其伪代码实现。
在这部分文章中,我们将探讨 Scikit-Learn 中实现这一算法的类,讨论它们的各种参数,并演示如何使用它们解决几个分类和回归问题。
尽管 XGBoost 库提供了一个更优化和高度可扩展的梯度提升实现,但对于小到中等规模的数据集,使用 Scikit-Learn 中的梯度提升类通常更为简便,因为它们有更简单的接口和显著更少的超参数需要调整。
Scikit-Learn 中的梯度提升
Scikit-Learn 提供了以下实现梯度提升决策树(GBDT)模型的类:
-
GradientBoostingClassifier用于分类问题。
-
GradientBoostingRegressor用于回归问题。
除了决策树的标准参数,如criterion, max_depth(默认设置为 3)和min_samples_split,这些类还提供以下参数:
-
损失 — 需要优化的损失函数。在
GradientBoostingClassifier
中,这个函数可以是'log_loss'
(默认值)或'exponential'
(这将使梯度提升表现得像AdaBoost)。在 GradientBoostingRegressor 中,这个函数可以是'squared_error'
(默认值)、'absolute_error'
、'huber'
或‘quantile’(有关这些损失函数之间的差异,请参见这篇文章)。 -
n_estimators — 提升迭代的次数(默认值为 100)。
-
学习率 — 缩小每棵树贡献的因子(默认值为 0.1)。
-
子样本 — 用于训练每棵树的样本比例(默认值为 1.0)。
-
max_features — 搜索每个节点最佳分割时要考虑的特征数量。选项包括指定特征数量的整数、指定特征比例的浮点数、使用特征的平方根的‘sqrt’、使用特征的对数的‘log2’,以及使用所有特征的 None(默认值)。
-
验证比例 — 用作早期停止的验证集的训练集比例(默认值为 0.1)。
-
n_iter_no_change — 当验证评分在前* n_iter_no_change 次迭代中未改善至少tol*时终止训练(默认值为 0.0001)。默认情况下,n_iter_no_change 设置为 None,这意味着早期停止被禁用。
梯度提升估计器还有以下属性,它们是从数据中学习到的:
-
n_estimators_ — 通过早期停止确定的拟合树数量(如果指定,否则设置为n_estimators)。
-
估计器 — 已拟合的树集合。
-
特征重要性 — 模型估计的特征重要性(将在本文后面讨论)。
-
oob_scores — 每次迭代时的袋外样本损失值(仅在subsample < 1.0 时可用)。
-
train_score — 每次迭代时训练集上的损失值。
GradientBoostingClassifier
例如,我们可以对Iris 数据集进行梯度提升分类器的拟合,使用每朵花的前两个特征(萼片宽度和萼片长度)。作为提醒,我们在这个数据集上使用随机森林能够获得 81.58%的测试准确率(经过超参数调整)。让我们看看梯度提升是否能做得更好。
我们首先加载数据集:
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data[:, :2] # we only take the first two features
y = iris.target
然后我们将数据集分为训练集和测试集(使用与之前实验相同的随机种子):
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
现在我们创建一个 GradientBoostingClassifier 模型,使用其默认设置(即,一个由 100 棵树组成的集成,max_depth=3),并将其拟合到训练集:
from sklearn.ensemble import GradientBoostingClassifier
clf = GradientBoostingClassifier(random_state=42)
clf.fit(X_train, y_train)
我们固定梯度提升分类器的随机状态,以便结果可以重复。模型的性能是:
print(f'Train accuracy: {clf.score(X_train, y_train):.4f}')
print(f'Test accuracy: {clf.score(X_test, y_test):.4f}')
Train accuracy: 0.9554
Test accuracy: 0.7895
这些结果与之前通过随机森林获得的结果相同,但在超参数调整之前。
调整超参数
让我们在一些梯度提升超参数上运行随机搜索,以找到更好的模型。为了公平比较,我们使用与随机森林相同的搜索迭代次数(50 次)。
from sklearn.model_selection import RandomizedSearchCV
params = {
'n_estimators': [10, 50, 100, 200, 500],
'max_depth': np.arange(3, 11),
'subsample': np.arange(0.5, 1.0, 0.1),
'max_features': ['sqrt', 'log2', None]
}
search = RandomizedSearchCV(GradientBoostingClassifier(random_state=42), params, n_iter=50, cv=3, n_jobs=-1)
search.fit(X_train, y_train)
print(search.best_params_)
随机搜索找到的最佳模型是:
{'subsample': 0.6, 'n_estimators': 10, 'max_features': 'sqrt', 'max_depth': 3}
即,最佳模型由 10 棵决策树组成,max_depth = 3,每棵树在训练集的 60%随机子样本上进行训练。该模型在训练集和测试集上的准确性是:
best_clf = search.best_estimator_
print(f'Train accuracy: {best_clf.score(X_train, y_train):.4f}')
print(f'Test accuracy: {best_clf.score(X_test, y_test):.4f}')
Train accuracy: 0.8125
Test accuracy: 0.8684
测试集上的准确性显著高于调整后随机森林的结果(86.84%对 81.58%)。
让我们来检查这个分类器找到的决策边界:
梯度提升分类器在鸢尾数据集上找到的决策边界
与随机森林分类器找到的决策边界相比,我们可以看到梯度提升分类器能够捕捉到更多的紫花地丁区域,而不会对异常值过拟合。
GradientBoostingRegressor
为了演示梯度提升回归模型,我们将使用加州住房数据集。该数据集的目标是基于该区的 8 个不同特征(如中位收入或每户平均房间数),预测加州某个区(房块)的中位房价。
我们首先获取数据集:
from sklearn.datasets import fetch_california_housing
data = fetch_california_housing()
X, y = data.data, data.target
feature_names = data.feature_names
然后,我们将数据集分为 80%的训练集和 20%的测试集:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
接下来,我们使用默认设置(即,一个由 100 棵树组成的集成,max_depth=3)拟合一个 GradientBoostingRegressor 到训练集:
from sklearn.ensemble import GradientBoostingRegressor
reg = GradientBoostingRegressor(random_state=0)
reg.fit(X_train, y_train)
该模型的R²得分是:
train_score = reg.score(X_train, y_train)
print(f'R2 score (train): {train_score:.4f}')
test_score = reg.score(X_test, y_test)
print(f'R2 score (test): {test_score:.4f}')
R2 score (train): 0.8027
R2 score (test): 0.7774
这是一个略逊于我们在调整前使用随机森林得到的结果(测试集上的R²得分=0.798)。然而,请注意,默认情况下 RandomForestRegressor 中的树不会被修剪(它们的最大深度没有限制),而 GradientBoostingRegressor 中的树的默认最大深度仅为 3,同时两种估计器的默认树数相同(100)。
调整超参数
让我们通过运行以下随机搜索来调整梯度提升回归模型的超参数:
from sklearn.model_selection import RandomizedSearchCV
params = {
'n_estimators': [10, 50, 100, 200, 500],
'max_depth': np.arange(3, 11),
'subsample': np.arange(0.5, 1.0, 0.1),
'max_features': ['sqrt', 'log2', None]
}
search = RandomizedSearchCV(GradientBoostingRegressor(random_state=0), params, n_iter=50, cv=3, n_jobs=-1)
search.fit(X_train, y_train)
print(search.best_params_)
随机搜索找到的最佳模型是:
{'subsample': 0.7999999999999999, 'n_estimators': 500, 'max_features': 'log2', 'max_depth': 7}
也就是说,最佳模型使用 500 棵树,最大深度为 7,每棵树在训练集的 80%的随机子样本上进行训练,每个节点分裂使用特征的对数数量。
该模型在训练集和测试集上的R²分数是:
best_reg = search.best_estimator_
print(f'R2 score (train): {best_reg.score(X_train, y_train):.4f}')
print(f'R2 score (test): {best_reg.score(X_test, y_test):.4f}')
R2 score (train): 0.9849
R2 score (test): 0.8519
在测试集上的R²分数明显高于随机森林回归器调优后的结果(0.8166)。
学习曲线
我们还可以绘制每次提升迭代中的训练误差和测试误差。训练误差存储在估计器的train_score_属性中。测试误差可以通过调用staged_predict()方法获得,该方法返回一个生成器,按每次迭代返回给定数据集上的模型预测。
from sklearn.metrics import mean_squared_error as MSE
test_score = np.zeros(best_reg.n_estimators_)
for i, y_test_pred in enumerate(best_reg.staged_predict(X_test)):
test_score[i] = MSE(y_test, y_test_pred)
plt.plot(np.arange(best_reg.n_estimators), best_reg.train_score_, label='Training loss')
plt.plot(np.arange(best_reg.n_estimators), test_score, 'r', label='Test loss')
plt.xlabel('Boosting iterations')
plt.ylabel('MSE')
plt.legend()
加州住房数据集上梯度提升回归器的学习曲线
我们可以看到,最小测试误差在大约 100 次迭代后达到,也就是说,该数据集的最佳树木数量约为 100。此外,随着我们向集成中添加更多树,测试误差保持稳定,这表明模型不容易过拟合。
另一种找到最佳树木数量的方法是使用早停法。我们来运行相同的随机搜索,但这次不改变估计器的数量,而是将其设置为固定的 500,并通过将n_iter_no_change设置为 5 来启用早停法。这会自动将训练集的 10%留作验证集,并在验证分数在 5 次迭代内没有提高时终止训练。
from sklearn.model_selection import RandomizedSearchCV
params = {
'max_depth': np.arange(3, 11),
'subsample': np.arange(0.5, 1.0, 0.1),
'max_features': ['sqrt', 'log2', None]
}
search = RandomizedSearchCV(GradientBoostingRegressor(random_state=0, n_estimators=500, n_iter_no_change=5),
params, n_iter=50, cv=3, n_jobs=-1)
search.fit(X_train, y_train)
print(search.best_params_)
reg = search.best_estimator_
print(f'R2 score (train): {reg.score(X_train, y_train):.4f}')
print(f'R2 score (test): {reg.score(X_test, y_test):.4f}')
{'subsample': 0.8999999999999999, 'max_features': 'log2', 'max_depth': 7}
R2 score (train): 0.9227
R2 score (test): 0.8402
与之前的模型相比,这个估计器在测试集上的准确度稍差,这可以通过搜索的随机化以及它只使用了 90%的训练集来构建集成来解释。
我们可以检查在启用早停法之前实际构建了多少棵树,通过检查*n_estimators_*属性来实现:
reg.n_estimators_
118
特征重要性
与其他树基集成方法类似,梯度提升树可以提供数据集中特征的重要性估计,即每个特征对模型预测的贡献程度。这对于模型解释以及进行特征选择都很有用。
单棵决策树中特征的重要性由特征在树中的位置(位于树顶部的特征对树的预测贡献更大)和使用该特征分裂节点所实现的节点纯度减少来决定。在树基集成方法中,如随机森林和梯度提升树,我们对集成中的所有树的特征重要性进行平均。
例如,我们可以绘制我们梯度提升回归器在加州住房数据集中找到的特征重要性:
# Sort the features by their importance
feature_importance = best_reg.feature_importances_
sorted_idx = np.argsort(feature_importance)
# Plot the feature importances
pos = np.arange(len(feature_importance))
plt.barh(pos, feature_importance[sorted_idx])
plt.yticks(pos, np.array(feature_names)[sorted_idx])
plt.xlabel('Feature importance')
加州住房数据集中特征的重要性
在这个数据集中,最重要的特征是 MedInc(中位收入)、房屋位置(经度和纬度)以及 AveOccup(家庭成员的平均数量)。
基于直方图的梯度提升
Scikit-Learn 0.21 引入了两种基于直方图的梯度提升实现:HistGradientBoostingClassifier 和 HistGradientBoostingRegressor,它们类似于 LightGBM [1] 中使用的基于直方图的算法。
这些估计器首先将数据集中的连续特征离散化为整数值的区间(默认为 255 个区间)。在训练过程中,这些区间用于根据达到树中特定节点的样本值构建特征直方图。然后,基于这些直方图找到该节点的最佳分割点。
这种离散化具有以下优点:
-
显著减少了在树的每个节点上考虑的分割点数量。
-
这避免了在每个节点上对连续特征值进行排序的需要(请参阅这篇文章中的“处理连续特征”部分,了解为什么需要从一开始就进行排序)。
此外,直方图估计器的许多部分都进行了并行化。例如,梯度计算在样本之间进行并行化,而在节点上寻找最佳分割点则在特征之间进行并行化。
离散化和并行化共同使得基于直方图的估计器在样本数量较大(n > 10,000)时运行速度远快于标准梯度提升估计器。
此外,基于直方图的估计器内置支持缺失值和分类特征,这避免了在数据预处理时使用填补器或独热编码器的需要。
大多数基于直方图的估计器的参数与 GradientBoostingClassifier 和 GradientBoostingRegressor 相同,唯一的变化如下:
-
估计器的参数被称为 max_iter,而不是 n_estimators。
-
树的默认大小已被修改:max_depth 默认为 None(而不是 3),max_leaf_nodes 设置为 31,而 min_samples_leaf 设置为 20。
-
当样本数量超过 10,000 时,早期停止功能会自动启用。
此外,添加了以下参数:
-
max_bins 表示要使用的最大区间数。不得大于 255。一个额外的区间保留用于缺失值。
-
categorical_features 是一个整数列表,表示数据集中分类特征的位置。
-
interaction_cst 指定交互约束,即在子节点分裂中可以相互交互的特征集(默认为 None)。
HistGradientBoostingClassifier 示例
例如,让我们比较 HistGradientBoostingClassifier 和 GradientBoostingClassifier 在一个人工生成的数据集上的表现。
我们将使用 Scikit-Learn 中的函数 make_hastie_10_2,它生成一个二分类的 10 维数据集,与 Hastie 等人[2]中的示例 10.2 相同。
数据集包含 10 个遵循标准高斯分布的特征,目标是由以下定义的二进制标签:
也就是说,负类位于一个半径为 9.34 的 10 维球体内。
让我们首先生成一个包含 50,000 个样本的数据集:
from sklearn.datasets import make_hastie_10_2
X, y = make_hastie_10_2(n_samples=50000, random_state=0)
然后我们将其分为 80% 的训练集和 20% 的测试集:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
现在我们来训练一个 GradientBoostingClassifier 并测量它的训练时间:
from sklearn.ensemble import GradientBoostingClassifier
clf = GradientBoostingClassifier(random_state=0)
%timeit clf.fit(X_train, y_train)
12.6 s ± 358 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
训练这个模型平均需要 12.6 秒。它在训练集和测试集上的表现是:
print(f'Train accuracy: {clf.score(X_train, y_train):.4f}')
print(f'Test accuracy: {clf.score(X_test, y_test):.4f}')
Train accuracy: 0.9392
Test accuracy: 0.9231
现在我们来训练一个 HistGradientBoostingClassifier 在相同的数据集上:
from sklearn.ensemble import HistGradientBoostingClassifier
clf = HistGradientBoostingClassifier(random_state=0)
%timeit clf.fit(X_train, y_train)
1.53 s ± 120 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
训练这个模型平均只需 1.53 秒(比 GradientBoostingClassifier 快 8 倍以上)。它在训练集和测试集上的表现是:
print(f'Train accuracy: {clf.score(X_train, y_train):.4f}')
print(f'Test accuracy: {clf.score(X_test, y_test):.4f}')
Train accuracy: 0.9725
Test accuracy: 0.9467
测试集上的准确率显著提高(94.67% 代替 92.31%)。
总结
让我们总结一下梯度提升与其他监督学习模型相比的优缺点。
优点:
-
提供高度准确的模型,通常在结构化数据集上表现最佳。
-
通过组合多个弱模型,能够捕捉数据集中的复杂交互和模式。
-
能够通过自动选择相关特征有效处理高维数据集。
-
相较于其他模型,对异常值的敏感性较低,因为每个基础模型从前一个模型的残差中学习。
-
可以处理异质数据类型,包括数值和类别特征。
-
可以处理缺失值而无需插补。
-
提供特征重要性的度量。
-
可以应用于回归和分类任务,并支持多种损失函数。
缺点:
-
训练可能会消耗大量计算资源,特别是在处理大型数据集或当集成模型有很多树时。此外,基础模型的训练无法并行化(例如,与随机森林不同)。
-
比决策树或线性回归等简单模型更难解释,因为解释模型的决策需要跟踪多个树的路径。
-
需要调整多个超参数,包括树的数量、每棵树的大小和学习率。
-
如果没有适当的正则化,或者提升迭代次数过多,可能会对训练集过拟合。
-
与其他模型相比,预测可能会更慢,因为它需要遍历多个树并聚合它们的预测。
最终备注
所有图片均为作者提供,除非另有说明。
你可以在我的 GitHub 上找到本文的代码示例:github.com/roiyeho/medium/tree/main/gradient_boosting
鸢尾花数据集信息:
引用: Fisher, R. A. (1988). Iris. UCI 机器学习库。 doi.org/10.24432/C56C76.
许可证: Creative Commons CC BY 4.0。
加利福尼亚住房数据集信息:
引用: Pace, R. Kelley 和 Ronald Barry (1997), Sparse Spatial Autoregressions, Statistics and Probability Letters, 33, 291-297。
许可证: Creative Commons CC0: 公共领域。
参考资料
[1] Ke 等人 (2017), “LightGBM: A Highly Efficient Gradient Boosting Decision Tree”。
[2] T. Hastie, R. Tibshirani 和 J. Friedman (2009), “Elements of Statistical Learning Ed. 2”, Springer。
梯度提升树:是早期停止还是不早期停止?
利用早期停止方法优化 LightGBM、XGBoost 和 CatBoost
·
关注 发表在 Towards Data Science ·7 分钟阅读·2023 年 3 月 23 日
–
梯度提升决策树(GBDTs)目前在表格数据问题上超越了深度学习,流行的实现如 LightGBM、XGBoost 和 CatBoost 主导了 Kaggle 竞赛[1]。早期停止**—一种在深度学习中常用的技术—也可以在训练和调整 GBDTs 时使用。然而,常见的做法是明确调整 GBDT 集成中的树的数量,而不是使用早期停止。在本文中,我展示了早期停止可以将训练时间缩短一半**,同时保持相同的性能,与明确调整树的数量相媲美。
通过减少训练时间,早期停止可以降低计算成本并减少实践者等待模型运行时的空闲时间。这样的节省在大型 GBDT 应用行业中尤为重要,如内容推荐、金融欺诈检测或信用评分。但早期停止如何在不损害性能的情况下减少训练时间呢?让我们深入探讨。
梯度提升决策树
梯度提升决策树(GBDTs)目前在基于(异质)表格数据的分类和回归问题中取得了最先进的表现(具有多种列类型的二维数据集)。虽然深度学习技术在自然语言处理和计算机视觉中表现出色,但尚未在表格数据领域夺得桂冠[2, 3, 4, 5]。
梯度提升决策树(GBDTs)。
GBDTs 通过顺序地将决策树添加到一个集成中来工作。与随机森林不同,GBDTs 中的树不是独立的。相反,它们被训练来纠正之前树的错误。因此,只要有足够的树,GBDT 模型在训练集上可以实现完美的表现。然而,这种行为——称为过拟合——已知会损害模型对未见数据的泛化能力。
超参数调整与早期停止
为了优化对训练数据的拟合程度,实践者调整几个关键的超参数:树的数量、学习率、每棵树的最大深度等。为了找到最佳的值集,会在一个单独的验证数据集中测试几个配置;在保留数据中表现最佳的模型被选为最终模型。
另一个有助于对抗过拟合的工具是早期停止。早期停止在深度学习中常见,是一种如果保留数据上的性能没有改善,则停止学习过程的技术。在 GBDTs 中,这意味着在这一点之后不再构建更多的树。
早停法在验证集中的损失停止减少时中止训练。
尽管在深度学习中很普遍,但早停法在 GBDT 用户中并不那么流行。相反,常见的是看到从业者通过上述搜索过程调整树木数量。但是如果使用早停法的效果等同于显式调整树木数量呢?毕竟,这两种机制的目标都是找到 GBDT 集合的最佳大小,给定学习率和其他超参数。如果是这样的话,这可能意味着通过使用早停法可以在大大减少的搜索时间内实现相同的性能,因为它会停止那些耗时且不具前景的迭代。让我们来测试这个假设。
实验设置
为此,在作者许可下,我使用了公共银行账户欺诈数据集,该数据集最近在 NeurIPS ’22 上发布[6]。它由一个真实的欺诈检测数据集的合成副本组成,由隐私保护的 GAN 生成。对于 GBDT 的实现,我选择了LightGBM,因其速度快且性能领先[1, 7]。所有在此实验中使用的代码可以在这个 Kaggle 笔记本中找到。
如上所述,为了找到最佳的超参数集,最常见的方法是尝试多种配置。最终,在验证集中表现最好的模型被选为最终模型。我遵循这种方法,在每次迭代中从合理的分布中随机抽取超参数。
为了检验我的假设,我运行了两个并行的随机搜索过程:
-
在没有早停法的情况下,树木数量参数在 10 到 4000 之间均匀测试。
-
使用早停法,最大树木数量设置为 4000,但最终由早停准则定义。早停法监控验证集中的交叉熵损失。训练过程仅在 100 次没有改进的迭代后(即耐心参数)被中止,此时将其重置为最佳版本。
以下函数用于在Optuna研究中运行每次随机搜索试验(为清晰起见已截断;完整版见 上述笔记本)*:
def _objective(t, dtrain, dval, early_stopping):
params = {
'boosting_type': t.suggest_categorical(['gbdt', 'goss']),
'learning_rate': t.suggest_float(0.01, 0.5, log=True),
'min_split_gain': t.suggest_float(0.00001, 2, log=True),
'num_leaves': t.suggest_int(2, 1024, log=True),
'max_depth': t.suggest_int(1, 15),
'min_child_samples': t.suggest_int(2, 100, log=True),
'bagging_freq': t.suggest_categorical([0, 1]),
'pos_bagging_fraction': t.suggest_float(0, 1),
'neg_bagging_fraction': t.suggest_float(0, 1),
'reg_alpha': t.suggest_float(0.00001, 0.1, log=True),
'reg_lambda': t.suggest_float(0.00001, 0.1, log=True),
}
model = lgb.train(
**params, dtrain,
num_boost_round=(
4000 if early_stopping
else trial.suggest_int('num_boost_rounds', 10, 4000)
),
valid_sets=dval if early_stopping else None,
callbacks=(
[lgb.early_stopping(stopping_rounds=100)] if early_stopping
else None))
性能
由于早停法监控验证集上的性能,所有模型都在未见过的测试集上进行评估,从而避免了偏见结果。
测试集上的结果。为了视觉清晰度,底部 20%的试验结果被移除。
是否要早停?两种方法的结果相似。 这一结果在测量交叉熵损失(早停监控的指标)和 5% FPR 下的召回率(一个在此数据集领域特别相关的二分类指标)时都一致[6]。在第一个标准上,无早停策略取得了略微更好的结果,而在第二个标准上,则是早停策略占优。
总之,这次实验的结果未能否定我的假设,即使用早停与显式调节 GBDT 中的树木数量之间没有显著差异。当然,更为稳健的评估需要在多个数据集、超参数搜索空间和随机种子上进行实验。
训练时间
我的假设的一部分是早停通过停止添加无前景的树木来减少平均训练时间。是否可以测量出有意义的差异?
训练时间的分布(以秒为单位)。
结果证实了我的假设的第二部分:使用早停时的训练时间明显减少。即使使用耐心值高达 100 次迭代的策略,平均训练时间也减少了一半,从 122 秒降至 58 秒。这意味着总训练时间从 3 小时 23 分钟减少到 1 小时 37 分钟。
尽管早停机制需要额外的计算来监控验证集上的交叉熵损失,但这些额外计算已在上述测量中考虑在内。
结论
梯度提升决策树(GBDTs)在处理表格数据的问题中目前处于最先进水平。我发现,在训练这些模型时使用早停将训练时间减少了一半,同时保持了与显式调节树木数量相同的性能。这使得像 LightGBM、XGBoost 和 CatBoost 这样的流行 GBDT 实现对大规模行业应用(如数字营销和金融)更具优势。
未来,验证在其他数据集和不同 GBDT 实现中的发现将是重要的。调节耐心参数也可能有益,尽管其最佳值可能会因数据集而异。
除非另有说明,所有图片均由作者提供。
参考文献
[1] H. Carlens. 2022 年竞争性机器学习现状。 ML Contests, 2023.
[2] Y. Gorishniy, I. Rubachev, V. Khrulkov 和 A. Babenko,重新审视用于表格数据的深度学习模型,第 35 届神经信息处理系统会议(NeurIPS 2021)。
[3] R. Shwartz-Ziv 和 A. Armon,表格数据:深度学习并不是你所需的一切,信息融合 81 (2022): 84–90。
[4] V. Borisov, T. Leemann, K. Seßler, J. Haug, M. Pawelczyk 和 G. Kasneci,深度神经网络与表格数据:一项调查,IEEE 神经网络与学习系统汇刊(2022)。
[5] L. Grinsztajn, E. Oyallon 和 G. Varoquaux,为什么树基模型仍然在典型表格数据上优于深度学习?,第 36 届神经信息处理系统会议——数据集和基准追踪(NeurIPS 2022)。
[6] S. Jesus, J. Pombal, D. Alves, A. Cruz, P. Saleiro, R. Ribeiro, J. Gama 和 P. Bizarro,扭转局面:用于机器学习评估的偏倚、不平衡和动态表格数据集,第 36 届神经信息处理系统会议——数据集和基准追踪(NeurIPS 2022)。
[7] G. Ke, Q. Meng, T. Finley, T. Wang, W. Chen, W. Ma, Q. Ye, T. Liu,LightGBM:一种高效的梯度提升决策树,第 31 届神经信息处理系统会议(NIPS 2017)。
梯度下降算法 101
原文:
towardsdatascience.com/gradient-descent-algorithm-101-c226c69d756c
面向初学者的指南
了解在机器学习和深度学习中广泛使用的优化算法
·发表于 Towards Data Science ·6 分钟阅读·2023 年 4 月 25 日
–
山坡 — 由 Ralph (Ravi) Kayden 拍摄于 Unsplash
想象你是山顶上的一滴水,而你的目标是到达位于山脚的湖泊。那座高山有不同的坡度和障碍,因此沿直线下滑可能不是最佳解决方案。你会如何解决这个问题?最佳方案可能是一步一步地迈出小步,每次都朝着更接近目标的方向前进。
梯度下降(GD)就是执行这个操作的算法,对于任何数据科学家来说理解它是至关重要的。它基本且相当简单,但却至关重要,任何愿意进入这个领域的人都应该能够解释它是什么。
在这篇文章中,我的目标是提供一个全面且适合初学者的指南,让大家理解什么是 GD,它的用途是什么,它是如何工作的,并提到不同的变体。
和往常一样,你会在文章末尾找到 资源 部分。
但首先要做的事。
介绍
使用维基百科的定义[1],梯度下降是一种用于寻找可微函数局部最小值的一阶迭代优化算法。尽管这肯定不是最有效的方法,但它在机器学习和深度学习中被广泛使用,尤其是在神经网络中。
基本上,它用于通过在每次迭代中更新一组参数来最小化函数的值。从数学角度来看,它使用导数(梯度)逐渐减小(下降)其值。
但有一个问题:并非所有函数都是可优化的。我们需要一个函数——无论是单变量还是多变量——可微分,即函数定义域中的每一点都有导数,并且凸(U 形或类似)。
现在,在这个简单的介绍之后,我们可以开始深入探讨其背后的数学。
实际案例
因为超越理论会更清晰,让我们使用实际的数字和数值来理解它的作用。
让我们使用一个常见的数据科学案例,我们希望开发一个回归模型。
免责声明:我完全发明了这个,没有逻辑依据来使用这些函数,所有内容都是随机的。目标是展示这个过程本身。
在任何数据科学问题中,成本函数或损失函数是我们要优化的函数。由于我们在使用回归,所以我们将使用这个:
随机回归函数 — 图片由作者提供
目标是找到 f(x,y)的最优最小值。让我绘制一下它的样子:
f(x,y)绘制 a=1 — 图片由作者提供
现在我们的目标是找到“x”和“y”的合适值,以便找到这个成本函数的最优值。我们已经可以从图形上看到它:
-
y=0
-
x 为-1 或 1
进入 GD 本身,因为我们希望让我们的机器学会做相同的事情。
算法
如前所述,梯度下降是一个迭代过程,我们计算梯度并向相反方向移动。这样做的理由是,函数的梯度用于确定函数的斜率。由于我们想向下移动,而不是向上移动,所以我们朝相反的方向移动。
这是一个简单的过程,在每次迭代中我们更新 x 和 y,按照以下方法进行:
梯度下降中的参数更新 — 图片由作者提供
用语言解释,在第 k 次迭代时:
-
使用 x 和 y 在该迭代中的值计算梯度。
-
对于每个变量——x 和 y——将其梯度乘以 lambda (𝜆),这是一个称为学习率的浮点数。
-
从 x 和 y 中分别移除第 2 步中计算出的值。
-
在下一次迭代中,让 x 和 y 具有新的值。
这个过程会重复进行,直到满足某个条件(今天不重要)。一旦满足条件,训练结束,优化也随之结束。我们(或者应该)达到了一个最小值(无论是局部还是全局)。
现在,让我们将这个理论付诸实践。
我们需要做的第一件事是计算 f(x,y)的梯度。梯度对应于一个偏导数的向量:
f(x,y)的梯度 — 图片由作者提供
现在,使用 Python,我要做的就是创建一个循环,迭代计算梯度——使用相应的 x 和 y——并按照上面指定的方式更新这些参数。
在此之前,我将定义两个额外的值:
-
学习率 (𝜆) 可以是固定的也可以是可变的。对于这个简单的教程,它将设置为 0.01。
-
我还会使用一个叫做 eps(epsilon)的值来决定何时停止迭代。一旦两个偏导数都低于这个阈值,梯度下降将停止。我将其设置为 0.0001。
现在,让我们来写一些代码:
import random
# Define constants
eps = 0.0001
lr = 0.01
# Initialize x and y with random values
x = random.uniform(-2, 4)
y = random.uniform(-1, 1)
def f(x,y):
return (x**2 -1)**2 +y**2
def df_x(x):
return 4*x*(x**2 - 1)
def df_y(y):
return 2*y
# Perform gradient descent
while max(df_x(x), df_y(y)) >= eps:
x = x - lr * df_x(x)
y = y - lr * df_y(y)
# Print optimal values found
print(f'x = {x}, y = {y}')
一次随机迭代的结果是:
示例 GD 输出 — 图片来源于作者
我们可以看到这些值接近 x=1 和 y=0,它们确实是函数的最小值。
我忘了提到的是 x 和 y 的初始化。我选择了在随机范围内生成一个数字。在实际问题中,通常需要更多的时间来考虑这些问题。学习率、停止条件以及许多其他超参数也是如此。
但对于我们的情况,这已经足够了。
梯度下降法的变体
我相信你现在已经理解了基本算法。然而,市面上存在多个版本,我认为其中一些值得一提。
-
随机梯度下降法 (SGD)。SGD 是一种变体,在每次迭代时随机选择一个数据点。这减少了计算次数,但显然有其缺点,例如,可能无法收敛到全局最小值。
-
批量梯度下降法 (BGD)。BGD 在每次迭代时使用整个数据集。这对于大型数据集来说并不完全理想,因为计算开销和速度较慢,但另一方面,理论上保证收敛到全局最小值。
-
迷你批量梯度下降法 (MBGD)。这可以被视为 SGD 和 BGD 之间的中间点。它既不使用单个数据点,也不使用整个数据集,而是一个子集。在每次迭代中,我们随机选择一定数量的样本(之前定义过)并仅使用这些样本进行梯度下降。
结论
梯度下降算法在机器学习和深度学习中被广泛使用,但在其他领域也有应用。因此,理解它是任何希望成为数据科学家的人的必修课。
我希望这篇文章澄清了它是什么、它做了什么以及它是如何做到的。
**Thanks for reading the post!**
I really hope you enjoyed it and found it insightful.
Follow me for more content like this one, it helps a lot!
**@polmarin**
如果你想进一步支持我,请考虑通过下面的链接订阅 Medium 的会员:这不会额外花费你任何钱,但会帮助我完成这个过程。非常感谢!
[## 使用我的推荐链接加入 Medium - Pol Marin
阅读 Pol Marin 的每一个故事(以及 Medium 上成千上万其他作家的故事)。您的会员费直接支持 Pol……
medium.com](https://medium.com/@polmarin/membership?source=post_page-----c226c69d756c--------------------------------)
资源
[1] 梯度下降法 — 维基百科
深度学习笔记:梯度下降
神经网络如何“学习”
·
关注 发表在 Towards Data Science ·11 分钟阅读·2023 年 11 月 4 日
–
图片由 Rohit Tandon 提供 / Unsplash
人工神经网络(ANNs)是 通用函数逼近器。只要提供足够的数据、具有适当的架构,并且经过 足够长时间的训练,它们可以逼近任何复杂的函数。
那么“训练”网络到底是什么意思呢?
在 之前关于前馈过程的文章 中,我提到训练一个网络意味着调整其权重的值,以获得对我们试图逼近的函数更好的拟合。
在这篇文章中,我将描述梯度下降算法,它用于调整人工神经网络(ANN)的权重。
让我们从基本概念开始。
从山上下降
想象一下,我们在山顶上,需要到达旁边山谷的最低点。
我们没有地图,天气阴霾,天色渐暗,我们丢失了路线,需要尽快到达底部。这不是一个好场景,但它展示了问题的“边界”。
为了安全起见,假设山上没有陡峭的山脊,因此它类似于一个可微函数。
从蒙维索峰(Monviso peak)下山。靠近翁奇诺,库内奥的小山谷。图像由作者提供。
当天黑时,我们看不到我们移动的方向。我们唯一能做的就是迈小步,并检查我们是否处于较低的高度。
如果我们注意到自己向上移动了,我们就朝相反的方向前进。如果我们向下移动,我们就继续这样做。我们重复这个过程,直到最终到达底部。
如你所见,这不一定是最佳的方法。我们可能会到达一个小山谷,而不是山底,或者可能会在一个平原上花费大量时间。
这说明了梯度下降的基本工作原理及其主要挑战。我们会回到这个例子,但首先让我们看看更正式的解释。
什么是梯度?
梯度是函数变化率的表示。它指示了最大增减方向。直观地说,这意味着在局部最大值或局部最小值处梯度为零。
对于依赖多个变量(或坐标轴)的函数,梯度是一个向量,其分量是函数在给定点的偏导数。这用符号∇(nabla)表示,代表向量微分算子。
让我们用数学符号来看一下。假设我们有一个 n 维函数 f:
该函数在点 p(由 n 个坐标确定)处的梯度为:
回到山的例子,山上有些地方地势陡峭,比如山坡,还有些地方地势几乎平坦,比如山谷或平原。山谷和平原代表局部最小值,这通常是关键点。
梯度下降方法
对于许多优化问题,我们的目标是最小化损失函数,以实现最准确的结果。
在深度学习和人工神经网络(ANN)中,我们使用的损失函数是可微的:它们在整个定义域内平滑且无不连续性。
这使我们能够使用相对于自变量的损失函数的导数作为是否正在朝着解决方案(全局最小值)移动的指示。
我们在与导数成比例时的步长有多大?这由步长参数η决定(当我们谈论深度学习时,我们可以称之为学习率)。它将乘以梯度,调整步长的大小。
这样一来,更陡的梯度将产生更大的步长。当我们接近局部最小值时,斜率(梯度)将趋近于零。
让我们看一下下面的图,以说明在优化一维函数时这如何工作:
一维问题中梯度下降的简化示例。图片由作者提供。
正如你所看到的,我们从一个任意点(我画了两个例子,A 和 B)初始化我们的“搜索”以寻找最小值。我们逐渐向最近的最小值迈进,θ的变化与斜率成比例。
插图表示以下算法的功能(伪代码)[1]:
θ(0) = θ_init # Initialization of optimization variable
η = 0.02 # Arbitrary step-size parameter
Є = 0.01 # Optimization accuracy
k = 0 # Iteration counter
while |f(θ(k+1) - f(θ(k))| > Є:
θ(k+1) = θ(k) - η ∇f(θ(k))
k = k + 1
这里的损失函数就像我们在黑暗中没有地图的山脉:我们不知道它的样子。我们想知道哪个θ值能使J最小化,但优化算法并不知道J在所有可能的θ输入下的值。
这就是为什么我们用任意的θ值初始化我们的优化算法。例如,图中的点 A 和 B 表示两个不同的初始化值。
梯度下降的潜在问题
梯度下降算法是有效的,因为它可以帮助我们为任何凸函数获得一个近似解。
如果我们尝试优化的函数是凸的,对于任何值ϵ,都有某个步长η使得梯度下降将在ϵ内收敛到θ的真实最优值θ。 [1]
然而,正如你可能猜到的,这并不完美。算法可能会收敛,但这并不保证我们会找到全局最小值。
梯度下降的主要挑战如下:
任意初始化对结果有影响
使用不同的初始化值,我们可能会遇到局部最小值而不是全局最小值。
例如,从上图中的点 B 开始,而不是点 A。
或者更不明显的情况,例如,像下图中的蓝线所示,收敛到一个平台(梯度消失问题)。
香草梯度下降在鞍形表面上的效果。动画显示了不同初始化点可能产生不同结果的情况。图片由作者提供。
💡 如果你对如何创建这种动画感兴趣,可以查看我的文章 在 Python 中创建梯度下降动画。
选择适当的步长需要在收敛速度和稳定性之间做出权衡。
步长或学习率与我们应使用的轮次数之间存在相互作用,以实现准确的结果。
以下面的参数实验结果为例。这些图像来自 Mike X Cohen 的在线课程 深度学习的深刻理解,我强烈推荐给任何对深度学习感兴趣并使用 PyTorch 的人,遵循科学的方法。
在这种情况下,Mike 展示了如何在独立改变学习率和训练轮次(一个参数随时间变化,网格上不同的值)时测试梯度下降优化的结果。我们可以看到这两个参数如何影响这个特定案例的结果。
图像来自 Mike X Cohen 的在线课程 深度学习的深刻理解。
函数的真正全局最小值在-1.4 左右。对于较小的学习率,收敛到该结果需要更多的训练轮次。因此,单纯使用更大的学习率似乎可以帮助我们减少计算时间。
但实际上,这并不是一个简单的收敛速度问题。
大步长可能导致非常缓慢的收敛,阻止算法完全收敛(在极小值周围不断振荡),或引发发散行为。
下一张图显示了不同学习率如何影响优化结果,即使我们在同一位置 x = 2 初始化算法。
对 f(x)=x² 应用不同步长的随机梯度下降示例。在所有情况下,算法都在 x = 2 处初始化。图像由作者提供,基础代码改编自 Saraj Rival 的笔记本。
在这里,很明显大步长能提高收敛速度,但仅到达某一点为止。
将学习率提高一个数量级导致算法陷入困境。η = 1 的结果在 x = 2 和 x = -2 之间振荡,这仅由左侧图中的蓝色水平线表示。
在某些情况下,大步长可能会将结果“射”向无限,导致程序的数值溢出。
另一方面,过小的步长可能导致非常缓慢的收敛或完全不收敛。
神经网络训练的梯度下降
在深度学习的背景下,我们试图优化的函数是我们的损失函数 J。我们将训练损失定义为所有训练数据集损失的平均值:
其中 Dtrain 是我们训练数据集中的样本数量。
因此,我们可以基于以下算法实现梯度下降,其中我们计算训练损失的梯度以执行模型权重的更新,并重复若干次迭代[2]
w = [0, ... ,0] # Initialize the weights
for k = 1,..., n_iters: # Repeat for n iterations
grad = ∇w TrainLoss(w) # Gradient of the Training losses
w[k] <-- w[k-1] - η * grad # Update the model weights
由于我们计算的是损失函数的梯度平均值,因此我们对它有更好的估计。因此,权重更新更有可能朝着改善模型性能的方向进行。
这种梯度下降实现的问题是其速度较慢。
对于一个有几个点和一个简单函数的玩具示例,它可能效果很好,但想象一下我们在开发一个 ANN,并且我们有一百万个数据点来训练它。
要用这个算法训练 ANN,我们需要计算模型对每个训练数据样本的输出,然后将它们的损失平均作为一个大批量。仅仅为了做一次权重更新。然后不断重复,直到达到收敛。
这被称为批量梯度下降。它每次迭代做一次(准确的)权重更新,但每次迭代可能需要很长时间,因为我们重复模型计算 n 次。
为了克服这个问题,我们可以使用所谓的随机梯度下降算法。
随机梯度下降
为了克服批量梯度下降的慢收敛问题,我们可以基于训练集中的每个样本来更新模型权重。其优点是我们不需要等到遍历整个数据集后才进行一次权重更新。
我们可以通过使用每个个体样本的损失函数来做到这一点,而不是使用考虑整个数据集作为批量的训练损失。
这就是随机梯度下降算法(SGD)的样子
w = [0, ... ,0] # Initialize the weights
for k = 1,..., n_epoch:
for (x, y) ∈ Dtrain: # For each sample
grad = ∇w J(x,y,w)
w[k] <-- w[k-1] - η(k) * grad # Update the model weights
注意步长是训练迭代的一个函数。这是因为为了使算法收敛,η必须随着迭代次数的增加而减小。
在MIT 6.036 的讲义 [1]中提到以下定理:
定理 4.1。如果 J 是凸的,并且 η(t) 是一个满足
然后 SGD 以概率 1 收敛到最优θ。
人们采取不同的方法来在训练过程中降低η的值,这通常被称为“退火”:
-
根据训练轮次调整学习率(例如,η(t) = 1/t),或者在达到某个学习轮次后将其设为更小的值。这个方法效果很好,但与模型性能无关。这被称为“学习率衰减”,是处理此问题的行业标准。
-
将学习率乘以损失函数的梯度:这种方法很好,因为它对问题是自适应的,但需要仔细调整。这已经被纳入了 RMSprop 和 Adam 梯度下降的变体中。
-
将学习率乘以损失:优点是这种方法同样对问题自适应,但也需要缩放。
SGD 在仅访问部分数据后可能表现良好。这种行为对相对较大的数据集很有用,因为我们可以减少所需的内存量,并且与“原生”梯度下降实现相比,总运行时间较短。
我们可以说,批量实现较慢,因为它需要遍历所有样本才能进行一次权重更新。
SGD 在每个样本上执行更新,但更新的质量较低。我们可能有噪声数据或一个非常复杂的函数需要用我们的 ANN 拟合。
使用大小为 Dtrain 的批量很慢,但准确,使用大小为 1 的批量很快,但不够准确。
在两者之间有一个术语,称为“mini-batch”梯度下降。
Mini-Batch 梯度下降
图片由Sebastian Herrmann提供,来源于Unsplash
如果我们将数据分成大小相等的更小批量,我们可以做批量梯度下降所做的事情,但针对每个mini-batch。
假设我们将数据分成 100 个更小的部分。
我们将数据分成 100 步。在每一步中,我们仅查看当前 mini-batch 中数据的训练损失,并改进我们的模型参数。我们重复这一过程,直到查看所有样本,然后重新开始循环。
每个循环称为周期。我之前更宽泛地使用了这个术语来指代优化过程中的迭代次数,但通常的定义指的是每次遍历训练数据集。对于批量梯度下降,迭代就是一个周期。
当我们设置训练 ANN 的周期数时,我们是在定义通过训练数据集的遍历次数。
使用 mini-batch 的优点是我们在每个 mini-batch 上更新模型参数,而不是在查看整个数据集后再更新。
对于批量梯度下降,批量大小是训练数据集中样本的总数。对于 mini-batch 梯度下降,mini-batch 通常是 2 的幂次:32 个样本、64、128、256 等。
当 mini-batch 大小减少到训练数据集中的单个示例时,SGD 将是一个极端情况。
使用 mini-batch 梯度下降的缺点是我们引入了一定程度的变异性——虽然比随机梯度下降(SDG)轻微。这并不保证每一步都会使我们更接近理想参数值,但总体方向仍然是向最小值靠近。
这种方法是行业标准之一,因为通过找到最佳批量大小,我们可以在处理非常大的数据集时在速度和准确性之间进行折衷。
感谢阅读!我希望这篇文章对你有趣,并且帮助你澄清了一些概念。我还分享了撰写这篇文章时使用的资料,供你参考,以便深入了解更正式的内容。
在未来的帖子中,我将写关于 更高级的梯度下降方法(那些人们在实际应用中使用的方法)以及我们如何在训练过程中实际更新模型权重,使用反向传播,因为梯度下降只是整个过程的一部分。
与此同时,你可能会对阅读我之前的文章感兴趣,关于前馈人工神经网络:
基本概念解释
参考文献
[1] MIT 开放学习图书馆:6.036 机器学习导论。第六章:梯度下降
[2] 斯坦福在线:人工智能与机器学习 4 — 随机梯度下降 | 斯坦福 CS221 (2021)
[3] 在线课程 深入理解深度学习,由 Mike X Cohen 提供( sincxpress.com)
最初发表于 https://www.makerluis.com 于 2023 年 11 月 4 日。
梯度下降:优化与初始化解释
高层次的优化介绍,7 分钟阅读
·
关注 发表在 Towards Data Science ·7 分钟阅读·2023 年 1 月 14 日
–
图片来源于 vackground.com 在 Unsplash
训练一个深度学习模型涉及一组模型参数的调整,将这些参数逐步逼近某个最优值集合。最优值集合被定义为模型在执行某个任务时达到最佳表现的点。
直观上,这可以被认为是我们学习新技能时的情况。例如,如果你决定尝试一项新运动,你很可能在第一次玩的时候表现得相当差劲(当然忽略任何天才儿童)。
然而,随着时间的推移,你会提高并学习如何将你自己的参数(在大脑中)向某个最佳值转变,以改善这项运动。
这些参数如何移动?
设想我们有一个度量值,它定义了我们在某项运动中的差劲程度。这个值越高,我们就越差;值越低,我们就越好。有点像高尔夫中的差点。
图像由Steven Shircliff提供,Unsplash上的图片
我们可以进一步设想,调整这些参数将对该度量值产生一些影响,即随着我们向最佳参数集合移动,度量值会降低(我们在任务中表现得更好)。
希望这能让你明白……但如果没有也没关系!我们会查看一个图示,试图解释这种情况。
可视化优化
图示展示了提高高尔夫水平的优化高级描述。图像由作者提供。
以上图为例,我们的高尔夫差点在A 点(情况相当糟糕——初学者水平),这就是我们开始向泰格·伍兹水平进发的地方!
我们应该朝哪个方向移动以达到 B 点(高尔夫的职业水平)?
你说左边?正确!
从数学上讲,这涉及到在 A 点找到梯度并沿着最陡下降的方向移动。
“等等,等等……提醒我一下梯度是什么”
梯度定义了函数变化的最陡速率。
该图展示了在函数不同点上梯度估计的局部性。图像由作者提供。
由于这个梯度仅在局部计算,即 A 点的梯度仅在 A 点正确,所以我们不希望在距离此点太远的地方信任这个梯度。例如,在图片中,点 X 和 Y 的梯度非常不同。
因此,在实际操作中,我们将梯度乘以学习率,它告诉我们向 B 点移动的距离。(我们稍后会再回来讨论这个!)
这是局部性论点,它是现代梯度下降优化算法的支柱之一。
局部性与学习率
想象你正在开车,你知道你想到达哪里,但不知道怎么走(也没有导航)。
你可以做的最好的事情是依靠指示标志来指导你朝着目标前进。
照片由 Brendan Church 提供,来源于 Unsplash
然而,这些指示牌只在出现的地方有效。例如,继续直行的指示不一定在 2 英里后仍然有效。
这些指示牌有点像我们在优化算法中的梯度计算。它们包含关于旅行方向(或函数形状)在特定点的局部信息。
根据你多么谨慎(或冒险),你可能更喜欢每 200 米设置一个指示牌,或者你可能满意每两英里设置一个。完全取决于旅程的情况!
例如,如果是一条长而直的道路,我们可以用很少的指示牌。但如果是一个复杂的旅程,充满了许多转弯,我们很可能需要更多的指示牌。
显示不同类型函数的小学习率和大学习率之间差异的两个图。图片由作者提供。
这就是我们如何看待学习率。如果我们有一个像左边的那样的函数,我们可能能够使用较大的学习率(类似于一条长直的道路)。
然而,如果我们有右边的这个,这将需要一个更小的学习率,因为我们可能会超越我们的目标(错过一个转弯)。
还值得一提的是,我们很可能无法仅通过一个方向从 A 点到 B 点(除非我们已经非常接近)。因此,实际上,梯度下降通常是一个迭代过程,我们在旅程中的路标上接收指示(A 到 B 变成 A 到 C 到 D 到 E 到 B)。
因此,希望我们能够对学习率和路标数量之间的关系建立一些直觉。
将所有内容整合起来…
好的,希望我们已经对优化的目标和一些需要考虑的概念有了一个清晰的了解!
使用上述信息,我们现在可以定义梯度下降算法。
回到我们之前的图片,我们将点 A 的参数标记为(⍬₀),最终参数标记为点 B ⍬。
在从点 A 到第一个路标(点 C)的第一次迭代中,我们可以写出一个方程来描述参数更新。为此我们需要考虑:
-
在点 A 的性能指标 L 的梯度(相对于参数)
-
一个学习率
-
初始参数 ⍬₀
-
更新的参数 ⍬₁
单次梯度下降更新的方程。图片由作者提供。
以下参数更新是类似地计算的,因此我们能够写出通用公式为:
一般梯度下降步骤的方程。图片由作者提供。
初始值
好吧,标题承诺了关于初始值的一些讨论。
对于那些对目前没有提及这方面内容感到非常愤怒的人……非常抱歉!但希望这一部分能让你满意!
从上述所有描述来看,很容易理解初始值如何融入整体图景。
图示说明了不同初始值下的数值差异。图片由作者提供。
我之前提到了某个神童?我们称她为 Pam。就本文中的第一张图片而言,这在某种程度上相当于 Pam 在点 P 处拥有一些初始参数,而不是点 A。顺便说一下,Pam 是那个戴着皇冠和带着得意笑容的人——她知道自己很棒!
对初始值的高层次解释是,你从哪里开始你的优化。
一个好的初始值可以减轻优化算法的压力,而一个好的优化算法也可以为初始值做出相同的贡献。实际上,一个好的初始值可以在训练具有大量参数的深度学习模型时节省数百小时的计算时间。
由于这一点,许多不同的研究领域专注于开发更好的初始值****技术。这之所以非常困难,本质上就像是在对未来进行预测,而对我们所处的环境了解不多。
初始值重要的另一个原因与我们可能在优化之后所处的位置有关。
图示展示了不同初始值下梯度下降优化的不同结果。图片由作者提供。
请考虑上面的新优化表面。它有许多不同的最小值——其中一些比其他的更好!
在这张图中,很明显我们的起始点会严重影响我们最终的结果。这也是为什么对于机器学习从业者来说,实验不同的初始值以及调整超参数(如学习率)如此重要,以便在特定任务中找到最佳模型。
结论
在这篇文章中,我们介绍了一些关于梯度下降、优化和初始值的高层次解释。我们可视化了优化和初始值的目标,图形化地研究了这些概念,介绍了学习率的概念,甚至写下了梯度下降的公式!
希望这能帮助你建立对这些重要概念的直觉,并加深对梯度下降公式来源的理解!
感谢阅读,敬请关注更多与优化技术相关的文章!
一如既往,欢迎告知我任何问题或评论!
梯度下降与梯度提升:逐一对比
原文:
towardsdatascience.com/gradient-descent-vs-gradient-boosting-a-side-by-side-comparison-7067bb3c5712
从初始化到收敛的简单英语
·发表于Towards Data Science ·阅读时长 5 分钟·2023 年 2 月 28 日
–
引言
梯度下降和梯度提升是两种流行的机器学习算法。尽管它们的处理方法和应用不同,但这两种算法都基于梯度计算,并且共享若干相似步骤。本文的主要目的是详细比较这两种算法,帮助读者更好地理解它们的相似之处和不同之处。
图片由Gregoire Jeanneau提供,来源于Unsplash
梯度下降
梯度下降是机器学习中常用的优化算法,用于最小化成本函数。目标是找到一组最佳参数,以最小化预测值与实际值之间的误差。该过程开始时随机初始化模型的权重或系数。然后,它通过计算成本函数相对于每个参数的梯度,迭代地更新权重,沿着成本函数的最大下降方向进行。
梯度提升
梯度提升是一种集成方法,通过结合多个弱模型来创建一个更强的预测模型。它通过迭代地将新模型拟合到前一个模型的残差错误来进行工作。最终的预测是所有模型预测值的总和。在梯度提升中,重点是前一个模型所犯的错误。
不同却相似
为了提供梯度下降和梯度提升的全面比较,我们将首先分别解释这两种算法,然后逐步比较每种算法的优化方法。这种方法将帮助读者更好地理解这两种算法的相似性和差异。
梯度下降算法的简单英语解释
以下是一些用简单英语解释梯度下降的步骤:
-
选择起点:梯度下降从随机或预定义的模型权重或系数开始。
-
计算梯度:梯度是函数的最陡上升或下降方向。在梯度下降中,我们计算成本函数相对于每个参数的梯度。成本函数衡量模型对训练数据的拟合程度。
-
更新权重:一旦我们获得梯度,就更新模型的权重,方向与梯度相反。更新的大小由学习率决定,学习率控制每次迭代中权重的调整幅度。
-
直到收敛:我们重复步骤 2 和 3,直到达到成本函数的最小值,这对应于模型的最佳权重集。收敛标准可能有所不同,例如达到一定的迭代次数或当成本函数的变化变得足够小时。
通过迭代地调整权重,朝着成本函数的最陡下降方向,梯度下降旨在找到最佳的参数集,以最小化预测值和实际值之间的误差。
梯度提升算法的简单英语解释
以下是一些用简单英语解释梯度提升的步骤:
-
训练一个弱模型:我们从训练一个弱模型开始,比如决策树或回归模型,使用训练数据。弱模型可能单独表现不佳,但可以进行一些预测。
-
计算误差:我们计算弱模型的预测值和实际值之间的误差。这个误差成为下一个模型的目标。
-
训练新模型:我们训练一个新模型来预测前一个模型的错误。这个新模型在前一个模型的残差或错误上进行拟合。
-
合并模型:我们将所有模型的预测结果合并以进行最终预测。最终预测是所有模型预测结果的总和。
-
直到收敛:我们重复步骤 2 到 4,向集成中添加新模型,直到达到预定义的模型数量或在验证集上的性能停止提升。
通过迭代地将新模型拟合到前一个模型的残差中,梯度提升旨在提高模型的准确性。最终预测是所有模型预测的组合,每个模型都纠正前一个模型的错误。梯度提升可以有效地处理非线性关系、缺失值和异常值。
并排比较
这里是梯度下降和梯度提升每一步的并排比较:
1. 初始化:
-
梯度下降:随机或预定义初始化模型的权重或系数。
-
梯度提升:在训练数据上训练一个弱模型,例如决策树或回归模型。
2. 错误计算:
-
梯度下降:计算模型在整个训练集上的预测值与实际值之间的误差或损失。
-
梯度提升:计算弱模型在训练集上的预测值与实际值之间的误差或残差。
3. 更新或拟合:
-
梯度下降:根据学习率和成本函数的梯度,沿着梯度的反方向更新模型的权重。
-
梯度提升:拟合一个新模型以预测前一个模型的残差错误,基于弱模型的错误和训练数据。
4. 组合:
-
梯度下降:不需要组合,因为目标是优化单个模型的参数。
-
梯度提升:结合所有模型的预测结果以做出最终预测。最终预测是所有模型预测结果的总和。
5. 收敛:
-
梯度下降:重复步骤 2 到 4,直到达到收敛,这可能取决于如迭代次数或成本函数的变化等标准。
-
梯度提升:重复步骤 2 到 4,向集成中添加新模型,直到达到预定数量的模型或在验证集上的性能停止改善。
结论
梯度下降和梯度提升都依赖梯度计算来优化模型,但它们在方法和目的上有所不同。梯度下降专注于最小化单一模型的成本函数,而梯度提升则旨在提高模型集成的准确性。
尽管梯度下降和梯度提升具有不同的优化目标,但它们共享基于梯度下降的共同算法基础。在梯度下降中,算法优化单个模型的参数以最小化成本函数。相比之下,梯度提升旨在通过迭代添加新模型来优化模型集成,以最小化集成的成本函数。然而,这两种算法都使用梯度下降作为基本优化技术。
图卷积网络:GNNs 简介
使用 PyTorch Geometric 的逐步指南
·
关注 发表在Towards Data Science ·16 分钟阅读·2023 年 8 月 14 日
–
作者提供的图像
图神经网络(GNNs)是深度学习领域中最吸引人和迅速发展的架构之一。作为处理图结构数据的深度学习模型,GNNs 带来了显著的多样性和强大的学习能力。
在各种类型的 GNN 中,图卷积网络(GCNs)已经成为最普遍且广泛应用的模型。GCNs 因其能够利用节点的特征及其局部信息进行预测而具有创新性,提供了一种有效处理图结构数据的方法。
在本文中,我们将深入探讨 GCN 层的机制,并解释其内部工作原理。此外,我们还将探索其在节点分类任务中的实际应用,使用PyTorch Geometric作为我们的工具。
PyTorch Geometric 是 PyTorch 的一个专门扩展,专为 GNNs 的开发和实现而创建。它是一个高级但用户友好的库,提供了一整套工具来促进基于图的机器学习。为了开始我们的旅程,我们需要安装 PyTorch Geometric。如果你使用 Google Colab,PyTorch应该已经安装好了,因此我们只需要执行几个额外的命令。
所有代码都可以在Google Colab和GitHub上找到。
!pip install torch_geometric
import torch
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
现在 PyTorch Geometric 已经安装好了,让我们探索一下本教程中将使用的数据集。
🌐 I. 图数据
图是表示对象之间关系的重要结构。你可以在许多现实世界的场景中遇到图数据,例如社交和计算机网络、分子化学结构、自然语言处理和图像识别等。
在这篇文章中,我们将研究臭名昭著且广泛使用的扎卡里的空手道俱乐部数据集。
图片作者提供
扎卡里的空手道俱乐部数据集体现了 1970 年代 Wayne W. Zachary 观察到的空手道俱乐部内部形成的关系。这是一种社交网络,其中每个节点代表一个俱乐部成员,节点之间的边代表发生在俱乐部环境之外的互动。
在这个特定的场景中,俱乐部成员被分为四个不同的组。我们的任务是根据他们的互动模式给每个成员分配正确的组(节点分类)。
让我们使用 PyG 的内置函数导入数据集,并尝试了解它使用的Datasets
对象。
from torch_geometric.datasets import KarateClub
# Import dataset from PyTorch Geometric
dataset = KarateClub()# Print information
print(dataset)
print('------------')
print(f'Number of graphs: {len(dataset)}')
print(f'Number of features: {dataset.num_features}')
print(f'Number of classes: {dataset.num_classes}')
KarateClub()
------------
Number of graphs: 1
Number of features: 34
Number of classes: 4
该数据集仅包含 1 个图,其中每个节点具有 34 维的特征向量,并且属于四个类别中的一个(我们的四个组)。实际上,Datasets
对象可以看作是Data
(图)对象的集合。
我们可以进一步检查我们独特的图,以了解更多信息。
# Print first element
print(f'Graph: {dataset[0]}')
Graph: Data(x=[34, 34], edge_index=[2, 156], y=[34], train_mask=[34])
[Data](https://pytorch-geometric.readthedocs.io/en/latest/modules/data.html)
对象特别有趣。打印它可以很好地总结我们正在研究的图:
-
x=[34, 34]
是节点特征矩阵,其形状为(节点数,特征数)。在我们的例子中,这意味着我们有 34 个节点(我们的 34 个成员),每个节点都与一个 34 维特征向量相关联。 -
edge_index=[2, 156]
表示图的连通性(节点如何连接),其形状为(2,定向边的数量)。 -
y=[34]
是节点真实标签。在这个问题中,每个节点被分配到一个类别(组),因此我们对每个节点有一个值。 -
train_mask=[34]
是一个可选属性,用于指定哪些节点应用于训练,列表中包含True
或False
。
让我们打印这些张量以了解它们存储了什么。我们从节点特征开始。
data = dataset[0]
print(f'x = {data.x.shape}')
print(data.x)
x = torch.Size([34, 34])
tensor([[1., 0., 0., ..., 0., 0., 0.],
[0., 1., 0., ..., 0., 0., 0.],
[0., 0., 1., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 1., 0., 0.],
[0., 0., 0., ..., 0., 1., 0.],
[0., 0., 0., ..., 0., 0., 1.]])
在这里,节点特征矩阵x
是一个单位矩阵:它不包含任何相关信息关于节点。它本可以包含诸如年龄、技能水平等信息,但在这个数据集中并非如此。这意味着我们只能通过查看节点之间的连接来对它们进行分类。
现在,让我们打印边索引。
print(f'edge_index = {data.edge_index.shape}')
print(data.edge_index)
edge_index = torch.Size([2, 156])
tensor([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7,
7, 7, 8, 8, 8, 8, 8, 9, 9, 10, 10, 10, 11, 12, 12, 13, 13, 13,
13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21,
21, 22, 22, 23, 23, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 27, 27,
27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31,
31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33],
[ 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 19, 21, 31, 0, 2,
3, 7, 13, 17, 19, 21, 30, 0, 1, 3, 7, 8, 9, 13, 27, 28, 32, 0,
1, 2, 7, 12, 13, 0, 6, 10, 0, 6, 10, 16, 0, 4, 5, 16, 0, 1,
2, 3, 0, 2, 30, 32, 33, 2, 33, 0, 4, 5, 0, 0, 3, 0, 1, 2,
3, 33, 32, 33, 32, 33, 5, 6, 0, 1, 32, 33, 0, 1, 33, 32, 33, 0,
1, 32, 33, 25, 27, 29, 32, 33, 25, 27, 31, 23, 24, 31, 29, 33, 2, 23,
24, 33, 2, 31, 33, 23, 26, 32, 33, 1, 8, 32, 33, 0, 24, 25, 28, 32,
33, 2, 8, 14, 15, 18, 20, 22, 23, 29, 30, 31, 33, 8, 9, 13, 14, 15,
18, 19, 20, 22, 23, 26, 27, 28, 29, 30, 31, 32]])
在图论和网络分析中,节点之间的连通性通过多种数据结构进行存储。edge_index
就是这种数据结构之一,其中图的连接存储在两个列表中(156 条定向边,相当于 78 条双向边)。这两个列表的原因在于一个列表存储源节点,而第二个列表标识目标节点。
这种方法称为坐标列表(COO)格式,本质上是一种高效存储稀疏矩阵的方式。稀疏矩阵是高效存储大部分为零元素的矩阵的数据结构。在 COO 格式中,仅存储非零元素,从而节省内存和计算资源。
相反,更直观和简洁的表示图连通性的方法是通过邻接矩阵 A。这是一个方阵,其中每个元素Aᵢⱼ s指定图中从节点i到节点j的边的存在与否。换句话说,非零元素Aᵢⱼ 表示从节点i到节点j的连接,而零表示没有直接连接。
作者提供的图片
然而,邻接矩阵在稀疏矩阵或边较少的图中并不像 COO 格式那样节省空间。然而,为了清晰和易于解释,邻接矩阵仍然是表示图连通性的热门选择。
邻接矩阵可以通过edge_index
和一个工具函数to_dense_adj()
来推断。
from torch_geometric.utils import to_dense_adj
A = to_dense_adj(data.edge_index)[0].numpy().astype(int)
print(f'A = {A.shape}')
print(A)
A = (34, 34)
[[0 1 1 ... 1 0 0]
[1 0 1 ... 0 0 0]
[1 1 0 ... 0 1 0]
...
[1 0 0 ... 0 1 1]
[0 0 1 ... 1 0 1]
[0 0 0 ... 1 1 0]]
对于图数据,节点之间密集互连的情况相对较少。正如你所见,我们的邻接矩阵A是稀疏的(填充了零)。
在许多现实世界的图中,大多数节点只与少数其他节点连接,导致邻接矩阵中有大量零。存储这么多零是完全不高效的,这就是为什么 PyG 采用了 COO 格式。
相反,真实标签易于理解。
print(f'y = {data.y.shape}')
print(data.y)
y = torch.Size([34])
tensor([1, 1, 1, 1, 3, 3, 3, 1, 0, 1, 3, 1, 1, 1, 0, 0, 3, 1, 0, 1, 0, 1, 0, 0,
2, 2, 0, 0, 2, 0, 0, 2, 0, 0])
我们存储在 y
中的节点真实标签仅仅编码了每个节点的组号(0, 1, 2, 3),这就是为什么我们有 34 个值。
最后,让我们打印训练掩码。
print(f'train_mask = {data.train_mask.shape}')
print(data.train_mask)
train_mask = torch.Size([34])
tensor([ True, False, False, False, True, False, False, False, True, False,
False, False, False, False, False, False, False, False, False, False,
False, False, False, False, True, False, False, False, False, False,
False, False, False, False])
训练掩码显示了哪些节点应该用 True
语句进行训练。这些节点代表训练集,而其他节点可以视为测试集。这种划分有助于通过提供未见过的数据来进行模型评估。
但我们还没完成
对象提供了更多功能。它提供了各种实用函数,使得可以调查图的多个属性。例如:
-
is_directed()
告诉你图是否有向。有向图意味着邻接矩阵不是对称的,即边的方向在节点间的连接中是重要的。 -
isolated_nodes()
检查是否有一些节点没有连接到图的其余部分。这些节点可能在分类等任务中带来挑战,因为它们缺乏连接。 -
has_self_loops()
表示是否至少有一个节点自我连接。这与环的概念不同:环意味着一条路径开始和结束于同一个节点,在此过程中遍历其他节点。
在扎卡里武术俱乐部数据集中,所有这些属性返回 False
。这意味着图是无向的,没有孤立节点,并且没有节点与自身相连。
print(f'Edges are directed: {data.is_directed()}')
print(f'Graph has isolated nodes: {data.has_isolated_nodes()}')
print(f'Graph has loops: {data.has_self_loops()}')
Edges are directed: False
Graph has isolated nodes: False
Graph has loops: False
最后,我们可以使用 [to_networkx](https://pytorch-geometric.readthedocs.io/en/latest/modules/utils.html?highlight=to_networkx#torch_geometric.utils.to_networkx)
将 PyTorch Geometric 图转换为流行的图库 NetworkX。这对于使用 networkx
和 matplotlib
可视化小图特别有用。
让我们为每个组绘制不同颜色的数据集。
from torch_geometric.utils import to_networkx
G = to_networkx(data, to_undirected=True)
plt.figure(figsize=(12,12))
plt.axis('off')
nx.draw_networkx(G,
pos=nx.spring_layout(G, seed=0),
with_labels=True,
node_size=800,
node_color=data.y,
cmap="hsv",
vmin=-2,
vmax=3,
width=0.8,
edge_color="grey",
font_size=14
)
plt.show()
这个扎卡里武术俱乐部的图显示了我们的 34 个节点、78 条(双向)边和 4 个标签及 4 种不同颜色。现在我们已经了解了使用 PyTorch Geometric 加载和处理数据集的基本内容,我们可以介绍图卷积网络架构。
✉️ II. 图卷积网络
本节旨在从头开始介绍和构建图卷积层。
在传统的神经网络中,线性层对传入的数据应用线性变换。这种变换通过使用权重矩阵 𝐖 将输入特征 x 转换为隐藏向量 h。暂时忽略偏差,这可以表示为:
在图数据中,通过节点之间的连接增加了额外的复杂性。这些连接很重要,因为在网络中,通常假设相似的节点比不相似的节点更可能互相链接,这种现象被称为网络同质性。
我们可以通过将节点的特征与邻居的特征合并来丰富我们的节点表示。这个操作称为卷积或邻域聚合。让我们将节点 i 及其邻域表示为 Ñ。
与卷积神经网络(CNNs)中的滤波器不同,我们的权重矩阵 𝐖 是唯一的,并且在每个节点之间共享。但还有另一个问题:节点没有像像素那样的固定邻居数量。
我们如何处理一个节点只有一个邻居,而另一个节点有 500 个邻居的情况?如果我们简单地将特征向量相加,那么对于拥有 500 个邻居的节点,得到的嵌入 h 将会大得多。为了确保所有节点的值具有相似的范围并便于比较,我们可以根据节点的度来归一化结果,其中度是指一个节点的连接数量。
我们快到了!由 Kipf 等人(2016)介绍的图卷积层还有一个最终的改进。
作者观察到,具有大量邻居的节点的特征比那些较孤立节点的特征传播得更容易。为了抵消这种效应,他们建议为邻居较少的节点的特征分配更大的权重,从而平衡所有节点的影响。这个操作可以表示为:
注意,当 i 和 j 拥有相同数量的邻居时,这等同于我们自己定义的层。现在,让我们看看如何在 Python 中使用 PyTorch Geometric 实现它。
🧠 III. 实现一个 GCN
PyTorch Geometric 提供了GCNConv
函数,该函数直接实现了图卷积层。
在这个示例中,我们将创建一个基本的图卷积网络,包括一个 GCN 层、一个 ReLU 激活函数和一个线性输出层。这个输出层将产生四个值,对应我们的四个类别,最高值将决定每个节点的类别。
在以下代码块中,我们定义了一个具有 3 维隐藏层的 GCN 层。
from torch.nn import Linear
from torch_geometric.nn import GCNConv
class GCN(torch.nn.Module):
def __init__(self):
super().__init__()
self.gcn = GCNConv(dataset.num_features, 3)
self.out = Linear(3, dataset.num_classes) def forward(self, x, edge_index):
h = self.gcn(x, edge_index).relu()
z = self.out(h)
return h, zmodel = GCN()
print(model)
GCN(
(gcn): GCNConv(34, 3)
(out): Linear(in_features=3, out_features=4, bias=True)
)
如果我们添加了第二个 GCN 层,我们的模型将不仅仅从每个节点的邻居处聚合特征向量,还会从这些邻居的邻居处聚合特征向量。
我们可以堆叠多个图层以聚合更多的远离值,但有一个问题:如果我们添加太多图层,聚合变得如此强烈,以至于所有嵌入最终看起来都一样。这种现象被称为过度平滑,当图层过多时,可能会成为一个实际问题。
现在我们已经定义了 GNN,让我们用 PyTorch 编写一个简单的训练循环。我选择了常规的交叉熵损失,因为这是一个多类分类任务,优化器使用 Adam。在本文中,我们不会实现训练/测试拆分,以保持简单,专注于 GNN 如何学习。
训练循环是标准的:我们尝试预测正确的标签,并将 GCN 的结果与 data.y
中存储的值进行比较。通过交叉熵损失计算错误,并使用 Adam 进行反向传播,以微调 GNN 的权重和偏差。最后,我们每 10 个 epochs 打印一次指标。
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.02)
# Calculate accuracy
def accuracy(pred_y, y):
return (pred_y == y).sum() / len(y)# Data for animations
embeddings = []
losses = []
accuracies = []
outputs = []# Training loop
for epoch in range(201):
# Clear gradients
optimizer.zero_grad() # Forward pass
h, z = model(data.x, data.edge_index) # Calculate loss function
loss = criterion(z, data.y) # Calculate accuracy
acc = accuracy(z.argmax(dim=1), data.y) # Compute gradients
loss.backward() # Tune parameters
optimizer.step() # Store data for animations
embeddings.append(h)
losses.append(loss)
accuracies.append(acc)
outputs.append(z.argmax(dim=1)) # Print metrics every 10 epochs
if epoch % 10 == 0:
print(f'Epoch {epoch:>3} | Loss: {loss:.2f} | Acc: {acc*100:.2f}%')
Epoch 0 | Loss: 1.40 | Acc: 41.18%
Epoch 10 | Loss: 1.21 | Acc: 47.06%
Epoch 20 | Loss: 1.02 | Acc: 67.65%
Epoch 30 | Loss: 0.80 | Acc: 73.53%
Epoch 40 | Loss: 0.59 | Acc: 73.53%
Epoch 50 | Loss: 0.39 | Acc: 94.12%
Epoch 60 | Loss: 0.23 | Acc: 97.06%
Epoch 70 | Loss: 0.13 | Acc: 100.00%
Epoch 80 | Loss: 0.07 | Acc: 100.00%
Epoch 90 | Loss: 0.05 | Acc: 100.00%
Epoch 100 | Loss: 0.03 | Acc: 100.00%
Epoch 110 | Loss: 0.02 | Acc: 100.00%
Epoch 120 | Loss: 0.02 | Acc: 100.00%
Epoch 130 | Loss: 0.02 | Acc: 100.00%
Epoch 140 | Loss: 0.01 | Acc: 100.00%
Epoch 150 | Loss: 0.01 | Acc: 100.00%
Epoch 160 | Loss: 0.01 | Acc: 100.00%
Epoch 170 | Loss: 0.01 | Acc: 100.00%
Epoch 180 | Loss: 0.01 | Acc: 100.00%
Epoch 190 | Loss: 0.01 | Acc: 100.00%
Epoch 200 | Loss: 0.01 | Acc: 100.00%
太好了!毫不奇怪,我们在训练集(完整数据集)上达到了 100% 的准确率。这意味着我们的模型学会了正确地将每个空手道俱乐部的成员分配到正确的组。
我们可以通过动画化图形来生成一个整洁的可视化效果,并观察 GNN 在训练过程中预测的演变。
%%capture
from IPython.display import HTML
from matplotlib import animation
plt.rcParams["animation.bitrate"] = 3000
def animate(i):
G = to_networkx(data, to_undirected=True)
nx.draw_networkx(G,
pos=nx.spring_layout(G, seed=0),
with_labels=True,
node_size=800,
node_color=outputs[i],
cmap="hsv",
vmin=-2,
vmax=3,
width=0.8,
edge_color="grey",
font_size=14
)
plt.title(f'Epoch {i} | Loss: {losses[i]:.2f} | Acc: {accuracies[i]*100:.2f}%',
fontsize=18, pad=20)fig = plt.figure(figsize=(12, 12))
plt.axis('off')anim = animation.FuncAnimation(fig, animate, \
np.arange(0, 200, 10), interval=500, repeat=True)
html = HTML(anim.to_html5_video())
display(html)
最初的预测是随机的,但经过一段时间,GCN 能够完美地标记每个节点。实际上,最终的图形与我们在第一部分末尾绘制的图形相同。但 GCN 到底学到了什么?
通过聚合邻近节点的特征,GNN 学习了网络中每个节点的向量表示(或嵌入)。在我们的模型中,最终层仅学习如何使用这些表示来产生最佳分类。然而,嵌入才是真正的 GNN 产物。
让我们打印出模型学到的嵌入。
# Print embeddings
print(f'Final embeddings = {h.shape}')
print(h)
Final embeddings = torch.Size([34, 3])
tensor([[1.9099e+00, 2.3584e+00, 7.4027e-01],
[2.6203e+00, 2.7997e+00, 0.0000e+00],
[2.2567e+00, 2.2962e+00, 6.4663e-01],
[2.0802e+00, 2.8785e+00, 0.0000e+00],
[0.0000e+00, 0.0000e+00, 2.9694e+00],
[0.0000e+00, 0.0000e+00, 3.3817e+00],
[0.0000e+00, 1.5008e-04, 3.4246e+00],
[1.7593e+00, 2.4292e+00, 2.4551e-01],
[1.9757e+00, 6.1032e-01, 1.8986e+00],
[1.7770e+00, 1.9950e+00, 6.7018e-01],
[0.0000e+00, 1.1683e-04, 2.9738e+00],
[1.8988e+00, 2.0512e+00, 2.6225e-01],
[1.7081e+00, 2.3618e+00, 1.9609e-01],
[1.8303e+00, 2.1591e+00, 3.5906e-01],
[2.0755e+00, 2.7468e-01, 1.9804e+00],
[1.9676e+00, 3.7185e-01, 2.0011e+00],
[0.0000e+00, 0.0000e+00, 3.4787e+00],
[1.6945e+00, 2.0350e+00, 1.9789e-01],
[1.9808e+00, 3.2633e-01, 2.1349e+00],
[1.7846e+00, 1.9585e+00, 4.8021e-01],
[2.0420e+00, 2.7512e-01, 1.9810e+00],
[1.7665e+00, 2.1357e+00, 4.0325e-01],
[1.9870e+00, 3.3886e-01, 2.0421e+00],
[2.0614e+00, 5.1042e-01, 2.4872e+00],
...
[2.1778e+00, 4.4730e-01, 2.0077e+00],
[3.8906e-02, 2.3443e+00, 1.9195e+00],
[3.0748e+00, 0.0000e+00, 3.0789e+00],
[3.4316e+00, 1.9716e-01, 2.5231e+00]], grad_fn=<ReluBackward0>)
如你所见,嵌入不需要具有与特征向量相同的维度。在这里,我选择将维度从 34 (dataset.num_features
) 降到三维,以获得更好的 3D 可视化效果。
让我们在训练开始之前,即第 0 轮,绘制这些嵌入。
# Get first embedding at epoch = 0
embed = h.detach().cpu().numpy()
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(projection='3d')
ax.patch.set_alpha(0)
plt.tick_params(left=False,
bottom=False,
labelleft=False,
labelbottom=False)
ax.scatter(embed[:, 0], embed[:, 1], embed[:, 2],
s=200, c=data.y, cmap="hsv", vmin=-2, vmax=3)plt.show()
我们看到 Zachary 空手道俱乐部中的每个节点及其真实标签(而不是模型的预测)。目前,它们还很分散,因为 GNN 尚未训练完成。但如果我们在训练循环的每一步绘制这些嵌入,我们将能够可视化 GNN 实际上学到了什么。
让我们看看它们随着时间的推移如何演变,随着 GCN 在分类节点方面变得越来越好。
%%capture
def animate(i):
embed = embeddings[i].detach().cpu().numpy()
ax.clear()
ax.scatter(embed[:, 0], embed[:, 1], embed[:, 2],
s=200, c=data.y, cmap="hsv", vmin=-2, vmax=3)
plt.title(f'Epoch {i} | Loss: {losses[i]:.2f} | Acc: {accuracies[i]*100:.2f}%',
fontsize=18, pad=40)fig = plt.figure(figsize=(12, 12))
plt.axis('off')
ax = fig.add_subplot(projection='3d')
plt.tick_params(left=False,
bottom=False,
labelleft=False,
labelbottom=False)anim = animation.FuncAnimation(fig, animate, \
np.arange(0, 200, 10), interval=800, repeat=True)
html = HTML(anim.to_html5_video())
display(html)
我们的图卷积网络(GCN)有效地学习了将相似节点分组到不同的簇中的嵌入。这使得最终的线性层能够轻松地区分它们为不同的类别。
嵌入并非 GNN 特有:它们在深度学习中无处不在。它们也不一定是三维的:实际上,它们很少是三维的。例如,像BERT这样的语言模型生成的嵌入维度通常是 768 甚至 1024。
额外的维度存储了关于节点、文本、图像等更多的信息,但它们也会创建更大的模型,这些模型更难以训练。这就是为什么尽可能保持低维嵌入是有利的原因。
结论
图卷积网络是一种非常多功能的架构,可以应用于许多背景。在这篇文章中,我们熟悉了 PyTorch Geometric 库以及像Datasets
和Data
这样的对象。然后,我们成功地从头开始重建了一个图卷积层。接下来,我们通过实现一个 GCN 将理论付诸实践,这使我们理解了实际的方面以及各个组件如何相互作用。最后,我们可视化了训练过程,并清楚地了解了这种网络所涉及的内容。
Zachary 的空手道俱乐部是一个简单的数据集,但足够用来理解图数据和 GNN 中的最重要概念。尽管我们在这篇文章中仅讨论了节点分类,但 GNN 还可以完成其他任务:链接预测(例如,推荐朋友)、图分类(例如,标记分子)、图生成(例如,创建新分子)等。
除了 GCN 之外,研究人员还提出了许多 GNN 层和架构。在下一篇文章中,我们将介绍图注意力网络(GAT)架构,它通过注意机制动态计算 GCN 的归一化因子和每个连接的重要性。
如果你想了解更多关于图神经网络的信息,可以通过我的书籍《动手实践图神经网络》深入探索 GNN 的世界。
下一篇文章
使用 PyTorch Geometric 的自注意力 GNN 指南
[towardsdatascience.com
通过点击一下了解更多机器学习知识并支持我的工作 — 成为 Medium 会员,请点击这里:
[## 通过我的推荐链接加入 Medium — Maxime Labonne
作为 Medium 会员,你的会员费的一部分将用于支持你阅读的作者,你将获得对每个故事的完全访问权限……
如果你已经是会员,你可以 在 Medium 上关注我.
表格数据的图数据科学
图方法比你想象的要更通用
·
关注 发表在 Towards Data Science · 7 分钟阅读 · 2023 年 11 月 15 日
–
图片由 Alina Grubnyak 提供,Unsplash
图数据科学方法通常应用于具有某种固有图形特性的数据显示,例如分子结构数据、交通网络数据等。然而,图方法也可以对那些不显示明显图形结构的数据有用,比如用于机器学习任务的表格数据。在这篇文章中,我将简单直观地演示——不涉及任何数学或理论——通过将表格数据表示为图,我们可以开启对这些数据进行推理的新可能性。
为了保持简单,我将以下面的信用批准数据集作为示例。目标是根据其他属性的值预测批准的值。有许多分类算法可以用来做这件事,但让我们探讨一下如何使用图来处理这个问题。
作者创建的信用批准数据集
图形表示
首先要考虑的是如何将数据表示为图。我们希望捕捉这样一个直觉:两个实例之间共享的属性值越多,它们之间的相似度就越高。我们将使用一个节点来表示每个实例(我们称这些节点为实例节点),并为每个可能的属性值使用一个节点(这些是属性值节点)。实例节点和属性值节点之间的连接是双向的,并反映在表格中的信息。为了保持真的简单,我们将省略属性"Employment"和"History"。这是图形表现。
信用批准数据集的图表示。作者提供的图片。
消息传递
针对某个新实例的属性值,有几种使用图方法预测某个未知属性值的方式。我们将使用消息传递的概念。这是我们将使用的过程。
消息传递过程
在起始节点初始化值为 1 的消息,并让该节点将消息传递给其连接的每个节点。任何接收到消息的节点都会将消息(通过因子k膨胀,其中 0 <k<1)传递给其它连接的节点。继续消息传递,直到达到目标节点(即要预测其值的属性对应的节点),或者没有更多节点可传递消息为止。由于消息不能被传回到接收它的节点,该过程保证终止。
当消息传递完成时,图中的每个节点将收到零个或多个值不同的消息。对属于目标属性的每个节点的这些值进行求和,然后对这些(总和)值进行归一化,使它们本身的总和为 1。将归一化值解释为概率。然后可以使用这些概率来预测未知的属性值,或者从分布中抽取一个随机值来估算。在每次传递中膨胀消息值反映了长路径应该比短路径贡献更少于概率估计的直觉。
示例 1
假设我们希望在收入低的情况下预测批准的值。下面图中的箭头说明了消息传递过程的操作,每个箭头的粗细表示消息值(在每一跳中以因子k = 0.5 膨胀)。
估计在收入低的情况下批准的分布。图片由作者提供。
消息从节点收入:低(绿色)启动。该节点将值为 1 的消息传递给实例 1 和实例 2,然后每个实例将消息(扩展值为 0.5)传递给节点教育:大学和批准:否。请注意,由于教育:大学从实例 1 和实例 2 接收消息,它必须将每个这些消息传递给实例 3,扩展值为 0.25。目标变量每个节点的数字显示了接收到的消息值的总和(括号中为百分比的归一化值)。在收入低的条件下,我们得到批准的以下概率:
-
Prob (批准为‘是’ | 收入低) = 20%
-
Prob (批准为‘否’ | 收入低) = 80%
这些概率与从表中基于计数的预测结果不同。由于五个实例中有两个实例的收入低,并且这两个实例的批准为否,因此基于计数的预测将导致批准为否的概率为 100%。
消息传递程序已考虑到属性值教育大学,由实例 1 和 2 拥有的,同时也由实例 3 拥有,实例 3 的批准为是,从而贡献了节点批准:是的总消息值。如果我们在图中加入了额外的属性就业和历史,这可能会进一步增加连接起始节点和目标节点的路径数量,从而利用额外的上下文信息,并改善概率分布的估计。
示例 2
当对多个属性进行条件判断时,也可以使用消息传递程序。在这种情况下,我们只需在与我们条件的属性值对应的每个节点上启动消息,并从每个节点遵循相同的程序。下图显示了在收入低且教育水平为研究生的情况下,预测批准值的结果。来自每个起始节点的消息序列以不同的颜色显示。
估计在收入低且教育水平为研究生的情况下批准的分布。图片由作者提供。
实例 4 的教育值为研究生,因此对节点批准:是的消息值的总和做出贡献。实例 5 也对批准:是的做出进一步贡献,因为它与实例 4 共享高收入。
[注意:在这些示例中,我们将批准作为目标变量;然而,我们也可以用完全相同的方式估计收入或教育的概率分布]
这些示例表明,消息传递的简单概念(一个基本上是基于图的操作),结合适当的图表示,使我们能够进行一般且灵活的推理。具体来说,可以用来估计任何属性的概率分布,条件是一个或多个属性的值。
推理过程有些临时性*,* 设计成尽可能简单来支持我们的论点。有许多变体可以使用。关键点在于图方法使我们能够利用实例之间丰富的关系网络,这是用基于向量的方法难以捕捉的。当然,我们可以尝试用向量来表达消息传递过程(即,参考表而不是图),但这会很复杂和笨重。图方法的简洁和优雅来自于图表示和推理过程的自然配对。
我们可以从我们的例子中得出另一个有趣的观察。在上面的分析中,我们没有提到在实例节点处接收到的消息值之和(即,图中左侧节点)。让我们看看这些值可以显示给我们什么信息。在示例 1 中,在消息传递完成时,实例节点 1 到 5 的消息值之和分别为 1.0、1.0、0.5、0.0 和 0.0。将这些值归一化为总和为 1,结果分别为 40%、40%、20%、0% 和 0%。前两个实例具有批准号,它们归一化值的总和为 80%。最后三个实例具有批准是,它们归一化值的总和为 20%。但这些仅仅是我们在原始分析中得到的批准属性的概率。 (您可以验证 Example 2 中的相同情况)。这并非巧合。实例节点上的消息值之和可以解释为表示该实例与我们条件化的属性值的相似度。因此,推理过程可以被认为是加权最近邻的一种形式,其中相似性度量隐含在消息传递过程中。
UNCRi 框架
在 Skanalytix,我们开发了一个基于图的计算框架,名为统一数值/类别表示与推断(UNCRi)。 该框架结合了独特的图形数据表示和灵活的推断过程,可以用于估计和从任何类别或数值变量的条件分布中采样。它可以应用于分类和回归、缺失值填补、异常检测以及从完整联合分布或某些条件分布中生成合成数据等任务。该框架对数据的极端情况具有鲁棒性:类别变量可以从二元到高基数;数值变量可以是多峰的、高度偏斜的和任意规模的;缺失值比例可以很高。你可以在skanalytix.com
了解更多关于 UNCRi 的信息。(UNCRi 代码是闭源的)。
结论
从一开始,模式识别和机器学习领域就被操作向量的方法主导。向量的普遍存在使得很难想象其他方法。图方法提供了一个强大而灵活的替代方案。当应用于表格数据时,图方法不仅可以预测一个属性的值或用从其估计分布中抽取的随机值填补属性,还可以通过使用概率链式法则生成整个合成数据集,这些数据实例以与源数据相同的方式分布。所有这些都可以通过一个图和一个推断过程完成!虽然在本文中我们只考虑了类别变量,但这些思想也可以扩展到包含数值和类别属性混合的数据集。
图机器学习:概述
解密图神经网络——第一部分
入门的关键概念
·
关注 发布于 Towards Data Science ·9 分钟阅读·2023 年 4 月 4 日
–
作者图片
图神经网络(GNN)在数据科学和机器学习中受到关注,但在专家圈外仍然了解不多。要理解这一激动人心的方法,我们必须从更广泛的图机器学习(GML)领域入手。许多在线资源谈论 GNN 和 GML 时,好像它们是可以互换的概念,或者好像 GNN 是一种万灵药,使其他 GML 方法变得过时。事实并非如此。GML 的主要目的之一是压缩大型稀疏图数据结构,以便进行可行的预测和推断。GNN 是实现这一目标的一种方式,也许是最先进的方式,但不是唯一的方式。理解这一点将帮助为本系列的未来部分奠定更好的基础,我们将在其中更详细地讨论特定类型的 GNN 和相关的 GML 方法。
在这篇文章中,我们将:
-
回顾一下图数据结构的简要概述
-
介绍 GML 任务及其解决的问题类型
-
探讨压缩的概念及其在推动不同 GML 方法(包括 GNN)中的重要性
什么是图?
如果你正在阅读这篇文章,你可能已经对图数据结构有一定的了解。如果没有,我建议阅读这个关于属性图的资源或这个关于图数据库概念的资源。我将在这里做一个非常简要的回顾:
图由节点和通过关系连接的节点组成。有几种不同的方式来建模图数据。为了简化,我将使用属性图模型,该模型有三个主要组成部分:
-
节点,代表实体(有时称为顶点),
-
关系,代表节点之间的关联或互动(有时称为边或链接),以及
-
属性,代表节点或关系的特征。
作者提供的图片
什么是图机器学习(GML)?
从根本上说,图机器学习(GML)是将机器学习应用于图,专门用于预测和指导任务。GML 在供应链、欺诈检测、推荐、客户 360、药物发现等领域有各种应用。
理解 GML 的最佳方法之一是通过它可以完成的不同类型的机器学习任务。我将监督式和无监督式学习分开说明。
监督式 GML 任务
下图概述了监督学习中最常见的三种 GML 任务:
作者提供的图片
进一步扩展:
-
节点属性预测: 预测离散或连续的节点属性。可以将节点属性预测视为预测事物的形容词,例如,在金融服务平台上,某账户是否应被分类为欺诈,或者如何在在线零售店中对产品进行分类。
-
链接预测: 预测两个节点之间是否存在关系以及该关系的一些潜在属性。链接预测对实体解析等应用非常有帮助,我们希望预测两个节点是否反映了相同的基础实体;推荐系统中,我们希望预测用户接下来可能想购买或互动的内容;以及生物信息学中,用于预测蛋白质和药物的相互作用。在每种情况下,我们关注的是预测实体之间的关联、相似性或潜在的动作或互动。
-
图属性预测: 预测图或子图的离散或连续属性。在需要将每个实体建模为独立图进行预测的领域,图属性预测非常有用,而不是将实体建模为大型图中的节点,后者表示完整的数据集。用例包括材料科学、生物信息学和药物发现,其中单个图可以代表分子或蛋白质,我们希望对其进行预测。
无监督 GML 任务
以下是无监督学习中最常见的四种 GML 任务:
作者提供的图像
进一步阐述:
-
表示学习: 降维同时保持重要信号是 GML 应用中的核心主题。图表示学习通过从图结构生成低维特征来明确地做到这一点,通常用于后续的探索性数据分析(EDA)和机器学习。
-
社区检测(关系的聚类): 社区检测是一种用于识别图中密切互连节点组的聚类技术。社区检测在异常检测、欺诈和调查分析、社交网络分析以及生物学中具有各种实际应用。
-
相似性: 相似性在 GML 中指的是在图中找到并测量相似节点对。相似性适用于许多用例,包括推荐、实体解析以及异常和欺诈检测。常见的相似性技术包括 节点相似性算法、拓扑链接预测 和 K-最近邻 (KNN)。
-
中心性与路径寻找: 我将这两个概念归为一类,因为它们通常与机器学习任务关系较少,而更多涉及分析测量。然而,它们在技术上仍然适用,因此我会为了完整性而涵盖它们。中心性用于查找图中的重要或有影响力的节点。中心性在许多用例中普遍存在,包括欺诈和异常检测、推荐、供应链、物流和基础设施问题。路径寻找用于找到图中的最低成本路径或评估路径的质量和可用性。路径寻找可以使许多涉及物理系统的用例受益,例如物流、供应链、交通运输和基础设施。
压缩如何成为 GML 的关键
我遇到了这篇有趣的博客文章 by Matt Ranger,它美妙地解释了这一点:GML 的一个重要目标,以及在很大程度上自然语言处理的目标,是在保持重要信号用于预测和推断的同时,压缩大型稀疏数据结构。
考虑一个由邻接矩阵表示的正则图,这是一个方阵,每行和每列代表一个节点。如果从节点 A 到节点 B 的关系存在,则 A 行与 B 列交叉的单元格为 1;否则为 0。下面是一些小型正则图及其邻接矩阵的示例。
作者提供的图像
请注意,上述邻接矩阵中的许多单元格是 0。如果将其扩展到大型图形,特别是现实世界应用中发现的那些图形,零的比例会增加,邻接矩阵将变成大多数是零。
说明示例使用了来自大型图可视化工具和方法的 Last.fm 推荐图可视化以及来自 Beck, Fabian 等的矩阵图像,通过对比多个层级识别模块化模式。
这是因为随着这些图的增长,平均度中心性增长得要慢得多,甚至几乎没有增长。在社交网络中,这可以通过像邓巴数字这样的概念得到证实,它是一个人能够维持稳定社会关系的认知极限。你也可以对其他类型的图有直观认识,比如金融交易图或推荐系统的用户购买图。随着这些图的增长,一个人参与的潜在独特交易或购买的数量增长得要比他们的能力快得多。也就是说,如果网站上有六种产品,一个用户购买其中一半是可行的,但如果有数十万种产品,则不那么可行。因此,你最终会得到非常大且稀疏的数据结构。
如果你能直接将这些稀疏数据结构用于机器学习,你就不需要 GNNs 或任何 GML——你只需将它们作为特征插入到传统的 ML 模型中即可。然而,这并不可行。它不会扩展,而且即使超越这一点,它还会引发关于收敛和估计的数学问题,使 ML 模型不准确且不可行。因此,GML 的一个基本关键是压缩这些数据结构;可以说,这正是 GML 的全部意义所在。
如何实现压缩?——图机器学习方法
在最高层次上,存在三种 GML 方法来实现这种压缩。
作者提供的图片
经典图算法
经典图算法包括像PageRank、Louvain和Dijkstra 的最短路径。它们可以独立用于无监督社区检测、相似性、中心性或路径查找。经典算法的结果也可以作为传统下游模型的特征,如线性和逻辑回归、随机森林或神经网络,以执行 GML 任务。
经典图算法往往简单、易于入门,并且相对可解释和解释。然而,它们可能需要比其他 GML 方法更多的手动工作和主题专家(SME)。这使得经典图算法在实验和开发中成为良好的初步选择,有助于了解在你的图上什么效果最佳。它们在生产中也可以在简单问题上表现良好,但更复杂的用例可能需要升级到另一种 GML 方法。
非 GNN 图嵌入
图嵌入是一种表示学习形式。一些图嵌入技术利用 GNN 架构,而另一些则没有。后者,即非 GNN,是这种方法的重点。这些嵌入技术则依赖于矩阵分解/分解、随机投影、随机游走或哈希函数架构。一些示例包括 Node2vec(基于随机游走)、FastRP(随机投影和矩阵操作) 和 HashGNN(哈希函数架构)。
图嵌入涉及生成数值或二进制特征向量来表示节点、关系、路径或整个图。其中,节点嵌入是最基本且最常用的。基本思想是为每个节点生成一个向量,使得向量之间的相似性(例如点积)近似于图中节点之间的相似性。下面是一个小型 扎卡里空手道俱乐部网络 的示例。请注意,邻接矩阵是如何被压缩为每个节点的 2 维嵌入向量,以及这些向量如何聚集在一起以反映图的社区结构。大多数现实世界的嵌入将具有多于两个维度(128 到 256 或更高),以表示具有数百万或数十亿节点的大型现实世界图,但基本直觉是相同的。
作者提供的图像
上述相同的逻辑也适用于关系、路径和整个图嵌入:嵌入向量中的相似性应当近似于图结构中的相似性。这实现了压缩,同时保持了重要信号,使得嵌入在各种下游机器学习任务中具有用处。
与经典图算法相比,非 GNN 嵌入可以减少手动工作量和对 SME 的需求。尽管非 GNN 嵌入通常需要调整超参数才能得到最佳效果,但它们往往更容易自动化并在不同图上进行泛化。此外,一些非 GNN 嵌入如 FastRP 和 HashGNN 由于不需要模型训练,可以在普通硬件上极好地扩展到大图。这相比于基于 GNN 的方法可以带来巨大的好处。
然而,非 GNN 嵌入也有一些权衡。由于涉及的数学操作更为一般化,它们的可解释性和解释能力不如经典图算法。它们通常是转导式的,不过 Neo4j 图数据科学的近期改进使得其中一些在特定应用中可以有效地表现为归纳式。我们将在本系列后续内容中更深入地讨论转导式和归纳式设置;这与对新未见数据的预测能力有关,是 GML 的一个重要考虑点。
图神经网络(GNNs)
图片来源:作者
GNN 是一种神经网络模型,它以图数据作为输入,将其转换为中间嵌入,然后将这些嵌入传递到对齐预测任务的最终层。这个预测任务可以是监督性的(节点属性预测、链接预测、图属性预测)或无监督的(聚类、相似性,或仅仅是用于表示学习的最终输出嵌入)。因此,与经典算法和非 GNN 嵌入不同,后者将结果作为特征传递给下游机器学习模型,特别是在监督任务中,GNNs 是完全端到端的图原生解决方案。
GNNs 作为完整的端到端解决方案,具有多种好处。值得注意的是,在训练过程中学习到的中间嵌入理论上能够自动推断图中的最重要信息。最近的大多数 GNNs 也因拥有经过训练的模型而具备归纳能力。
GNNs(图神经网络)也存在一些弱点,包括高复杂性、扩展困难,以及低可解释性和解释能力。GNNs 由于过度平滑和其他数学原理,还可能在深度方面存在局限性。
我将在下一个博客中进一步讨论 GNNs,《GNNs:它们是什么以及为何重要》。与此同时,如果你想开始图机器学习,请查看 Neo4j Graph Data Science。数据科学家和工程师可以在这里找到入门的技术文档。
总结
本文的主要收获:
-
图机器学习(GML)是一个广泛的领域,涵盖了许多用例应用,包括多个不同的监督和无监督机器学习任务。
-
GML(图机器学习)的主要目的之一是压缩大型稀疏图结构,同时保持预测和推断所需的重要信号。
-
GNNs 是实现这种压缩的多种 GML 方法之一。
图形机器学习 @ ICML 2023
图形机器学习的新动态?
最近的进展和热门趋势,2023 年 8 月版
·
关注 发表在 Towards Data Science ·16 分钟阅读·2023 年 8 月 6 日
–
壮丽的海滩和热带夏威夷风光🌴并没有阻止勇敢的科学家们参加在檀香山举办的国际机器学习大会并展示他们的最新研究成果!让我们一起看看我们最喜欢的图形机器学习领域的新动态。
图片作者。
感谢 Santiago Miret 校对本文。
为了让帖子不那么枯燥,我在檀香山拍了一些照片📷
目录(可点击):
-
图形变换器:更稀疏、更快且有方向
-
理论:GNN 的 VC 维,深入探讨过度挤压
-
新的 GNN 架构:延迟和半跳
-
生成模型 — 分子稳定扩散,离散扩散
-
几何学习:几何 WL,克利福德代数
-
分子:2D-3D 预训练,MD 中的不确定性估计
-
材料与蛋白质:用于蛋白质的 CLIP,Ewald 消息传递,对称增强
-
酷应用:算法推理、归纳 KG 完成、用于质谱的 GNN
-
总结的 Meme 部分
图转换器:更稀疏、更快、且有方向
我们大约一年前 提出了 GraphGPS,很高兴看到许多 ICML 论文基于我们的框架并进一步扩展 GT 能力。
➡️ Exphormer 由 Shirzad, Velingker, Venkatachalam 等人 添加了图动机的稀疏注意力的缺失部分:与 BigBird 或 Performer(最初为序列设计)不同,Exphormer 的注意力基于 1-hop 边、虚拟节点(与图中的所有节点相连)以及一个精巧的 扩展边 想法。扩展图具有固定度,并被证明可以近似完全连接的图。所有组件结合起来,注意力成本为 O(V+E) 而不是 O(V²)。这使得 Exphormer 能够在几乎所有地方超越 GraphGPS,并扩展到最多 16 万个节点的非常大图。令人惊叹的工作,Exphormer 有很大机会成为 GT 中标准的稀疏注意力机制 👏。
➡️ 与图转换器并行,扩展图已经可以用来增强任何 MPNN 架构的性能,如 Deac, Lackenby, 和 Veličković 在 Expander Graph Propagation 中所示。
类似地,Cai 等人 证明了具有虚拟节点的 MPNN 可以近似线性 Performer-like 注意力,因此即使是经典的 GCN 和 GatedGCN 只要加入虚拟节点,也能在长范围图任务中表现出相当的 SOTA 性能(我们发布了 LGRB 基准测试来测量 GNN 和 GT 的长范围能力)。
来源:Shirzad, Velingker, Venkatachalam 等人
➡️ 一些受视觉模型启发的 GT 的 基于补丁 的子采样方法:He 等人 的 “ViT/MLP-Mixer 在图上的推广” 将输入分成多个补丁,使用 GNN 将每个补丁编码为一个令牌,并对这些令牌运行变换器。
来源:“ViT/MLP-Mixer 在图上的推广” 由 He 等人
在 GOAT 中,由 Kong 等人 提出,节点特征被投影到 K-Means 的 K 个簇的代码本中,并且每个节点的采样的三跳邻域都关注这个代码本。GOAT 是一个单层模型,并且可以扩展到数百万节点的图中。
➡️ 有向图 也受到了一些 Transformer 的喜爱 💗。“Transformers Meet Directed Graphs” 由 Geisler 等人 引入了磁拉普拉斯 —— 非对称邻接矩阵的拉普拉斯的泛化。磁拉普拉斯的特征向量与有向随机游走结合,成为 Transformer 的强大输入特征,在 OGB Code2 图属性预测数据集上设置了新的 SOTA,超过了现有方法很多!
🏅 最后但并非最不重要的是,我们在社区标准 ZINC 数据集上有了一个新的 SOTA GT — GRIT,由 Ma, Lin, 等人 提出,其全 d-维随机游走矩阵被称为相对随机游走概率(RRWP),作为边特征用于注意力计算(相比之下,流行的 RWSE 特征只是这个矩阵的对角元素)。RRWP 明显比最短路径距离特征更强大,在 ZINC 上取得了创纪录的低 0.059 MAE(比 GraphGPS 的 0.070 低)。GRIT 在其他基准测试中通常也优于 GPS 👏。同样地,Eliasof 等人 提出了一个巧妙的思路,将随机和谱特征结合为位置编码,在超越 RWSE 的同时并未尝试过与 GTs 结合。
图片由作者提供。
理论:GNNs 的 VC 维,深入探讨过度压缩
➡️ VC 维 衡量了模型的容量和表达能力。它已经广泛应用于经典机器学习算法的研究中,但令人惊讶的是,从未应用于研究 GNNs。在 “WL meet VC” 中,Morris 等人 最终揭示了 WL 测试和 VC 维之间的联系 — 原来 VC 维可以由 GNN 权重的比特长度界定,即 float32 权重意味着 VC 维为 32。此外,VC 维对给定任务中唯一 WL 颜色的数量以对数方式依赖,对深度和层数则多项式依赖。这是一个重要的理论结果,我鼓励你深入了解!
来源:“WL meet VC” by Morris 等人
🍊🖐️ 过度压缩效应——尝试将来自过多邻居节点的信息塞入会导致信息丢失——是 MPNN 的另一个常见问题,我们尚未完全理解如何妥善处理。今年,有 3 篇论文专门讨论了这个话题。也许最基础的是Di Giovanni 等的工作,解释了 MPNN 的宽度、深度和图拓扑如何影响过度压缩。
结果表明,宽度可能有帮助(但存在泛化问题),深度实际上没有什么帮助,而图拓扑(由节点间的通勤时间表征)起着最重要的作用。我们可以通过各种图重连策略(基于空间或谱特性添加和移除边)来减少通勤时间,这些策略有很多(你可能听说过基于 Ricci 流的重连,该研究在 ICLR 2022 上获得了杰出论文奖)。事实上,还有一项后续研究对此进行了更深入的探讨,推导了一些关于过度压缩和 MPNN 属性的不可能性声明——我强烈推荐阅读!
➡️ 有效电阻是空间重连策略的一个例子,Black 等对此进行了详细研究。基于 Ricci 流的重连方法与图的曲率相关,进一步研究见于Nguyen 等的工作中。
➡️ 子图 GNN 继续受到关注:两项工作(Zhang, Feng, Du 等 和 Zhou, Wang, Zhang)同时推导了最近提出的子图 GNN 的表现力等级及其与 1 阶及更高阶 WL 测试的关系。
图像作者提供。
新型 GNN 架构:延迟和半跳
如果你厌倦了 GCN 或 GAT 的各种变体,这里有一些新鲜的想法,可以与任何你选择的 GNN 搭配使用:
⏳ 正如我们在理论部分所知,重新连接有助于对抗过度挤压。Gutteridge 等人 介绍了*“DRew: 动态重连的延迟消息传递”,它在后期 GNN 层中逐渐稠密化图,使得长距离节点能够看到先前节点的原始状态(原始 DRew),或者这些跳跃连接是基于延迟*来添加的——取决于两个节点之间的距离(vDRew 版本)。例如( 🖼️👇),在 vDRew 延迟消息传递中,来自层 0 的起始节点将在层 1 上向 2-hop 邻居展示其状态,并将在层 2 上向 3-hop 邻居展示其状态。DRew 显著提高了普通 GNN 处理长距离任务的能力——实际上,启用 DRew 的 GCN 是来自 长距离图基准 的 Peptides-func 数据集上的当前 SOTA 👀
来源: Gutteridge 等人
🦘 另一个有趣的想法来自Azabou 等人,即通过在每条边上插入具有特殊连接模式的新慢节点来减慢消息传递——仅从起始节点来的一个输入连接和与目标节点的对称边。慢节点在异质性基准测试中大幅提升了普通 GNN 的性能,也可以通过创建具有不同慢节点位置的视图来实现自监督学习,针对相同的原始图。HalfHop 是一个无需深思熟虑的自监督学习组件,它提升了性能,并且应该成为许多 GNN 库的标准套件 👍。
来源: Azabou 等人
图片由作者提供。
生成模型 — 分子稳定扩散,离散扩散
➡️ 扩散模型可以在特征空间(例如,图像生成中的像素空间,如原始 DDPM)或潜在空间(如稳定扩散)中工作。在特征空间中,必须设计噪声过程以尊重特征空间的对称性和等变性。在潜在空间中,可以简单地向(预训练的)编码器生成的特征添加高斯噪声。大多数 3D 分子生成模型在特征空间中工作(如开创性的EDM),而由Xu 等人(著名的GeoDiff的作者)提出的新GeoLDM模型是首个为 3D 分子生成定义潜在扩散的模型。也就是说,在训练 EGNN 自编码器之后,GeoLDM 在去噪目标上进行训练,其中噪声从标准高斯分布中采样。GeoLDM 相比于 EDM 和其他非潜在扩散方法带来了显著的改进👏。
GeoLDM。来源:Xu 等人
➡️ 在非几何图的领域(仅具有邻接关系和可能的类别节点特征)中,由DiGress(ICLR’23)开创的离散图扩散似乎是最适用的选项。Chen 等人提出了EDGE,这是一种由节点度分布引导的离散扩散模型。与 DiGress 不同,EDGE 中的最终目标图是没有边的断开图,前向噪声模型通过伯努利分布移除边,反向过程将边添加到最近的活跃节点(活跃节点是指在前一步中度数发生变化的节点)。由于度引导引入的稀疏性,EDGE 可以生成高达 4k 节点和 40k 边的大型图!
图生成与 EDGE。来源:Chen 等人
➡️ 最后,“图形结构扩散模型”由Weilbach 等人提出,弥合了连续生成模型与在感兴趣问题中引入特定结构的概率图模型之间的差距——通常此类问题具有组合性质。核心思想是将问题的结构编码为尊重排列不变性的注意力掩码,并在 Transformer 编码器的注意力计算中使用该掩码(根据定义,除非使用位置嵌入,否则对输入标记排列是等变的)。GSDM可以处理二进制连续矩阵分解、布尔电路,生成数独,并执行排序。特别有趣的是论文中蕴含的一丝讽刺🙃。
GSDM 任务到注意力偏差。来源:“图形结构扩散模型” 由 Weilbach 等
作者提供的图片
几何学习:几何 WL,Clifford 代数
几何深度学习蓬勃发展!有很多有趣的论文展示,这将占据整个帖子,因此我只会重点介绍几个。
➡️ 几何 WL 终于在 Joshi, Bodnar 等 的工作中出现。几何 WL 扩展了 WL 测试的概念,加入了几何特征(例如坐标或速度),并推导出表达力层级,直到 k-order GWL。关键点:1️⃣ 等变 模型比 不变 模型更具表现力(注意在完全连接的图中差异消失),2️⃣ 张量阶 的特征提升了表现力,3️⃣ 体序 的特征提升了表现力(见下图 👇)。也就是说,球面 > 笛卡尔坐标 > 标量,以及 多体交互 > 仅距离。论文还展示了一个令人惊叹的学习资源 Geometric GNN Dojo,你可以从基本原理推导并实现大多数 SOTA 模型!
➡️ 超越向量到 Clifford 代数,Ruhe 等 推导了 几何 Clifford 代数网络(GCANs)。Clifford 代数通过双向量、三向量和(一般)多向量自然支持高阶交互。关键思想是 Cartan-Dieudonné 定理,即每个正交变换都可以分解为在超平面上的 反射,而几何代数将数据表示为 Pin(p,q,r) 群的元素。GCANs 引入了线性层、归一化、非线性等概念,以及它们如何用神经网络进行参数化。实验包括流体动力学建模和 Navier-Stokes 方程。
来源:Ruhe 等
实际上,已经有一篇后续工作介绍了等变 Clifford 神经网络——你可以了解更多关于 Clifford 代数基础以及微软研究院支持的最新论文 CliffordLayers。
💊 等变 GNN(EGNN)是几何深度学习中的阿司匹林,几乎适用于所有任务,并且已经看到相当多的改进。Eijkelboom 等 将 EGNN 与 单纯形网络 结合,这些网络在高阶结构(即单纯形复合体)上操作,形成 EMPSN。这是第一个结合几何和拓扑特征的例子之一,具有很大的改进潜力!最后,Passaro 和 Zitnick 推导出一种巧妙的技巧,将 SO(3) 卷积简化为 SO(2),将复杂度从 O(L⁶) 降到 O(L³),同时提供了数学等价性保证 👀。这一发现使得几何模型在像 OpenCatalyst 这样的大型数据集上得以扩展,并已被应用于 Equiformer V2 —— 很快将在许多其他几何模型库中出现 😉
图片来源:作者。
分子:2D-3D 预训练,MD 中的不确定性估计
➡️ Liu, Du 等 提出了 MoleculeSDE,这是一个新的框架,用于在分子数据上进行 2D-3D 联合预训练。除了标准的对比损失外,作者还添加了两个 生成 组件:通过基于分数的扩散生成重建 2D -> 3D 和 3D -> 2D 输入。使用标准的 GIN 和 SchNet 作为 2D 和 3D 模型,MoleculeSDE 在 PCQM4M v2 上进行了预训练,并在下游微调任务中表现良好。
➡️ Wollschläger 等 对 GNN 中的不确定性估计进行了一项全面研究,重点关注分子动力学和力场。识别关键的物理信息和应用导向原则,作者提出了一种 局部神经核,这是一种基于高斯过程的扩展,适用于任何几何 GNN,处理不变和等变量(已在 SchNet、DimeNet 和 NequIP 上进行尝试)。在许多情况下,LNK 从一个模型的估计与需要训练多个模型的昂贵集成效果相当或更好。
图片来源:作者。
材料与蛋白质:CLIP 用于蛋白质,Ewald 消息传递,等变增强
CLIP 及其后代已经成为文本到图像模型中的标准工具。我们能否对文本到蛋白质做同样的事情?可以!
➡️ Xu, Yuan 等 提出了 ProtST,一个用于学习文本蛋白质描述(通过 PubMedBERT)和蛋白质序列(通过 ESM)联合表示的框架。除了对比损失外,ProtST 还有一个多模态掩码预测目标,例如,掩盖文本和蛋白质序列中的 15% 令牌,并基于潜在表示联合预测这些令牌,以及基于序列或语言单独的掩码预测损失。此外,作者设计了一个新的 ProtDescribe 数据集,包含 550K 对齐的蛋白质序列-描述对。 ProtST 在 PEER 基准测试中在许多蛋白质建模任务上表现出色,包括蛋白质功能注释和定位,同时还允许从文本描述中进行零样本蛋白质检索(见下例)。看起来 ProtST 具有成为许多蛋白质生成模型背后核心的光明前景 😉
来源: Xu, Yuan 等
实际上,ICML 展示了几项蛋白质生成工作,如 Lin 和 AlQuraishi 的 GENIE 和 Yim, Trippe, De Bortoli, Mathieu 等 的 FrameDiff — 这些工作尚未依赖文本描述,因此将 ProtST 融入其中似乎是提升性能的明智选择 📈
Gif 来源: SE(3) Diffusion Github
⚛️ 分子上的 MPNNs 具有严格的局部性偏差,这会抑制对长程交互的建模。 Kosmala 等 推导出了 Ewald 消息传递,并应用了 Ewald 求和 的思想,该思想将相互作用势能分解为短程和长程项。短程交互由任何 GNN 建模,而长程交互则是新的,通过 3D 傅里叶变换 和傅里叶频率上的消息传递来建模。结果表明,这一长程项相当灵活,可以应用于任何建模周期性和非周期性系统(如晶体或分子)的网络,如 SchNet、DimeNet 或 GemNet。该模型在 OC20 和 OE62 数据集上进行了评估。如果你对更多细节感兴趣,可以查看 Arthur Kosmala 的 1 小时讲座!
来源: Kosmala 等
在PotNet中,林等人使用了与 Ewald 求和类似的思想来处理 3D 晶体,其中长程连接使用不完全贝塞尔函数建模。PotNet 在 Materials Project 数据集和 JARVIS 上进行了评估,因此阅读这两篇论文可以很好地理解 Ewald 求和为许多与晶体相关的任务带来的好处 😉
来源:林等人
➡️ 另一种方法是通过杜瓦尔、施密特等人在FAENet中赋予任何 GNNs 晶体和分子等效性的看法。一种标准的方法是将某些对称性和等效性直接嵌入 GNN 架构中(例如在 EGNN、GemNet 和 Ewald Message Passing 中)— 这是一种安全但计算昂贵的方式(特别是涉及球谐函数和张量积时)。另一种选项通常用于视觉 — 展示相同输入的许多增强,模型最终应该学习到增强中的相同不变性。作者选择第二条路径,并设计了一种严格的方法来采样 2D / 3D 数据的不变或等变增强(例如用于能量或力的增强),所有这些增强都有花哨的证明 ✍️。为此,数据增强管道包括将 2D / 3D 输入投影到基于距离协方差矩阵的 PCA 的规范表示中,从中我们可以均匀采样旋转。
提出的 FAENet 是一个简单的模型,只使用距离,但在使用随机帧平均数据增强时表现非常好,同时速度快 6 到 20 倍。同样适用于晶体结构!
增强和随机帧平均。来源:杜瓦尔、施密特等
图片由作者提供。
酷炫应用:算法推理,归纳 KG 完成,质谱 GNN
本节中的几篇论文不属于上述任何一篇,但仍值得关注。
➡️ “神经算法推理与因果正则化” Bevilacqua 等人 解决了图学习中的一个常见问题——在测试时对更大输入的 OOD 泛化。研究算法推理问题中的 OOD 泛化时,作者观察到在某一步骤中存在许多不同的输入产生相同的计算。与此同时,这也意味着某些输入子集不会(或不应该)影响预测结果。这个假设使得可以设计一个自监督目标(称为Hint-ReLIC),该目标更倾向于一个“有意义”的步骤而不是一堆不影响预测结果的步骤。这个新目标显著提高了许多 CLRS-30 任务的表现,达到 90%以上的 micro-F1。是否可以在一般消息传递中利用相同的原则来改进其他图学习任务中的 OOD 转移是一个有趣的问题 🤔
来源:“神经算法推理与因果正则化” Bevilacqua 等人。
如果你对神经算法推理更感兴趣,可以查看知识与逻辑推理研讨会的会议记录,其中包含更多相关工作。
➡️ “InGram: 通过关系图的归纳知识图嵌入” Lee 等人 似乎是 ICML’23 上为数不多的知识图谱论文之一(根据我的搜索)。InGram 是首批能够在测试时对未见实体和未见关系进行归纳泛化的方法之一。之前的归纳 KG 模型需要以某种形式学习关系嵌入以对新节点进行泛化,而在这种范式下,新的未见关系很难建模。InGram 在原始的多关系图上构建了一个关系图,即关系类型的图,并通过运行 GAT 基于这个图学习关系的表示。实体表示是从随机初始化和 GNN 编码器中获得的。拥有实体和关系表示后,应用 DistMult 解码器作为评分函数。InGram 在未见关系方面有很大机会与GraIL (ICML 2020)对未见实体的影响相当 😉。
来源:“InGram: 通过关系图的归纳知识图嵌入” Lee 等人。
🌈 “利用图神经网络高效预测高分辨率质谱”由Murphy 等人提出,是一个将 GNNs 应用于预测质谱这一实际物理问题的酷应用。主要发现是,大部分质谱信号可以通过少数几个成分(产物离子和中性丧失公式)来解释。并且有可能从训练数据中挖掘出这些公式的词汇。因此,这个问题可以被框架为图分类(或图属性预测),在给定分子图的情况下,我们预测与某些质谱值对应的词汇项。这种方法,GRAFF-MS,通过 GIN 构建带有边特征的分子图表示,通过 SignNet 获得拉普拉斯特征,并与协变量特征进行汇总。与基线 CFM-ID 相比,GRAFF-MS 的推断时间为约 19 分钟,而 CFM-ID 则为 126 小时,性能显著提升👀。
来源: “利用图神经网络高效预测高分辨率质谱”由Murphy 等人提出
结论性表情包部分
同一张照片上的四位 Michaels(背景中还有一个ε)!
2022 年的表情包终于汇聚到了Michael Bronstein!
图形机器学习在 2023 年的现状
最前沿动态
热点趋势和重大进展
·
关注 发布在 数据科学前沿 · 26 分钟阅读 · 2023 年 1 月 1 日
–
2022 年已经结束,是时候坐下来回顾一下在图形机器学习(Graph ML)方面取得的成就,并对 2023 年的可能突破进行假设了。敬请关注 🎄☕
背景图像由 DALL-E 2 生成,文本由作者添加。
这篇文章由 Hongyu Ren (斯坦福大学)、 Zhaocheng Zhu (Mila 和蒙特利尔大学)共同撰写。我们感谢 Christopher Morris 和 Johannes Brandstetter 在理论和偏微分方程部分的反馈和帮助。请关注 Michael、 Hongyu、 Zhaocheng、* Christopher和 Johannes 在 Medium 和 Twitter 上,以获取更多与图机器学习相关的讨论。
目录:
-
生成模型:分子和蛋白质的去噪扩散模型
-
DFTs、机器学习力场、材料和天气模拟
-
几何学与拓扑学与偏微分方程
-
图变换器
-
大型图
-
GNN 理论:Weisfeiler 和 Leman 的前景,子图 GNN
-
知识图谱:归纳推理接管
-
算法推理和对齐
-
酷炫的 GNN 应用
-
硬件:IPU 和 Graphcore 赢得 OGB LSC 2022
-
新的会议:LoG 和分子机器学习
-
课程和教育材料
-
新的数据集、基准和挑战
-
软件库和开源
-
加入社区
-
2022 年的网络迷因
生成模型:分子和蛋白质的去噪扩散模型
生成扩散模型在视觉语言领域是 2022 年深度学习世界的头条话题。尽管生成图像和视频无疑是尝试不同模型和采样技术的酷炫领域,我们认为
在 2022 年,扩散模型最有用的应用实际上是在几何深度学习领域中创建的,重点关注分子和蛋白质
在我们最近的文章中,我们在思考是否 “去噪扩散模型就是你所需的一切?”。
去噪扩散模型就是你所需的一切吗?
towardsdatascience.com
在那里,我们回顾了最新的生成模型用于图生成(DiGress)、分子构象生成(EDM、GeoDiff、Torsional Diffusion)、分子对接(DiffDock)、分子连接(DiffLinker)和配体生成(DiffSBDD)。一旦帖子公开,几种令人惊叹的蛋白质生成模型也随之发布:
Chroma来自 Generate Biomedicines,允许施加功能性和几何约束,甚至可以使用自然语言查询,比如“生成一个具有 CHAD 结构域的蛋白质”,这要归功于一个小型的 GPT-Neo,经过蛋白质标注的训练;
Chroma 蛋白质生成。来源: Generate Biomedicines
RoseTTaFold Diffusion(RF Diffusion)来自 Baker Lab 和 MIT,具有类似功能,还支持文本提示,如“生成一个能够结合 X 的蛋白质”,并且能够进行功能性基序支架、酶活性位点支架和de novo蛋白质设计。强项:用 RF Diffusion 生成的 1000 种设计在实验室中被合成和测试!
RF Diffusion。来源: Watson 等 BakerLab
Meta AI FAIR 团队在蛋白质设计领域通过语言模型取得了惊人的进展:2022 年中,ESM-2发布了,这是一种仅在蛋白质序列上训练的蛋白质语言模型,远超 ESM-1 及其他基准模型。而且,后来显示编码的语言模型表示是获得蛋白质实际几何结构的非常好的起点,而无需多重序列比对(MSAs)——这可以通过ESMFold实现。特别感谢 Meta AI 和 FAIR 发布了该模型及其权重:它在官方 GitHub 仓库和HuggingFace上也可以找到!
扩展 ESM-2 可以获得更好的折叠预测。来源:Lin, Akin, Rao, Hie 等
🍭 随后,来自 ESM 团队的更多好消息传来:Verkuil 等发现 ESM-2 可以生成de novo蛋白质序列,这些序列实际上可以在实验室中合成,并且更重要的是,它们在已知的自然蛋白质中没有任何匹配。Hie 等提出了一种全新的蛋白质设计编程语言(可以把它看作是 ESMFold 的查询语言)——生产规则以约束函数的语法树形式组织。然后,每个程序被“编译”为一个控制生成过程的能量函数。Meta AI 还发布了最大的Metagenomic Atlas,但更多内容请参见本文的数据集部分。
在抗体设计领域,IgLM 采用了类似的基于 LM 的方法,如 Shuai、Ruffolo 和 Gray 所述。IGLM 生成基于链和物种 ID 标签的抗体序列。
最后,我们要特别提到 Jian Tang 实验室在 Mila 的一些工作。由 Liu 等人 提出的 MoleculeSTM 是一个类似 CLIP 的文本到分子模型(以及一个新的大型预训练数据集)。MoleculeSTM 能做到两件令人印象深刻的事情:(1)通过文本描述如“噻唑衍生物”检索分子,并从给定的 SMILES 分子中检索文本描述;(2)根据文本提示进行分子编辑,如“使分子在水中溶解且渗透性低”——模型根据描述编辑分子图谱,令人瞠目结舌 🤯
然后,Shi 等人 提出的 ProtSEED 是一个同时生成蛋白质序列 和 结构的模型(例如,大多数现有的蛋白质扩散模型一次只能处理其中之一)。ProtSEED 可以基于残基特征或残基对进行条件设置。从模型的角度看,它是一个具有改进的三角注意力的对称迭代模型。ProtSEED 在抗体 CDR 共同设计、蛋白质序列-结构共同设计和固定骨架序列设计中进行了评估。
从文本输入中进行分子编辑。来源:Liu 等人
除了生成蛋白质结构外,还有一些工作致力于从结构生成蛋白质序列,这被称为逆折叠。不要忘记查看 Meta 的 ESM-IF1 和 Baker 实验室的 ProteinMPNN。
2023 年的预期:(1)扩散模型的性能改进,例如更快的采样和更高效的求解器;(2)更强大的条件蛋白质生成模型;(3)对 生成流网络(GFlowNets,查看 教程)在分子和蛋白质中的更成功应用。
DFTs、ML 力场、材料和天气模拟
AI4Science 成为对称 GNN 研究及其应用的前沿。通过将 GNN 与 PDEs 配对,我们现在可以处理更复杂的预测任务。
2022 年,这一前沿领域扩展到了用于 分子动力学 和 材料发现 的基于 ML 的 密度泛函理论(DFT)和 力场 近似。另一个不断增长的领域是 天气模拟。
我们推荐 Max Welling 的 讲座,以获得关于 AI4Science 的更广泛概述,以及深度学习在科学中的应用现状。
从模型开始,2022 年见证了等变 GNN 在分子动力学和模拟中的激增,例如,基于NequIP、由Musaelian、Batzner 等人提出的Allegro或由Batatia et al.提出的MACE。这些模型的设计空间非常大,因此可以参考Batatia、Batzner 等人的最新综述以获得概述。对于大多数模型来说,一个关键组件是e3nn库(Geiger 和 Smidt的论文)和张量积的概念。我们强烈推荐 Erik Bekkers 提供的一个出色的新课程,以理解数学基础并跟上最新论文。
⚛️ 密度泛函理论(DFT)计算是分子动力学的主要工具之一(并且在大型集群中占据了大量计算时间)。然而,DFT 的时间复杂度是 O(n³),那么机器学习能否有所帮助呢?在学习到的力场已准备好用于基态催化剂发现中,Schaarschmidt et al.展示了学习势能模型的实验研究——结果表明 GNNs 在 O(n)线性时间内可以表现得非常好!Easy Potentials方法(基于 Open Catalyst 数据训练)证明是一个非常好的预测器,特别是与后处理步骤配合时。模型方面,它是一个带有Noisy Nodes自监督目标的 MPNN。
在**《力量不足》**中,Fu et al.提出了一个新的分子动力学基准——除了 MD17,作者们还添加了液体(水)、肽(丙氨酸二肽)和固态材料(LiPS)的数据集。更重要的是,作者们考虑了广泛的物理属性,如模拟的稳定性、扩散性和径向分布函数。包括 SchNet、ForceNet、DimeNet、GemNet(-T 和-dT)以及 NequIP 在内的大多数 SOTA 分子动力学模型都被探讨了。
来源: Fu et al.
在晶体结构建模中,我们要特别提到由Kaba 和 Ravanbakhsh提出的等变晶体网络——一种用来构建具有晶体对称性的周期性结构表示的巧妙方法。晶体可以用晶格和单位胞来描述,基向量可以进行群变换。概念上,ECN 创建了与对称群对应的边索引掩码,对这些掩码索引进行消息传递,并聚合多个对称群的结果。
关于材料发现的更多消息可以在最近的 AI4Mat NeurIPS workshop 会议记录中找到!
☂️ 基于机器学习的天气预报也取得了巨大的进展。特别是,DeepMind 的 GraphCast 和华为的 Pangu-Weather 展示了出色的结果,大大超越了传统模型。虽然 Pangu-Weather 利用 3D/视觉输入和视觉变换器,GraphCast 则采用了网格 MPNN,其中地球被分割为多个层级的网格。最深层有大约 40K 节点,具有 474 个输入特征,模型输出 227 个预测变量。MPNN 遵循“编码器-处理器-解码器”结构,并具有 16 层。GraphCast 是一个自回归模型,相对于下一个时间步预测,即它利用前两个状态预测下一个状态。GraphCast 可以在单个 TPUv4 上在 <60 秒内建立 10 天的预测,并且比非机器学习预测模型准确得多。👏
GraphCast 中的编码器-处理器-解码器网格 MPNN。来源:Lam, Sanchez-Gonzalez, Willson, Wirnsberger, Fortunato, Pritzel 等
2023 年的期待:我们期望看到更多关注 GNN 的计算效率和可扩展性。目前基于 GNN 的力场取得了显著的准确性,但仍比经典力场慢 2-3 个数量级,并且通常只部署在几百个原子上。为了使 GNN 在材料科学和药物发现中真正发挥变革性影响,我们将看到许多人致力于解决这个问题,无论是通过架构进步还是更智能的采样方法。
几何学 & 拓扑学 & PDEs
在 2022 年,1️⃣ 我们对 GNN 中的过度平滑和过度压缩现象及其与代数拓扑的关系有了更好的理解;2️⃣ 使用 GNN 进行 PDE 建模现在已经成为主流。
1️⃣ Michael Bronstein 的实验室对这个问题做出了巨大贡献 —— 查看那些关于神经切片扩散和将 GNN 视为梯度流的优秀帖子。
细胞切片理论,作为代数拓扑的一个分支,为图神经网络的工作原理提供了新的见解…
[towardsdatascience.com
以及关于 GNN 作为梯度流的内容:
GNN 作为梯度流的衍生物,通过最小化描述吸引力和排斥力的可学习能量来优化…
[towardsdatascience.com
2️⃣ 使用 GNNs 进行 PDE 建模已成为主流话题。一些论文需要 🤯 数学警报 🤯 提示,但如果你对 ODEs 和 PDEs 的基础知识很熟悉,这应该会更容易。
消息传递神经 PDE 求解器 由 Brandstetter, Worrall, 和 Welling 描述了消息传递如何帮助解决 PDE,具有更好的泛化能力,并摆脱手动启发式。此外,MP-PDEs 在表示上包含经典求解器,如有限差分。
来源: Brandstetter, Worrall, 和 Welling
该主题通过许多近期工作得到了进一步发展,包括使用隐式神经表示进行连续预测 (Yin et al.)、支持混合边界条件 (Horie and Mitsume),或 PDE 的潜在演变 (Wu et al.)
2023 年的期待:神经 PDE 及其应用有可能扩展到更多与物理相关的 AI4Science 子领域,特别是计算流体动力学(CFD)在未来几个月可能会受到基于 GNN 的替代品的影响。经典的 CFD 被广泛应用于多个领域的研究和工程问题,包括空气动力学、高超声速和环境工程、流体流动、视频游戏中的视觉效果,或上述天气模拟。基于 GNN 的替代品可能会增强/替代传统的经过验证的技术,如有限元方法 (Lienen et al.)、重网格算法 (Song et al.)、边值问题 (Loetsch et al.),或与三角化边界几何的交互 (Mayr et al.)。
神经 PDE 社区正在开始建立强大且常用的基准和框架,这将反过来帮助加速进展,例如 PDEBench (Takamoto et al.) 或 PDEArena (Gupta et al.)
图神经网络变换器
绝对是 2022 年的主要社区推动力之一,图神经网络变换器(GTs)在有效性和可扩展性方面有了很大进展。2022 年发布了几个杰出的模型:
👑 GraphGPS 由 Rampášek et al. 提出的,因其结合了局部消息传递、全局注意力(可选地,线性以提高效率)和位置编码,最终在 ZINC 和许多其他基准上设立了新的 SOTA 标杆,被誉为 “2022 年的 GT”。查看有关 GraphGPS 的专门文章
最佳图形变换器的烹饪秘诀
towardsdatascience.com
GraphGPS 作为 GPS++ 的核心,获胜 OGB 大规模挑战赛 2022 模型在 PCQM4M v2(图回归)上表现突出。GPS++,由 Graphcore、Valence Discovery 和 Mila 创建,整合了更多特性,包括 3D 坐标,并利用了稀疏优化的 IPU 硬件(更多信息见下一节)。GPS++ 权重已在 GitHub 上可用!
GraphGPS 直观理解。来源:Rampášek et al
Transformer-M 由 Luo et al. 提出的方法也启发了许多顶级 OGB LSC 模型。Transformer-M 将 3D 坐标添加到整洁的 2D-3D 预训练混合中。在推理时,当 3D 信息未知时,该模型将推断出一部分 3D 知识,从而显著提高 PCQM4Mv2 的性能。代码可用。
Transformer-M 2D-3D 预训练方案。来源: Luo et al.
TokenGT 由 Kim et al 提出的方法更加明确,并将输入图的所有边(除了所有节点)添加到喂给 Transformer 的序列中。使用这些输入,编码器需要额外的标记类型来区分节点和边。作者证明了几个很好的理论性质(尽管代价是较高的计算复杂度 O((V+E)²),在完全连接图的最坏情况下可能达到四次方)。代码可用。
TokenGT 将节点和边都添加到输入序列中。来源:Kim et al
2023 年的预期:在来年,我们预计 1️⃣ GTs 在数据和模型参数两个维度上扩展,从小于 50 节点的分子到数百万节点的图,以见证如文本和视觉基础模型中的突现行为 2️⃣ 类似于 BLOOM 由 BigScience Initiative 提供的用于分子数据的大型开源预训练等变 GT,也许在 Open Drug Discovery 项目中。
大图
🔥 我们在 2022 年最喜欢的一篇是Chamberlain, Shirobokov 等的 “基于子图草图的链接预测图神经网络”——这是算法与 ML 技术的巧妙结合。众所周知,SEAL 类的标记技巧相比于标准 GNN 编码器可以显著提升链接预测性能,但却面临巨大的计算/内存开销。在这项工作中,作者发现利用哈希 (MinHashing) 和基数估计 (HyperLogLog) 算法,可以高效地获取查询边两个节点之间的距离。本质上,消息传递是在 minhashing 和 hyperloglog 单节点的初步草图(min 聚合用于 minhash,max 用于 hyperloglog 草图)上进行的——这就是ELPH 链接预测模型的核心(带有简单的 MLP 解码器)。然后,作者设计了一个更具可扩展性的 BUDDY 模型,其中 k-hop 哈希传播可以在训练前预计算。实验表明,ELPH 和 BUDDY 可以扩展到以前过于庞大或资源消耗过大的图中。出色的工作,绝对是未来所有链接预测模型的坚实基线!👏
计算子图哈希以估计邻域和交集基数的动机。来源:Chamberlain, Shirobokov 等
在图采样和迷你批处理方面,Gasteiger, Qian, 和 Günnemann 设计了基于影响力的迷你批处理 (IBMB),这是个很好的例子,说明个性化 PageRank (PPR) 如何解决图批处理问题!IBMB 旨在创建对节点分类任务影响最大的最小迷你批次。实际上,影响力分数等同于 PPR。实际上,给定一组目标节点,IBMB (1) 将图划分为永久集群,(2) 在每个批次内运行 PPR,选择 top-PPR 节点以形成最终的子图迷你批次。生成的迷你批次可以发送到任何 GNN 编码器。IBMB 对图的大小几乎是常数 O(1),因为分区和 PPR 可以在预处理阶段预计算。
尽管生成的批次是固定的,并且在训练过程中不会改变(不够随机),但作者设计了类似动量的优化项来缓解这种非随机性。IBMB 可以在训练和推理中使用,速度提升可达 17 倍和 130 倍 🚀
基于影响力的迷你批处理。来源:Gasteiger, Qian, 和 Günnemann
本小节的副标题可以是“由谷歌提供”,因为大多数论文的作者都来自谷歌 😉
Carey 等 创建了Stars,一种在数十万亿边的规模下构建稀疏相似性图的方法🤯。成对的 N²比较显然不可行——Stars 使用了两个跳数的spanner 图(这些图中相似的点通过最多两个跳数连接)和SortingLSH,两者结合使得接近线性的时间复杂度和高稀疏性成为可能。
Dhulipala 等 创建了ParHAC,一种用于非常大图的近似(1+𝝐)并行层次聚类(HAC)算法及其广泛的理论基础。ParHAC 具有 O(V+E)复杂度和多对数深度,在具有数百亿边的图上运行速度比基线快高达 60 倍(这里是具有 1.7B 节点和 125B 边的超链接图)。
Devvrit 等 创建了S³GC,一种可扩展的自监督图聚类算法,使用单层 GNN 和对比训练目标。S³GC 使用图结构和节点特征,能够扩展到高达 1.6B 边的图。
最后,Epasto 等 创建了 PageRank 的差分隐私修改版本!
LoG 2022 包含了两个关于大规模 GNN 的教程:生产中 GNN 的扩展由 Da Zheng、Vassilis N. Ioannidis 和 Soji Adeshina 主讲,以及并行和分布式 GNN由 Torsten Hoefler 和 Maciej Besta 主讲。
2023 年值得期待:进一步降低计算成本和推理时间,以应对非常大的图。也许 OGB LSC 图的模型可以在普通机器上运行,而不是在大型集群上?
GNN 理论:Weisfeiler 和 Leman 的足迹,子图 GNN
年度游客!原始肖像来源:几何深度学习 IV:GNN 的化学前体 由 Michael Bronstein 主讲
🏖 🌄 Weisfeiler 和 Leman,图 ML 和 GNN 理论的奠基人,度过了非常多产的一年!继之前访问过Neural、Sparse、Topological和Cellular场所后,2022 年我们在几个新地方见到了他们:
-
WL Go 机器学习 — Morris 等 对 WL 测试的基础知识、术语及各种应用的综合调查;
-
WL Go 关系 —— Barcelo et al 首次尝试研究在多关系图和知识图中使用的关系 GNNs 的表现力。结果表明,R-GCN 和 CompGCN 的表现力相同,且受限于关系 1-WL 测试,最具表现力的消息函数(聚合实体-关系表示)是 Hadamard 乘积;
-
WL Go Walking by Niels M. Kriege 研究了随机游走核的表现力,发现 RW 核(经过小的修改)与 WL 子树核一样具表现力。
-
WL Go 几何:Joshi, Bodnar et al 提出了几何 WL 测试(GWL)来研究等变和不变 GNNs(对于某些对称性:平移、旋转、反射、排列)的表现力。结果表明,等变 GNNs(例如 E-GNN、NequIP 或 MACE)在理论上比不变 GNNs(例如 SchNet 或 DimeNet)更强大。
-
WL Go 时间:Souza et al 提出了时间 WL 测试来研究时间 GNNs 的表现力。作者随后提出了一种新型的单射聚合函数(以及 PINT 模型),这应该是最具表现力的;
-
WL Go 渐进:Bause 和 Kriege 提议用非单射函数修改原始 WL 颜色细化,其中不同的多重集合可能被分配相同的颜色(在某些条件下)。因此,它使得颜色细化过程更加渐进,并且收敛到稳定着色的速度更慢,最终保留了 1-WL 的表现力,但在过程中获得了一些区分特性。
-
WL Go 无限:Feldman et al 提议用从拉普拉斯的热核衍生的谱特征或拉普拉斯的 k 最小特征向量(对于大图)来改变初始节点着色,这与拉普拉斯位置编码(LPEs)非常接近。
-
WL Go 双曲:Nikolentzos et al 指出 WL 测试的颜色细化过程会产生颜色的树状层次结构。为了保持这些颜色所编码的节点相对距离,作者建议将每层/迭代的输出状态映射到双曲空间,并在每次更新后调整。最终的嵌入应该保留节点距离的概念。
📈 在比 1-WL 更具表达力的架构领域中,子图 GNNs 是最大的趋势。其中有三种方法脱颖而出:1️⃣ 子图联合网络(SUN),由Frasca, Bevilacqua 等提出,提供了子图 GNNs 设计空间和表达力的全面分析,显示它们受限于 3-WL;2️⃣ 有序子图聚合网络(OSAN),由Qian, Rattan 等提出,设计了一种子图增强 GNNs(k-OSAN)的层次结构,并发现 k-OSAN 与 k-WL 不可比,但严格受限于(k+1)-WL。OSAN 的一个特别酷的部分是使用隐式 MLE(NeurIPS’21),这是一种可微分的离散采样技术,用于采样有序子图。️3️⃣ SpeqNets 由Morris 等提出,设计了一种图网络的置换等变层次结构,平衡了可扩展性和表达力。4️⃣ GraphSNN 由Wijesinghe 和 Wang提出,基于子图同构和子树同构的重叠推导出表达性模型。
🤔 一些研究重新审视 WL 框架作为 GNN 表达力的一种通用手段。Geerts 和 Reutter定义了k 阶 MPNNs,可以通过张量语言(WL 与张量语言之间的映射)进行表征。一个新的匿名 ICLR’23 提交提出利用图的双连通性并定义了广义距离 WL算法。
如果你想更深入地研究这个主题,查看 Fabrizio Frasca、Beatrice Bevilacqua 和 Haggai Maron 的精彩LOG 2022 教程及其实际例子吧!
2023 年的期待:1️⃣ 更多致力于创建时间和内存高效的子图 GNNs。2️⃣ 更好地理解 GNNs 的泛化能力。3️⃣ Weisfeiler 和 Leman 访问 10 个新地方!
知识图谱:归纳推理占据主导地位
去年,我们观察到了 KG 表示学习的重大转变:传导性方法正被积极淘汰,取而代之的是归纳模型,这些模型可以为新的、未见过的节点构建有意义的表示,并执行节点分类和链接预测。
在 2022 年,该领域沿着两个主要轴线扩展:1️⃣ 归纳链接预测(LP)2️⃣ 和归纳(多跳)查询回答,将链接预测扩展到更复杂的预测任务。
1️⃣ 在链路预测中,大多数归纳模型(如NBFNet或NodePiece)通过假设关系类型的集合在训练期间是固定的且不会随时间变化,从而转移到未见节点,并学习关系嵌入。当关系集合也发生变化时会发生什么?在最困难的情况下,我们希望能够转移到具有完全不同节点和关系类型的知识图谱。
到目前为止,所有支持未见关系的模型都依赖于元学习,这种方法既慢又消耗资源。在 2022 年,黄,任和莱斯科维奇首次提出了CSR(连接子图推理器)框架,它在实体和关系类型上都是归纳的且不需要任何元学习!👀 通常,在推理时,对于新关系,模型至少看到k个示例三元组(因此是 k-shot 学习场景)。从概念上讲,CSR 提取每个示例周围的子图,试图学习共同的关系模式(即优化边缘掩码),然后将掩码应用于查询子图(预测缺失的目标链路)。
支持具有未见实体和关系类型的知识图谱的归纳 CSR。来源:黄,任和莱斯科维奇
Chen 等人的ReFactor GNNs是另一项有关浅层 KG 嵌入模型归纳特性的有洞察力的工作——特别是,作者发现浅层因子分解模型如 DistMult 在反向传播的视角下,与无限深度的 GNNs 类似,节点如何从邻近节点和非邻近节点更新其表示。理论上,任何因子分解模型都可以转变为归纳模型!
2️⃣ 从归纳表征学习也开始涉及到复杂的逻辑查询回答。 (厚颜无耻的插入广告)事实上,这是我们团队今年的重点之一 😊 首先,在Zhu 等人的研究中,我们发现神经贝尔曼-福特网络从简单的链接预测成功地推广到了复杂的查询任务,这是在一个新的GNN 查询执行器(GNN-QE)模型中,其中一个基于 NBF-Net 的 GNN 进行了关系投影,而其他逻辑运算通过模糊逻辑t-范数来实现。 然后,在知识图中的归纳逻辑查询回答中,我们研究了⚗️ 归纳性的本质 ⚗️并提出了两种解决方案,以在推理时回答关于未知实体的逻辑查询,即通过(1)与仅用于推理的解码器配对的归纳节点表示(性能较差但可扩展),或通过(2)类似于 GNN-QE 中的归纳关系结构表示(质量更高但需要更多资源并且难以扩展)。 总的来说,我们能够在推理时处理拥有数百万节点和 500k 个未见节点以及 5m 未见边缘的图中进行归纳查询设置。
透过节点表示(NodePiece-QE)和关系结构表示(GNN-QE)进行归纳逻辑查询回答。 来源:Galkin 等人
这个领域中的另一项重要工作是SMORE来自任、戴等人 — 这是一个大规模(仅限传导)的系统,可对大约 90M 个节点和 300M 条边缘的完整 Freebase 进行复杂查询回答👀。 除了 CUDA、训练和管道优化,SMORE 还实现了一个双向查询采样器,使得训练查询可以在数据加载器中即时生成,而无需创建和存储大量数据集。 不要忘记从 LOG 2022 中查看关于大规模图推理的全新实践教程!
最后但并非最不重要,杨、林和张提出了一篇有趣的论文,重新思考了知识图完成的评估。 他们指出知识图倾向于是开放世界的(即,有些事实并未被知识图编码),而不是大部分作品所假设的闭世界。 因此,在闭世界假设下观察到的指标对真实指标呈现出了对数趋势——这意味着如果你的模型得到了 0.4 的 MRR,那么测试知识图很可能是不完整的,而你的模型已经做得相当不错👍。也许我们可以设计一些新的数据集和评估来缓解这个问题?
2023 年的预期:一个可以完全迁移到不同知识图谱的新集合的归纳模型,例如在 Wikidata 上进行训练,并在 DBpedia 或 Freebase 上运行推理。
算法推理与对齐
2022 年是算法推理领域取得重大突破和里程碑的一年。
1️⃣ 首先,CLRS 基准测试由 Veličković 等人 提供,现在可以作为设计和评估算法推理模型和任务的主要平台。CLRS 已经包括了 30 个任务(如经典排序算法、字符串算法和图算法),但仍然允许你带入自己的公式或修改现有公式。
2️⃣ 然后,Ibarz 等人 和 DeepMind 的通用神经算法学习器表明,可以训练一个单一的处理器网络,在不同算法上以多任务模式进行训练——以前,你需要为每个 CLRS 问题训练一个单独的模型。论文还描述了模型架构和训练过程中的若干修改和技巧,以使模型更好地进行泛化并防止遗忘,例如,类似于三角注意力的三元组推理(在分子模型中常见)和 边变换器。总体而言,新模型带来了比基线高出 25% 的绝对增益,并且以 60%+ 的微观 F1 分数解决了 30 个 CLRS 任务中的 24 个。
来源:Ibarz 等人
3️⃣ 去年,我们讨论了关于算法对齐的工作,并看到 GNNs 可能与动态规划良好对齐的迹象。在 2022 年,Dudzik 和 Veličković 通过范畴论、抽象代数以及推前和拉回操作的概念证明了GNNs 是动态规划器。这是应用范畴论的一个绝妙例子,许多人认为这是“抽象无聊”的😉。范畴论可能会在 GNN 理论和图 ML 中产生更大的影响,因此可以查看新的课程 Cats4AI 以获得对该领域的温和介绍。
4️⃣ 最后,Beurer-Kellner 等人 的工作是神经算法推理框架的首批实际应用之一,这里将其应用于配置计算机网络,即互联网核心的路由协议如 BGP。在这项工作中,作者展示了将路由配置表示为图形,可以将路由问题框架化为节点属性预测。这种方法相比传统的基于规则的路由方法带来了惊人的👀 490x 👀加速,并且仍然保持 90%以上的规范一致性。
如果你想更深入地了解算法推理,不要错过 Petar Veličković、Andreea Deac 和 Andrew Dudzik 最新的 LoG 2022 教程。
2023 年的展望: 1️⃣ 算法推理任务可能会扩展到成千上万个节点的图,以及代码分析或数据库等实际应用, 2️⃣ 更多的基准算法, 3️⃣ 最不可能——会出现一个能够解决 quickselect 的模型 😅
酷炫的 GNN 应用
👃 使用 GNN 学习嗅觉。 早在 2019 年,Google AI 开始了一个关于嗅觉表示学习的 项目。从基础化学知识我们知道,芳香性取决于分子结构,例如环状化合物。事实上,整个“芳香烃”组被命名为 芳香的 是因为它们实际上有一些气味(与许多无机分子相比)。如果我们有一个分子结构,我们可以在其基础上使用 GNN 来学习一些表示!
最近,Google AI 发布了 一篇新博客文章 和 Qian 等人 的论文,描述了项目的下一阶段——主要气味地图,能够将分子分组为“气味簇”。作者进行了三项有趣的实验:对 400 种之前从未闻过的新分子进行分类,并与一组人类评审员的平均评分进行比较;将气味质量与基础生物学关联;以及探测芳香分子的驱蚊特性。基于 GNN 的模型表现非常出色——现在我们可以自信地说 GNN 可以嗅觉!期待 GNN 在香水行业的变革。
气味的嵌入。来源:Google AI 博客
⚽ GNNs + 足球。 如果你认为用于建模轨迹的复杂 GNN 仅用于分子动力学和深奥的量子模拟,那就不要担心!这里有一个非常有潜力的实际应用:Graph Imputer 由 Omidshafiei 等 提出的,DeepMind 和利物浦足球俱乐部预测足球运动员(以及足球)的轨迹。每场比赛图包含 23 个节点,通过标准消息传递编码器和特殊的时间依赖 LSTM 进行更新。数据集也非常新颖——它包含了 105 场英超比赛(每场比赛平均 90 分钟),所有球员和足球的运动被以 25 帧每秒的速度跟踪,得到的训练轨迹序列编码了大约 9.6 秒的比赛过程。
这篇论文易于阅读,并有大量的足球插图,快去看看吧!体育技术在这些年里迅速发展,足球分析师现在可以更深入地研究他们的对手。英超俱乐部会在即将到来的转会窗口中竞争 GNN 研究人员吗?是时候为 GNN 研究人员创建一个 transfermarkt 了😉
足球比赛模拟就像分子动力学模拟一样!来源:DeepMind
🪐 银河系与天体物理学。 对天体物理学爱好者而言:Mangrove 由 Jespersen 等 提出的应用 GraphSAGE 于暗物质的合并树,以预测各种银河属性,如恒星质量、冷气体质量、星形成率,甚至黑洞质量。尽管这篇论文在天体物理学术语上有些复杂,但在 GNN 参数化和训练方面相对简单。Mangrove 的速度比标准模型快 4 到 9 个数量级。实验图表就像艺术品一样,可以挂在墙上 🖼️。
Mangrove 将暗物质晕呈现为合并树和图。来源:Jespersen 等
🤖 GNNs 用于代码。像 AlphaCode 和 Codex 这样的代码生成模型具有令人惊叹的能力。虽然 LLMs 是这些模型的核心,但 GNNs 在几个巧妙的方面确实有帮助:指令指针注意力 GNNs(IPA-GNNs)首次由Bieber et al提出,用于预测运行时错误在竞赛编程任务中——这几乎就像一个虚拟的代码解释器!由Pashakhanloo et al.提出的CodeTrek建议将程序建模为关系图,并通过随机游走和 Transformer 编码器进行嵌入。下游应用包括变量误用、预测异常和预测被遮蔽的变量。
硬件:IPUs 和 Graphcore 赢得 OGB 大规模挑战赛 2022
🥇 2022 年为Graphcore和IPUs带来了巨大的成功——这些硬件专门优化了处理图形时非常需要的稀疏操作。第一个成功故事是优化了 IPUs 上的 Temporal Graph Nets (TGN),取得了巨大的性能提升(查看 Michael Bronstein 博客中的文章)。
加速和扩展在 Graphcore IPU 上的 Temporal Graph Networks
GPU 是 GNNs 的最佳硬件选择吗?与 Graphcore 一起,我们探讨了新 IPU 的优势……
towardsdatascience.com
此后,Graphcore 在 OGB LSC’22 的排行榜上大放异彩,在 3 个赛道中赢得了 2 个:WikiKG90M v2知识图谱上的链接预测和PCQM4M v2分子数据集上的图回归。除了强大的计算能力外,作者还做出了一些巧妙的模型决策:对于链接预测,采用了平衡实体采样和共享 (BESS)来训练一个浅层 LP 模型的集合(查看 Daniel Justus 的博客文章了解更多细节),对于图回归任务采用了 GPS++(我们在 GT 部分中讨论了 GPS++)。你可以尝试在 Paperspace 上使用 IPUs 支持的虚拟机来使用预训练模型。祝贺 Graphcore 及其团队!👏
PyG 与 NVIDIA (post) 和 Intel (post) 合作,分别提高了 GPU 和 CPU 上核心操作的性能。类似地,DGL 纳入 了最近 0.9 版本中的新 GPU 优化。对于稀疏矩阵乘法和采样程序都有大幅提升,因此我们建议你更新到最新版本的环境!
2023 年的期望: 主要 GNN 库可能会扩展对硬件后端的支持,如 IPU 或即将推出的 Intel Max 系列 GPU。
新会议:学习图形(LoG)和分子 ML(MoML)
今年我们见证了两个图形和几何 ML 会议的启动:学习图形会议(LoG) 和 分子 ML 会议(MoML)。
LoG 是一个更通用的全方位 GraphML 会议(今年以虚拟形式举行),而 MoML(在 MIT 举办)具有更广泛的使命和对 AI4Science 社区的影响,其中图和几何仍然扮演着重要角色。这两个会议都得到了极好的反响。MoML 吸引了 7 位顶级讲者和 38 个海报,LoG 有大约 3000 个注册、266 个投稿、71 个海报、12 个口头报告和 7 个精彩的教程(所有口头报告和教程的录音已在 YouTube 上)。此外,LoG 为评审引入了丰厚的奖金激励,显著提高了评审质量!在我们看来,LoG 的评审质量通常优于 NeurIPS 或 ICML 的评审。
这是图形 ML 社区的一次巨大胜利和庆典,祝贺所有在图形和几何机器学习领域工作的人员,拥有了一个新的“家”会议!
2023 年的期望: LOG 和 MoML 将成为包括在提交日历中的主要 Graph ML 会议,此外还有 ICLR / NeurIPS / ICML。
课程和教育材料
-
几何深度学习课程 — 第二版(2022 年)已在 YouTube 上。该领域的主要入门点。
-
群体等变深度学习介绍 由 Erik Bekkers 提供 — 这是关于等变性和等变模型的最佳新课程之一!
-
Cats4AI — 由 Andrew Dudzik、Bruno Gavranović、João Guilherme Araújo、Petar Veličković 和 Pim de Haan 开设的新课程,是了解范畴理论及其与几何深度学习连接的最佳场所。
-
夏季学校成果:意大利几何深度学习夏季学校、伦敦几何与机器学习(LOGML)夏季学校、BIRS 顶点表示学习研讨会。
-
斯坦福图学习研讨会 2022 — PyG 开发者、合作伙伴和斯坦福研究人员的最新消息。
新数据集、基准和挑战
-
OGB 大规模挑战 2022: 第二届大规模挑战,在 NeurIPS2022 上举办,涵盖节点、边、图级预测的大规模和现实图机器学习任务。
-
开放催化剂 2022 挑战: 第二届挑战,在 NeurIPS2022 上举办,任务是设计新的机器学习模型,以预测催化剂模拟的结果,以了解其活性。
-
CASP 15: 由 AlphaFold 在 CASP 14 中引发的蛋白质结构预测挑战。详细分析尚待公布,但似乎 MSAs 卷土重来,表现最好的模型仍然依赖于 MSAs。
-
长距离图基准: 用于测量 GNNs 和 GTs 在图中捕捉长距离交互的能力。
-
GraphWorld: 一个框架,用于分析 GNN 架构在数百万个合成基准数据集上的表现。
-
Chartalist — 一系列区块链图数据集。
-
PEER 蛋白质学习基准: 一个多任务蛋白质序列理解基准,包括 17 个蛋白质理解任务,分为 5 个任务类别。
-
ESM 宏基因组图谱: 一个综合性数据库,包含超过 6 亿个预测蛋白质结构,提供了漂亮的可视化和搜索界面。
软件库和开源
-
主流图机器学习库:PyG 2.2(PyTorch),DGL 0.9(PyTorch、TensorFlow、MXNet),TF GNN(TensorFlow)和 Jraph(Jax)
-
TorchDrug 和 TorchProtein: 用于药物发现和蛋白质科学的机器学习库。
-
PyKEEN: 用于训练和评估知识图谱嵌入的最佳平台。
-
Graphein: 提供多种基于图的蛋白质表示的包。
-
MatSci ML 工具包: 用于在 opencatalyst 数据集上进行深度学习的灵活框架。
-
E3nn:用于 E(3) 等变神经网络的首选库
加入社区
-
图学习(LoG)Slack 社区
-
PyG medium、博客文章和通讯
2022 年的流行文化现象 🪓
由 Michael Galkin 和 Michael Bronstein 创建