把全量迭代换成小批量滑动平均
k-means 常用的 Lloyd 算法每一轮都要扫完全部数据,再重算每个簇的中心。Meta FAIR 的 Swann Bessa 等 7 位作者 11 月 6 日提交到 arXiv 的论文提出 e-means:每次只取一个小批量,用指数滑动平均累积每个簇的向量和与样本数,两者相除得到中心。项目页说明,把批大小设成整个数据集、步长设为 1,e-means 的一次迭代就等于一次 Lloyd 迭代;作者的超参数搜索显示,这个极端取值的效果明显偏差。
批大小和步长按公式算,不用调参
以往的小批量 k-means 需要人工调批大小和学习率。论文拟合出一组缩放律,按数据量、簇数和计划轮数直接算出这两个值,不再做超参数搜索。此外,初始化方式有改动;没有分到样本的“死簇”不像常见做法那样用随机样本替换,而是按簇大小抽一个现有的簇一分为二;衰减率按余弦曲线调度,结束时落在每个簇最后一轮的精确均值上。
作者给出的数字,以及还没有的验证
论文摘要称,在多组嵌入数据集上,e-means 用 1.4 到 2.6 轮就低于 Lloyd 跑 25 轮的损失,对应 GPU 实际耗时 10 到 45 倍的加速,且经常优于 k-means++;把 100 亿条 DINO 嵌入组成的 DINO10B 分成 1600 万个簇只用了 2.5 轮。项目页的口径是 1.2 到 3 轮,GPU 上对比 Flash-KMeans 快 10 到 45 倍,CPU 上对比 Faiss 快 8 到 15 倍。
代码已放在 facebookresearch/faiss 的 contrib/e_means 目录。论文目前是 v1 预印本,未经同行评审,上述数字均为作者自测,测试对象是嵌入类数据;在其他数据分布上的表现有待第三方复现。
via: arXiv:2611.09501:e-means: outperforming k-means (in one-tenth the epochs)、e-means 项目页、GitHub:facebookresearch/faiss contrib/e_means