文件 VectorTransform.h
-
namespace faiss
实现具有多种变体的 k-means 聚类。
版权所有 (c) Facebook, Inc. 及其附属公司。
此源代码根据 MIT 许可证获得许可,该许可证位于此源树的根目录中的 LICENSE 文件中。
IDSelector 旨在定义要处理的向量子集(用于删除或作为搜索的子集)
PQ4 SIMD 打包和累积函数
基本内核使用 bbs = nb * 2 * 16 向量累积 nq 查询向量,并生成该向量的输出矩阵。 对于 nq * nb <= 4 很有用,否则寄存器溢出变得太大。
这些函数的实现分布在 3 个 cpp 文件中,以减少并行编译时间。 模板被显式实例化。
此文件包含用于计算距离的内核的回调。
在整个库中,向量以 float * 指针的形式提供。 当批量处理(添加/搜索)多个向量时,可以优化大多数算法。 在这种情况下,它们作为矩阵传入。 当大小为 d 的 n 个向量作为 float * x 提供时,向量 i 的分量 j 为
x[ i * d + j ]
其中 0 <= i < n 且 0 <= j < d。 换句话说,矩阵始终是紧凑的。 当指定矩阵的大小时,我们称其为 n*d 矩阵,这意味着行优先存储。
I/O 函数可以读/写到文件名、文件句柄或抽象介质的对象。
读取函数返回应该使用 delete 释放的对象。 这些对象中的所有引用都归对象所有。
反向列表的定义 + 几个实现该接口的通用类。
由于 IVF(反向文件)索引对于大规模用例非常有用,因此我们将与它们相关的几个函数分组到这个小库中。 大多数函数都可以在 IndexIVF 和嵌入在 IndexPreTransform 中的 IndexIVF 上工作。
在此文件中实现了 L2 和内积之外的额外度量
实现一些神经网络层,主要为了支持 QINCo
定义一些将变换应用于一组向量的对象。 通常这些是预处理步骤。
-
struct VectorTransform
- #include <VectorTransform.h>
应用于一组向量的任何变换
由 faiss::CenteringTransform, faiss::ITQTransform, faiss::LinearTransform, faiss::NormalizationTransform, faiss::RemapDimensionsTransform 继承
公共函数
-
inline explicit VectorTransform(int d_in = 0, int d_out = 0)
! 输出维度
-
virtual void train(idx_t n, const float *x)
在具有代表性的向量集合上执行训练。默认情况下不执行任何操作。
- 参数:
n – 训练向量的数量
x – 训练向量,大小为 n * d
-
float *apply(idx_t n, const float *x) const
应用转换,并在分配的指针中返回结果
- 参数:
n – 要转换的向量的数量
x – 输入向量,大小为 n * d_in
- 返回值:
输出向量,大小为 n * d_out
-
virtual void apply_noalloc(idx_t n, const float *x, float *xt) const = 0
应用转换,并在提供的矩阵中返回结果
- 参数:
n – 要转换的向量的数量
x – 输入向量,大小为 n * d_in
xt – 输出向量,大小为 n * d_out
-
virtual void check_identical(const VectorTransform &other) const = 0
-
inline virtual ~VectorTransform()
-
inline explicit VectorTransform(int d_in = 0, int d_out = 0)
-
struct LinearTransform : public faiss::VectorTransform
- #include <VectorTransform.h>
通用线性变换,在输出上应用偏置项 y = A * x + b
被 faiss::ITQMatrix, faiss::OPQMatrix, faiss::PCAMatrix, faiss::RandomRotationMatrix 继承
公共函数
-
explicit LinearTransform(int d_in = 0, int d_out = 0, bool have_bias = false)
支持 d_in > d_out 和 d_out < d_in
-
void transform_transpose(idx_t n, const float *y, float *x) const
如果 A 具有标准正交线,则计算 x = A^T * (x - b) 是反向变换
-
virtual void reverse_transform(idx_t n, const float *xt, float *x) const override
仅当 is_orthonormal 为真时有效。
-
void set_is_orthonormal()
计算 A^T * A 来设置 is_orthonormal 标志。
-
virtual void check_identical(const VectorTransform &other) const override
-
inline ~LinearTransform() override
-
explicit LinearTransform(int d_in = 0, int d_out = 0, bool have_bias = false)
-
struct RandomRotationMatrix : public faiss::LinearTransform
- #include <VectorTransform.h>
随机旋转一组向量。
公共函数
-
inline RandomRotationMatrix(int d_in, int d_out)
支持 d_in > d_out 和 d_out < d_in
-
void init(int seed)
必须在使用变换之前调用
-
virtual void train(idx_t n, const float *x) override
在具有代表性的向量集合上执行训练。默认情况下不执行任何操作。
- 参数:
n – 训练向量的数量
x – 训练向量,大小为 n * d
-
inline RandomRotationMatrix()
-
void transform_transpose(idx_t n, const float *y, float *x) const
如果 A 具有标准正交线,则计算 x = A^T * (x - b) 是反向变换
-
virtual void reverse_transform(idx_t n, const float *xt, float *x) const override
仅当 is_orthonormal 为真时有效。
-
void set_is_orthonormal()
计算 A^T * A 来设置 is_orthonormal 标志。
-
virtual void check_identical(const VectorTransform &other) const override
-
inline RandomRotationMatrix(int d_in, int d_out)
-
struct PCAMatrix : public faiss::LinearTransform
- #include <VectorTransform.h>
对一组向量应用主成分分析,可以选择进行白化和随机旋转。
公共函数
-
explicit PCAMatrix(int d_in = 0, int d_out = 0, float eigen_power = 0, bool random_rotation = false)
-
void prepare_Ab()
在计算均值,PCAMat和特征值后调用
-
void transform_transpose(idx_t n, const float *y, float *x) const
如果 A 具有标准正交线,则计算 x = A^T * (x - b) 是反向变换
-
virtual void reverse_transform(idx_t n, const float *xt, float *x) const override
仅当 is_orthonormal 为真时有效。
-
void set_is_orthonormal()
计算 A^T * A 来设置 is_orthonormal 标志。
-
virtual void check_identical(const VectorTransform &other) const override
公共成员
-
float eigen_power
变换后,组件乘以 eigenvalues^eigen_power
>=0:不白化 =-0.5:完全白化
-
float epsilon
添加到特征值的值,以避免在白化时除以0
-
bool random_rotation
PCA之后的随机旋转
-
size_t max_points_per_d
训练向量数量与维度的比率
-
int balanced_bins
尝试将输出特征向量分配到这么多 bins 中
-
bool have_bias
-
bool is_orthonormal
! 是否使用偏置项
检查矩阵 A 是否为正交矩阵 (启用 reverse_transform)
-
bool verbose
-
int d_in
-
int d_out
! 输入维度
-
bool is_trained
设置 VectorTransform 是否不需要训练,或者是否已经完成训练
-
explicit PCAMatrix(int d_in = 0, int d_out = 0, float eigen_power = 0, bool random_rotation = false)
-
struct ITQMatrix : public faiss::LinearTransform
- #include <VectorTransform.h>
ITQ 实现来自
Iterative quantization: A procrustean approach to learning binary codes for large-scale image retrieval,
Yunchao Gong, Svetlana Lazebnik, Albert Gordo, Florent Perronnin, PAMI’12.
公共函数
-
explicit ITQMatrix(int d = 0)
-
virtual void train(idx_t n, const float *x) override
在具有代表性的向量集合上执行训练。默认情况下不执行任何操作。
- 参数:
n – 训练向量的数量
x – 训练向量,大小为 n * d
-
void transform_transpose(idx_t n, const float *y, float *x) const
如果 A 具有标准正交线,则计算 x = A^T * (x - b) 是反向变换
-
virtual void reverse_transform(idx_t n, const float *xt, float *x) const override
仅当 is_orthonormal 为真时有效。
-
void set_is_orthonormal()
计算 A^T * A 来设置 is_orthonormal 标志。
-
virtual void check_identical(const VectorTransform &other) const override
-
explicit ITQMatrix(int d = 0)
-
struct ITQTransform : public faiss::VectorTransform
- #include <VectorTransform.h>
完整的 ITQ 变换,包括归一化和 PCA 变换
公共函数
-
explicit ITQTransform(int d_in = 0, int d_out = 0, bool do_pca = false)
-
virtual void train(idx_t n, const float *x) override
在具有代表性的向量集合上执行训练。默认情况下不执行任何操作。
- 参数:
n – 训练向量的数量
x – 训练向量,大小为 n * d
-
virtual void apply_noalloc(idx_t n, const float *x, float *xt) const override
应用转换,并在提供的矩阵中返回结果
- 参数:
n – 要转换的向量的数量
x – 输入向量,大小为 n * d_in
xt – 输出向量,大小为 n * d_out
-
virtual void check_identical(const VectorTransform &other) const override
-
explicit ITQTransform(int d_in = 0, int d_out = 0, bool do_pca = false)
-
struct OPQMatrix : public faiss::LinearTransform
- #include <VectorTransform.h>
应用旋转来使维度与 PQ 对齐,从而最小化重建误差。 可在 IndexPQ 或 IndexIVFPQ 之前使用。 该方法是下面文章中描述的非参数版本
“用于近似最近邻搜索的优化乘积量化” Tiezheng Ge, Kaiming He, Qifa Ke, Jian Sun, CVPR’13
公共函数
-
explicit OPQMatrix(int d = 0, int M = 1, int d2 = -1)
如果 d2 != -1,则输出此维度的向量
-
virtual void train(idx_t n, const float *x) override
在具有代表性的向量集合上执行训练。默认情况下不执行任何操作。
- 参数:
n – 训练向量的数量
x – 训练向量,大小为 n * d
-
void transform_transpose(idx_t n, const float *y, float *x) const
如果 A 具有标准正交线,则计算 x = A^T * (x - b) 是反向变换
-
virtual void reverse_transform(idx_t n, const float *xt, float *x) const override
仅当 is_orthonormal 为真时有效。
-
void set_is_orthonormal()
计算 A^T * A 来设置 is_orthonormal 标志。
-
virtual void check_identical(const VectorTransform &other) const override
公共成员
-
int M
子量化器的数量
-
int niter = 50
外部训练迭代的次数。
-
int niter_pq = 4
PQ 的训练迭代次数。
-
int niter_pq_0 = 40
对于第一个外部迭代,同样适用
-
size_t max_train_points = 256 * 256
如果训练点过多,则重新采样
-
bool verbose = false
-
ProductQuantizer *pq = nullptr
如果非 NULL,使用这个乘积量化器进行训练,应使用 (d_out, M, _) 构建
-
bool have_bias
-
bool is_orthonormal
! 是否使用偏置项
检查矩阵 A 是否为正交矩阵 (启用 reverse_transform)
-
int d_in
-
int d_out
! 输入维度
-
bool is_trained
设置 VectorTransform 是否不需要训练,或者是否已经完成训练
-
explicit OPQMatrix(int d = 0, int M = 1, int d2 = -1)
-
struct RemapDimensionsTransform : public faiss::VectorTransform
- #include <VectorTransform.h>
为输入向量重新映射维度,可能插入 0。严格来说,这也是一种线性变换,但我们不想用矩阵乘法来计算它。
公共函数
-
RemapDimensionsTransform(int d_in, int d_out, const int *map)
-
RemapDimensionsTransform(int d_in, int d_out, bool uniform = true)
根据需要重新映射输入到输出,跳过或插入维度。如果 uniform: 均匀地分布维度,否则只取前 d_out 个。
-
virtual void apply_noalloc(idx_t n, const float *x, float *xt) const override
应用转换,并在提供的矩阵中返回结果
- 参数:
n – 要转换的向量的数量
x – 输入向量,大小为 n * d_in
xt – 输出向量,大小为 n * d_out
-
virtual void reverse_transform(idx_t n, const float *xt, float *x) const override
只有当映射是排列时,逆变换才是正确的
-
inline RemapDimensionsTransform()
-
virtual void check_identical(const VectorTransform &other) const override
-
RemapDimensionsTransform(int d_in, int d_out, const int *map)
-
struct NormalizationTransform : public faiss::VectorTransform
- #include <VectorTransform.h>
逐向量归一化
公共函数
-
explicit NormalizationTransform(int d, float norm = 2.0)
-
NormalizationTransform()
-
virtual void apply_noalloc(idx_t n, const float *x, float *xt) const override
应用转换,并在提供的矩阵中返回结果
- 参数:
n – 要转换的向量的数量
x – 输入向量,大小为 n * d_in
xt – 输出向量,大小为 n * d_out
-
virtual void check_identical(const VectorTransform &other) const override
-
explicit NormalizationTransform(int d, float norm = 2.0)
-
struct CenteringTransform : public faiss::VectorTransform
- #include <VectorTransform.h>
从向量中减去每个分量的平均值。
公共函数
-
explicit CenteringTransform(int d = 0)
-
virtual void check_identical(const VectorTransform &other) const override
-
explicit CenteringTransform(int d = 0)
-
struct VectorTransform