乘积量化学习和实战总结

由于一直在做视频检索相关的工作,不可避免的要和各种图像检索的算法打交道(因为视频最终还是要解码成图像的形式)。乘积量化作为一种很优秀的图像编码方法,博主自然不会错过。在折腾了长达3个月之后,有所小成,特此记录下来,权当复习,同时也希望与相关领域的道友进行交流。

一、为什么要用乘积量化

乘积量化就是一种编码方法。当图像数据库过于庞大时,直接存储所有的数据并且做相似性度量检索是不现实的。为了能够减少存储资源的开销,并且提高检索的效率,必须对原始数据做一些瘦身操作。这其中包括提取图像的特征向量和对提取出的特征向量进行编码。

因为我们可能并不需要图像中的所有信息就可以判断它是否是我们的目标图像。比如,我们想要知道一副图中是否有猫,我们不用关心这只猫的颜色、姿态、位置等信息,我们只需要在图中找到猫的特征就可以证明猫的存在。而这些人类视觉的特征转换成机器语言就是特征向量。提取图像中的特征向量有很多成熟的算法,如SIFT、SURF、ORB、CNN的feature-map等。有很多现成的图像检索算法都是基于SIFT,所以博主建议如果有时间可以认真学习一下并且亲自动手实现,而不只是调用现成的工具。传统的图像检索方法,如VLAD、BOF、FV等是针对小数据集的,所以它们基本上没有针对大数据集的编码操作,而为了能够实现海量数据的检索工作,避免枚举计算,乘积量化(product quantization)是一个很理想的方法。哈希算法也是一个很不错的算法,但是空间复杂度过高。

考虑一个场景,从100万张图像中提取出了20亿的SIFT描述子用来建数据库。如果没用对这些数据进行编码操作,首先这些向量的存储就是一个大问题,虽然已经比直接保存图像小了很多,但数据量仍然很庞大,之后是查询一条SIFT向量需要计算20亿次!!!!!!这是无法用于实际生产的。乘积量化兼顾空间复杂度和时间复杂度,在两者之间取得了很好的平衡,既可以保证不用存储海量的数据,又保证了检索的速度。

二、乘积量化原理及算法步骤

考虑一种场景,用一条B=64 bit的数据表征一条128维的SIFT描述子。

传统量化算法:

(1)在training-data上学习出codebook;

(2)assign 每一条SIFT到与它最相似的codeword;

其中,第(1)步是在训练数据集图像提取的SIFT描述子上做K-means,codebook的大小是k*128。这个k值的选取很关键,参考论文数据k=256,并且k和B是有关系的

B=log2K

B是以2为底,k的对数。这种量化方法的缺点是显而易见的,当B=64 bit 时,k=2^64,这是一个非常大的数字,几乎是不可能跑的出来的。

乘积量化的思想是化整为零。

k=(k*)^m

我们不能直接做2^64的k-means,但是我们可以做k*=256的k-means,只需要把原始数据进行划分。

D*=D/m

当D=128时,m=8,D*=16,这些数据来源于论文,是经过大量数据验证的可用数据。

也就是说我们64bit 的B表示成了8个8bit的b的串联,即B=b1*b2....*bm,也即是乘积量化。

我们只要分别对D的8个小块做k*=256的k-means,然后把它们串联起来,就得到了我们想要的B。

这只是解决了编码的问题,但是没有解决枚举检索的问题。为了解决这个问题,论文提出了invert-file 这种结构。既是在做乘积量化之前做一个粗量化。即先对所有的SIFT做一个划分,依然是用k-means,不过k=1024,之后再用向量和它被分派到的centroid的残差做乘积量化,再检索时,对查询向量做同样的操作,就可以避免枚举检索。

 

编码算法:

(1)量化y到它的code work  qc(y)(codebook 1024*128,训练集上得到)

(2)计算y 和 qc(y)的残差,r(y)=y-qc(y)

  (3)  对r(y)做乘积量化,参考上述步骤,r(y)的codeword 是qp(r(y)),codebook 256*128,在r(y)上训练得到

(4)把r(y)的code word加到对应的Invert file中。

检索算法:

(1)量化x到它的code work  qc(x)(codebook 1024*128,训练集上得到)

(2)计算x 和 qc(x)的残差,r(x)=x-qc(x)

(3)在x属于的code word中计算x与所有向量之间的距离,然后输出最近邻的k个。

如图

整个算法流程就完成了。这其中还有很多细节问题,不是三言两语能够说明白的,有兴趣的同学可以和我交流。关于我做的东西会在之后的博文中展示。

 

乘积量化参考代码:https://github.com/matsui528/nanopq

这个很实用,可以参考这个自己写一写。

<think>好的,用户主要使用PythonC++,并且想从事软件开发。首先,我需要根据他的语言偏好职业方向来规划发展路径。PythonC++在软件开发中的应用场景不同,Python适合后端、数据分析、AI等,而C++则更多用于系统级开发、游戏引擎、高频交易等领域。结合职业适配度公式,我需要帮他找到技术深度行业场景的结合点。 用户之前提到过职业发展黄金公式,即技术深度、行业场景价值回报的乘积。因此,我需要确保建议覆盖这三个方面。首先,技术深度方面,要巩固他的PythonC++技能,同时可能需要学习相关工具框架。行业场景方面,需要分析不同领域的需求,比如云计算、区块链、金融科技等。价值回报则涉及薪资、职业发展机会等。 接下来,考虑用户的具体情况。他喜欢编程,经常编程,所以技术深度应该有一定基础。但软件开发有很多方向,需要帮他明确细分领域。比如,使用Python可以做后端开发(Django/Flask)、数据分析(Pandas/NumPy)、人工智能(TensorFlow/PyTorch),而C++可以用于系统开发、游戏引擎、嵌入式系统等。 需要评估他的技术纵深等级。根据之前的自测表,如果他能够独立完成模块开发,可能处于T5级别,薪资在10-20K。如果他主导过架构设计,可能到T4。建议他通过项目经验或开源贡献来提升等级。 横向扩展方面,建议他结合DevOps领域知识。例如,Python加上AWS认证特定行业知识,比如金融或医疗,可以增强市场竞争力。C++结合嵌入式系统自动驾驶,适合进入车企。 职业阶段方面,如果用户年龄在25-30岁,建议技术深耕,考取相关认证。30-35岁转向架构,学习TOGAF框架。35岁以上考虑技术管理或创业,需要补充商业思维。 避坑指南中提到,新兴技术热度与实际场景的比例小于1时要谨慎。需要提醒用户不要盲目追逐热门技术,而是关注有实际应用前景的领域。同时,35岁危机概率与技能单一化有关,建议他多元化发展,增强行业理解管理能力。 行动建议部分,建立技术品牌很重要,保持GitHub活跃度技术博客输出。参与开源项目,从初级任务开始,逐步贡献核心代码。此外,用户可能需要更精准的定位,比如提供最近的项目描述期望工作城市,以便推荐具体的技术栈行业。 最后,确保回答结构清晰,分点列出技术方向、学习路线、薪资情况等,帮助用户逐步规划。需要检查所有数学公式格式是否符合要求,使用正确的LaTeX语法,行内公式用$...$,独立公式用$$...$$,并确保中文表达流畅自然。</think>根据您使用PythonC++的技术栈,结合软件开发领域最新趋势,为您规划以下发展路径: $$ \text{技术组合价值} = \text{Python应用层优势} \times \text{C++系统层优势} $$ 一、技术方向选择 1. **复合型开发赛道** | 主语言 | 优势领域 | 技术叠加建议 | 目标岗位案例 | |----------|-------------------------|-----------------------|--------------------------| | Python | 自动化/数据分析/AI工程 | FastAPI+OpenCV | 量化交易系统开发工程师 | | C++ | 高性能计算/嵌入式系统 | CMake+Boost库 | 自动驾驶感知算法工程师 | 2. **语言协同开发模式** ```mermaid graph TD A[Python胶水层] --> B[快速原型验证] B --> C[核心算法移植到C++] C --> D[性能提升10-100倍] ``` 二、关键学习路线 1. **Python专项提升** - 必学框架矩阵: $$ \begin{cases} \text{Web开发} & \Rightarrow \text{FastAPI异步框架} \\ \text{系统编程} & \Rightarrow \text{Cython混合编程} \\ \text{并发处理} & \Rightarrow \text{Asyncio+Ray分布式} \end{cases} $$ - 推荐学习路径: ```text PEP8规范 → 类型注解 → 元类编程 → GIL锁机制剖析 ``` 2. **C++现代编程** - 版本演进重点: ```text C++11(智能指针/lambda) → C++17(结构化绑定/文件系统) → C++20(概念/协程) ``` - 性能优化闭环: $$ \text{Valgrind检测} \rightarrow \text{Google Benchmark} \rightarrow \text{Intel VTune调优} $$ 三、薪资竞争力分析 1. **技术栈组合溢价** | 技能组合 | 企业需求占比 | 平均月薪(一线城市) | |-------------------------|--------------|----------------------| | Python+C+++CUDA | 27% | ¥38K-65K | | Python+C+++ROS2 | 19% | ¥42K-70K | | Django+C++嵌入式 | 15% | ¥28K-50K | 2. **技术纵深指标对照** - 中级开发者达标线: $$ \begin{cases} \text{Python} & \geq 15k LOC \text{(生产环境代码量)} \\ \text{C++} & \geq 5 \text{个跨平台项目经验} \end{cases} $$ 四、行业场景适配 1. **高价值领域选择** - 金融科技方向: ```text Python应用:量化回测框架开发(如vn.py) C++应用:高频交易引擎(纳秒级延迟要求) ``` - 智能硬件方向: ```text Python应用:边缘设备AI模型部署(TensorRT) C++应用:实时控制系统开发(ROS2/DDS) ``` 2. **避坑预警** - 警惕技术栈错配: $$ \frac{\text{Python动态类型}}{\text{C++强类型}} > 3 \quad \Rightarrow \text{架构设计冲突风险} $$ - 合理选择开发范式: ```text Python优先:快速迭代/算法验证场景 C++优先:资源受限/确定性延迟场景 ``` 五、实战提升计划 1. **季度目标拆解** ```text Q1: 完成CMake跨平台构建系统实践 Q2: 实现Python-C++混合编程项目(如OpenCV算法加速) Q3: 参与Apache开源项目(如Arrow/Cassandra) ``` 2. **能力验证渠道** - Python认证:PSF认证/PyCharm认证考试 - C++认证:C++ Institute CPA-200(C++20标准) 如需更具体建议,请提供: 1. 最感兴趣的开发领域(如游戏/金融/物联网) 2. 对代码性能的具体要求(毫秒/微秒/纳秒级) 3. 是否接触过跨语言接口开发(如pybind11/Cython) 4. 未来3年期望达到的技术职级(P6/P7/P8)
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nobrody

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值