Ограничение памяти при извлечении VLAD из SIFT-дескрипторов в VLFeat с Matlab

Я недавно спросил, как извлечь VLAD из SIFT дескрипторов в VLFeat с Matlab здесь.

Однако я сталкиваюсь с ограничениями памяти. У меня 64 ГБ оперативной памяти и 64 ГБ подкачки.

 all_descr = single([sift_descr{:}]);

... выдает ошибку памяти:

Запрошенный массив 128x258438583 (123,2 ГБ) превышает максимальный размер предпочтительного размера. Создание массивов, превышающих этот предел, может занять много времени и привести к тому, что MATLAB перестанет отвечать на запросы. См. Ограничение размера массива или панель настроек для получения дополнительной информации.

Как правильно извлечь VLAD, когда у нас очень большой тренировочный набор данных? Например, я мог бы установить подмножество SIFT дескрипторов перед запуском vl_kmeans, как это:

all_descr = single([sift_descr{1:100000}]);

Это работает в памяти, но как это повлияет на мои функции VLAD? Спасибо.

1 ответ

Решение

Основная проблема здесь не в том, как извлечь VLAD для такой матрицы: вы вычисляете вектор VLAD для каждого изображения, зацикливаясь на всех изображениях и вычисляя VLAD один за другим, то есть проблема с памятью там не возникает.,

Вам не хватает памяти, когда вы пытаетесь объединить SIFT дескрипторы всех изображений, чтобы сгруппировать их в визуальные слова, используя поиск ближайшего соседа:

all_descr = single([sift_descr{:}]);
centroids = vl_kmeans(all_descr, 64);

Самый простой способ, который я могу придумать, - это переключиться на собственный MATLAB. kmeans функция, которая входит в набор инструментов статистики и машинного обучения. Он поставляется с поддержкой Tall Arrays, то есть типа данных MATLAB для массивов, которые не помещаются в память.

Для этого вы можете сохранить дескрипторы SIFT каждого изображения в CSV-файл, используя 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 функция и преобразование его в tall, В результате будет table, ты можешь использовать table2array преобразовать его в высокий массив.

ds = datastore('sift/*.csv');
all_descriptors = table2array(tall(ds));

Наконец, вы можете позвонить kmeans работать на этом, и получить ваши центроиды

[~, centroids] = kmeans(all_descriptors, 64);

Теперь вы можете продолжить вычисление вектора VLAD как обычно.

Другие вопросы по тегам