faiss hnsw 算法源码详解 - train
hnswlib 代码分析 hnswlib 源码分析
train过程说明
- 主要是生成hnsw模型
- Hnsw中,storage中存储的原始的中心点向量
- 生成hnsw
- 为每层分配空间
- 每层的中心点在当前层及下面的每一层都有中心点,例如第n层在n、n-1、…1层都有临近点,第3层只在3、2、1层有临近点。
- 同一个临近点在各层的数据是连续存储在一起的。
- 新加入的数据在下面的各层查找对应的临近点的候选集,选出最后的临近点,然后建立link
- 调整其他临近点的link,因为临近是相互的
76 void HNSW::set_default_probas(int M, float levelMult)
77 {
78 int nn = 0;
79 cum_nneighbor_per_level.push_back (0);
80 for (int level = 0; ;level++) {
81 float proba = exp(-level / levelMult) * (1 - exp(-1 / levelMult)); ///点落在每一层的概率,层越高概率越低,第0层概率为0.5
82 if (proba < 1e-9) break;
83 assign_probas.push_back(proba); ///向量落入每一层的概率
84 nn += level == 0 ? M * 2 : M;
85 cum_nneighbor_per_level.push_back (nn); ///每一层临近点的个数(每一层保存的是前几层的和)
86 }
87 }
203 /*n:向量个数, 为offsets,neighbors赋值*/
204 int HNSW::prepare_level_tab(size_t n, bool preset_levels)
205 {
206 size_t n0 = offsets.size() - 1;
207
208 if (preset_levels) {
209 FAISS_ASSERT (n0 + n == levels.size());
210 } else {
211 FAISS_ASSERT (n0 == levels.size());
212 for (int i = 0; i < n; i++) { ///为每条数据指定放到第几层
213 int pt_level = random_level(); ///数据放入第几层
214 levels.push_back(pt_level + 1); ///根据概率为数据指定level
215 }
216 }
217
218 int max_level = 0;
219 for (int i = 0; i < n; i++) { ///感觉这里是为offsets neighbors分配空间
220 int pt_level = levels[i + n0] - 1; ///第几层
221 if (pt_level > max_level) max_level = pt_level;
222 offsets.push_back(offsets.back() +
223 cum_nb_neighbors(pt_level + 1)); ///偏移是前面所有个数的累加
224 neighbors.resize(offsets.back(), -1);
225 }
226
227 return max_level; ///
}
439 /// Finds neighbors and builds links with them, starting from an entry
440 /// point. The own neighbor list is assumed to be locked. pt_id:向量(query向量)对应的id, nearest:最近点的idx(可以理解为中心点id),d_nearest:
最近距离,level:对应的层。在当前层查找最近的临近点,然后更新相关的临近点(随着新中心点加入,已加入的中心点的临近点也会发生变化)
441 void HNSW::add_links_starting_from(DistanceComputer& ptdis,
442 storage_idx_t pt_id,
443 storage_idx_t nearest,
444 float d_nearest,
445 int level,
446 omp_lock_t *locks,
447 VisitedTable &vt)
448 {
449 std::priority_queue<NodeDistCloser> link_targets;
450
451 search_neighbors_to_add(*this, ptdis, link_targets, nearest, d_nearest,
452 level, vt); ///当前层中和query最近的中心点放到link_targets队列中
453
454 // but we can afford(给予) only this many neighbors
455 int M = nb_neighbors(level); ///当前层的连接点数
456
457 ::faiss::shrink_neighbor_list(ptdis, link_targets, M); ///根据需要缩减临近点的数量(保留有代表性的临近点),把最优的放入link_targets中
458
459 while (!link_targets.empty()) {
460 int other_id = link_targets.top().id;
462 omp_set_lock(&locks[other_id]);
463 add_link(*this, ptdis, other_id, pt_id, level); ///调整other_id对应临近点(临近点是有限的)
464 omp_unset_lock(&locks[other_id]);
465
466 add_link(*this, ptdis, pt_id, other_id, level); ///调整新的链接(临近点是有限的)
467
468 link_targets.pop();
469 }
470 }
faiss hnsw 算法源码详解 - train相关推荐
- 【5G/4G】加/解密+完整性保护/校验算法源码详解
文章目录 加/解密+完整性保护/校验算法源码详解 一.加解密算法 二.完整性保护/校验算法 本人就职于国际知名终端厂商,负责modem芯片研发. 在5G早期负责终端数据业务层.核心网相关的开发工作,目 ...
- fdct算法 java_ImageSharp源码详解之JPEG压缩原理(3)DCT变换
DCT变换可谓是JPEG编码原理里面数学难度最高的一环,我也是因为DCT变换的算法才对JPEG编码感兴趣(真是不自量力).这一章我就把我对DCT的研究心得体会分享出来,希望各位大神也不吝赐教. 1.离 ...
- 【 反向传播算法 Back-Propagation 数学推导以及源码详解 深度学习 Pytorch笔记 B站刘二大人(3/10)】
反向传播算法 Back-Propagation 数学推导以及源码详解 深度学习 Pytorch笔记 B站刘二大人(3/10) 数学推导 BP算法 BP神经网络可以说机器学习的最基础网络.对于普通的简单 ...
- java的数组与Arrays类源码详解
java的数组与Arrays类源码详解 java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 类的 ...
- 李沐d2l《动手学深度学习》第二版——风格迁移源码详解
本文是对李沐Dive to DL<动手学深度学习>第二版13.12节风格迁移的源码详解,整体由Jupyter+VSCode完成,几乎所有重要代码均给出了注释,一看就懂.需要的同学可以在文末 ...
- AidLux“换脸”案例源码详解 (Python)
"换脸"案例源码详解 (Python) faceswap_gui.py用于换脸,可与facemovie_gui.py身体互换源码(上一篇文章)对照观看 打开faceswap_gui ...
- 【分类器 Softmax-Classifier softmax数学原理与源码详解 深度学习 Pytorch笔记 B站刘二大人(8/10)】
分类器 Softmax-Classifier softmax数学原理与源码详解 深度学习 Pytorch笔记 B站刘二大人 (8/10) 在进行本章的数学推导前,有必要先粗浅的介绍一下,笔者在广泛查找 ...
- 【 卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10)】
卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10) 本章主要进行卷积神经网络的相关数学原理和pytorch的对应模块进行推导分析 代码也是通过demo实 ...
- 【多输入模型 Multiple-Dimension 数学原理分析以及源码详解 深度学习 Pytorch笔记 B站刘二大人 (6/10)】
多输入模型 Multiple-Dimension 数学原理分析以及源码源码详解 深度学习 Pytorch笔记 B站刘二大人(6/10) 数学推导 在之前实现的模型普遍都是单输入单输出模型,显然,在现实 ...
最新文章
- python代码大全p-[译]让你的Python代码优雅又地道
- HDMI和VGA接口
- 坚持不懈,直到成功-I will persist. I will win.
- MongoDB只查询一个字段
- autocomplete=off inpu属性
- SAP BTP 应用 mta.yaml 里的 sap-btp-project1-dest-content module
- 成吉思汗:“世界之鞭”还是“人类之王”?
- [Cogs14] [网络流24题#1] 飞行员分配方案 [网络流,最大流,二分图匹配]
- Android TextView 带背景的文字垂直方向显示(ems属性)
- vue2.0路由(跳转和传参)经典介绍
- Python使用Telnetlib模块实现telnet远程操作
- 实验高中计算机,仿真物理实验室高中完整版
- 国内可以使用的英文搜索引擎
- 机器学习:蒙特卡罗方法
- HTML 简单日历制作方法
- C# winform 一个简单的类的方法的封装与调用
- 历届图灵奖和马尔奖获得者
- 【赵强老师】什么是PL/SQL?
- hash碰撞处理方法
- SiamFC++笔记