hnswlib 代码分析 hnswlib 源码分析

train过程说明

  1. 主要是生成hnsw模型
  2. Hnsw中,storage中存储的原始的中心点向量
  3. 生成hnsw
    1. 为每层分配空间
    2. 每层的中心点在当前层及下面的每一层都有中心点,例如第n层在n、n-1、…1层都有临近点,第3层只在3、2、1层有临近点。
    3. 同一个临近点在各层的数据是连续存储在一起的。
    4. 新加入的数据在下面的各层查找对应的临近点的候选集,选出最后的临近点,然后建立link
    5. 调整其他临近点的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相关推荐

  1. 【5G/4G】加/解密+完整性保护/校验算法源码详解

    文章目录 加/解密+完整性保护/校验算法源码详解 一.加解密算法 二.完整性保护/校验算法 本人就职于国际知名终端厂商,负责modem芯片研发. 在5G早期负责终端数据业务层.核心网相关的开发工作,目 ...

  2. fdct算法 java_ImageSharp源码详解之JPEG压缩原理(3)DCT变换

    DCT变换可谓是JPEG编码原理里面数学难度最高的一环,我也是因为DCT变换的算法才对JPEG编码感兴趣(真是不自量力).这一章我就把我对DCT的研究心得体会分享出来,希望各位大神也不吝赐教. 1.离 ...

  3. 【 反向传播算法 Back-Propagation 数学推导以及源码详解 深度学习 Pytorch笔记 B站刘二大人(3/10)】

    反向传播算法 Back-Propagation 数学推导以及源码详解 深度学习 Pytorch笔记 B站刘二大人(3/10) 数学推导 BP算法 BP神经网络可以说机器学习的最基础网络.对于普通的简单 ...

  4. java的数组与Arrays类源码详解

    java的数组与Arrays类源码详解 java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 类的 ...

  5. 李沐d2l《动手学深度学习》第二版——风格迁移源码详解

    本文是对李沐Dive to DL<动手学深度学习>第二版13.12节风格迁移的源码详解,整体由Jupyter+VSCode完成,几乎所有重要代码均给出了注释,一看就懂.需要的同学可以在文末 ...

  6. AidLux“换脸”案例源码详解 (Python)

    "换脸"案例源码详解 (Python) faceswap_gui.py用于换脸,可与facemovie_gui.py身体互换源码(上一篇文章)对照观看 打开faceswap_gui ...

  7. 【分类器 Softmax-Classifier softmax数学原理与源码详解 深度学习 Pytorch笔记 B站刘二大人(8/10)】

    分类器 Softmax-Classifier softmax数学原理与源码详解 深度学习 Pytorch笔记 B站刘二大人 (8/10) 在进行本章的数学推导前,有必要先粗浅的介绍一下,笔者在广泛查找 ...

  8. 【 卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10)】

    卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10) 本章主要进行卷积神经网络的相关数学原理和pytorch的对应模块进行推导分析 代码也是通过demo实 ...

  9. 【多输入模型 Multiple-Dimension 数学原理分析以及源码详解 深度学习 Pytorch笔记 B站刘二大人 (6/10)】

    多输入模型 Multiple-Dimension 数学原理分析以及源码源码详解 深度学习 Pytorch笔记 B站刘二大人(6/10) 数学推导 在之前实现的模型普遍都是单输入单输出模型,显然,在现实 ...

最新文章

  1. python代码大全p-[译]让你的Python代码优雅又地道
  2. HDMI和VGA接口
  3. 坚持不懈,直到成功-I will persist. I will win.
  4. MongoDB只查询一个字段
  5. autocomplete=off inpu属性
  6. SAP BTP 应用 mta.yaml 里的 sap-btp-project1-dest-content module
  7. 成吉思汗:“世界之鞭”还是“人类之王”?
  8. [Cogs14] [网络流24题#1] 飞行员分配方案 [网络流,最大流,二分图匹配]
  9. Android TextView 带背景的文字垂直方向显示(ems属性)
  10. vue2.0路由(跳转和传参)经典介绍
  11. Python使用Telnetlib模块实现telnet远程操作
  12. 实验高中计算机,仿真物理实验室高中完整版
  13. 国内可以使用的英文搜索引擎
  14. 机器学习:蒙特卡罗方法
  15. HTML 简单日历制作方法
  16. C# winform 一个简单的类的方法的封装与调用
  17. 历届图灵奖和马尔奖获得者
  18. 【赵强老师】什么是PL/SQL?
  19. hash碰撞处理方法
  20. SiamFC++笔记

热门文章

  1. 深蓝学院-视觉SLAM课程-第7讲笔记
  2. FIND函数的使用方法
  3. 《嵌入式系统 - Zephyr开发笔记》 第2章 Zephyr 编译环境搭建(Linux)
  4. 人又不聪明,还学别人秃顶 - 类似100条-转自小区论坛
  5. win8系统在安装msi文件时遇到2502和2503错误
  6. “保姆级”车载CAN总线教程(二)-堪称全网“最细”系列
  7. LCD段码液晶屏设计图纸分析
  8. 王小云:十年破译五部顶级密码
  9. JAVA 学习之implements的用法
  10. 暴走英雄坛服务器维修,暴走英雄坛妙手空空触发条件及任务流程