scikit-Learn PCA для набора данных изображений - PullRequest
0 голосов
/ 17 мая 2019

Я пытаюсь выполнить PCA для набора данных изображений с 100 000 изображений размером 224x224x3.

Я надеялся спроецировать изображения в пространство измерения 1000 (или где-то около этого).

Я делаю это на своем ноутбуке (16 Гб оперативной памяти, i7, без графического процессора) и уже установлен svd_solver = 'randomized' .

Однако примерка длится вечно. Набор данных и размер изображения слишком велики или есть какой-то трюк, который я мог бы использовать?

Спасибо!

Edit:

Это код:

pca = PCA(n_components=1000, svd_solver='randomized')
pca.fit(X)
Z = pca.transform(X)

X - это матрица размером 100000 x 150528, строки которой представляют сплющенное изображение.

Ответы [ 3 ]

1 голос
/ 22 мая 2019

Вы должны действительно пересмотреть свой выбор уменьшения размерности, если считаете, что вам нужно 1000 основных компонентов. Если у вас их так много, то у вас больше нет возможности интерпретации, поэтому вы также можете использовать другие и более гибкие алгоритмы уменьшения размерности (например, вариационные autencoders, t-sne, kernel-PCA). Ключевым преимуществом PCA является интерпретируемость основных компонентов.

Если у вас есть видеопоток того же места, то у вас должно быть в порядке <10 компонентов (хотя поиск основных компонентов может быть лучше). Более того, если ваш набор данных изображений не состоит из похожих изображений, то PCA, вероятно, не является правильным выбором. </p>

Кроме того, для изображений может лучше подойти факторизация неотрицательной матрицы (NMF). Для NMF вы можете выполнить стохастическую оптимизацию градиента, сэмплируя как пиксели, так и изображения для каждого шага градиента.

Однако, если вы все еще настаиваете на выполнении PCA, то я думаю, что рандомизированный решатель, предоставленный Facebook, является лучшим вариантом, который у вас есть. Запустите pip install fbpca и введите следующий код

from fbpca import pca

# load data into X
U, s, Vh = pca(X, 1000)

Невозможно получить быстрее, чем это без использования какой-либо структуры матрицы, например, разреженность или состав блоков (что вряд ли будет в вашем наборе данных).

Кроме того, если вам нужна помощь, чтобы выбрать правильное количество основных компонентов, я рекомендую использовать этот код

import fbpca
from bisect import bisect_left

def compute_explained_variance(singular_values):
    return np.cumsum(singular_values**2)/np.sum(singular_values**2)

def ideal_number_components(X, wanted_explained_variance):
    singular_values = fbpca.svd(X, compute_uv=False)  # This line is a bottleneck. 
    explained_variance = compute_explained_variance(singular_values)
    return bisect_left(explained_variance, wanted_explained_variance)

def auto_pca(X, wanted_explained_variance):
    num_components = ideal_number_components(X, explained_variance)
    return fbpca.pca(X, num_components)    # This line is a bottleneck if the number of components is high

Конечно, приведенный выше код не поддерживает перекрестную проверку, которую вы действительно должны использовать, чтобы выбрать правильное количество компонентов.

0 голосов
/ 17 мая 2019

попробуйте поэкспериментировать с iterated_power параметром PCA

0 голосов
/ 17 мая 2019

Вы можете попробовать установить

svd_solver="svd_solver"

Обучение должно быть намного быстрее. Вы также можете попробовать использовать:

from sklearn.decomposition import FastICA

Что является более масштабируемым В крайнем случае можно было бы превратить ваши изображения черно-белые , чтобы уменьшить размерность на 3, это может быть хорошим шагом, если ваша задача не является цветочувствительной (например, Оптическое распознавание символов)

...