使用 Matlab 从 VLFeat 中的 SIFT 描述符中提取 VLAD 时的内存限制
Memory Limitation when Extracting VLAD from SIFT Descriptors in VLFeat with Matlab
我最近询问如何使用 Matlab 从 VLFeat 中的 SIFT 描述符中提取 VLAD。
但是,我 运行 遇到内存限制。我有 64GB 内存和 64GB 交换空间。
all_descr = single([sift_descr{:}]);
... 产生内存错误:
Requested 128x258438583 (123.2GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a
long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information.
当我们有一个非常大的训练数据集时,提取 VLAD 的正确方法是什么?例如,我可以在 运行 vl_kmeans
之前对 SIFT 描述符进行子集化,如下所示:
all_descr = single([sift_descr{1:100000}]);
这在内存中有效,但它将如何影响我的 VLAD 功能?谢谢你。
这里的主要问题不是如何为这样的矩阵提取VLAD:你通过遍历所有图像并逐个计算VLAD来计算每个图像的VLAD向量,即内存问题那里没有出现。
当您尝试连接所有图像的 SIFT 描述符以使用最近邻搜索将它们聚类为视觉词时,您 运行 内存不足:
all_descr = single([sift_descr{:}]);
centroids = vl_kmeans(all_descr, 64);
我能想到的最简单的方法是切换到 MATLAB 自己的 kmeans
函数,它包含在 Statistics and Machine Learning 工具箱中。
它支持 Tall Arrays,即 MATLAB 的数据类型,用于不适合内存的数组。
为此,您可以使用 csvwrite
:
将每个图像的 SIFT 描述符保存到 CSV 文件中
for k = 1:size(filelist, 1)
I = imread([repo filelist(k).name]) ;
I = single(rgb2gray(I)) ;
[f,d] = vl_sift(I) ;
csvwrite(sprintf('sift/im_%d.csv', k), single(d.'));
end
然后,您可以使用 datastore
function and converting it to tall
将描述符加载为 Tall 数组。由于结果将是 table
,您可以使用 table2array
将其转换为 tall 数组。
ds = datastore('sift/*.csv');
all_descriptors = table2array(tall(ds));
最后,您可以调用 kmeans
函数,并获取质心
[~, centroids] = kmeans(all_descriptors, 64);
现在您可以照常计算 VLAD 向量了。
我最近询问如何使用 Matlab
但是,我 运行 遇到内存限制。我有 64GB 内存和 64GB 交换空间。
all_descr = single([sift_descr{:}]);
... 产生内存错误:
Requested 128x258438583 (123.2GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information.
当我们有一个非常大的训练数据集时,提取 VLAD 的正确方法是什么?例如,我可以在 运行 vl_kmeans
之前对 SIFT 描述符进行子集化,如下所示:
all_descr = single([sift_descr{1:100000}]);
这在内存中有效,但它将如何影响我的 VLAD 功能?谢谢你。
这里的主要问题不是如何为这样的矩阵提取VLAD:你通过遍历所有图像并逐个计算VLAD来计算每个图像的VLAD向量,即内存问题那里没有出现。
当您尝试连接所有图像的 SIFT 描述符以使用最近邻搜索将它们聚类为视觉词时,您 运行 内存不足:
all_descr = single([sift_descr{:}]);
centroids = vl_kmeans(all_descr, 64);
我能想到的最简单的方法是切换到 MATLAB 自己的 kmeans
函数,它包含在 Statistics and Machine Learning 工具箱中。
它支持 Tall Arrays,即 MATLAB 的数据类型,用于不适合内存的数组。
为此,您可以使用 csvwrite
:
for k = 1:size(filelist, 1)
I = imread([repo filelist(k).name]) ;
I = single(rgb2gray(I)) ;
[f,d] = vl_sift(I) ;
csvwrite(sprintf('sift/im_%d.csv', k), single(d.'));
end
然后,您可以使用 datastore
function and converting it to tall
将描述符加载为 Tall 数组。由于结果将是 table
,您可以使用 table2array
将其转换为 tall 数组。
ds = datastore('sift/*.csv');
all_descriptors = table2array(tall(ds));
最后,您可以调用 kmeans
函数,并获取质心
[~, centroids] = kmeans(all_descriptors, 64);
现在您可以照常计算 VLAD 向量了。