Вопрос или проблема
Я хочу обучить OneClassSVM() с помощью sklearn, и у меня есть набор из около 800 изображений в тренировочном наборе.
Я использую opencv для чтения изображений и изменения их размера до постоянных размеров (960×540), а затем добавляю их в массив numpy. Изображения RGB и, следовательно, имеют 3 измерения. Для этого я изменяю форму массива numpy после чтения всех изображений:
#Предположим, что X - это мой массив numpy, который содержит все изображения до изменения формы
#Теперь я изменяю форму X
n_samples = len(X)
X = X.reshape(n_samples, 950*540*3)
Как видите, количество признаков огромное (точно 1,539,000).
Теперь я пытаюсь обучить свою модель:
model = OneClassSVM(kernel="rbf", gamma=0.001)
model.fit(X)
После запуска моего кода он выдал ошибку MemoryError
. Если я не ошибаюсь, это очевидно из-за большого количества признаков? Есть ли способ предварительной обработки изображений перед подгонкой или уменьшения числа признаков?
Вам следует попробовать преобразовать их в главные компоненты с помощью PCA. Пожалуйста, обратитесь к этому Analytics Vidya PCA, это даст вам хорошее понимание.
PCA преобразует n больших векторов в p главных компонентов.
Первый главный компонент является линейной комбинацией оригинальных предсказательных переменных, которая захватывает максимальную дисперсию в наборе данных.
Второй главный компонент также является линейной комбинацией оригинальных предсказательных переменных, которая захватывает оставшуюся дисперсию. Все последующие следуют той же концепции.
Так вы можете выбрать топовые главные компоненты, которые достаточно хорошо объясняют совокупную дисперсию в ваших данных.
Один из подходов – использовать искусственную нейронную сеть для извлечения признаков, представляющих изображения. Это можно сделать либо с использованием заранее настроенной сети с предобученными весами и извлечением выхода одного из скрытых слоев, либо путем построения и обучения своей собственной сети для этой цели.
Использовать готовый предобученный модуль можно легко с помощью Keras и TensorFlow, где вы можете импортировать InceptionV3 или MobileNet с весами, предобученными на ImageNet, что даст вам 2048 или 1024 признаков на изображение соответственно.
Статья, обсуждающая такой подход, можно найти здесь. Надеюсь, это даст вам лучшую производительность, чем использование чего-то вроде PCA для уменьшения размерности.
Ответ или решение
Когда вы работаете с большими наборами изображений, такими как ваш набор из 800 изображений, и пытаетесь применить метод OneClassSVM из библиотеки sklearn, вы можете столкнуться с проблемами производительности из-за большого количества признаков. Размерность ваших изображений, равная 1,539,000 признаков (960x540x3), является слишком высокой для эффективной обработки, и это может привести к ошибке памяти (MemoryError). В этом ответе я предложу несколько методов предобработки, которые помогут вам уменьшить количество признаков и оптимизировать обучение вашей модели.
1. Применение главных компонент (PCA)
Один из наиболее распространенных методов уменьшения размерности, подходящий для данной задачи, – это метод главных компонент (PCA). PCA позволяет сократить количество признаков, сохранив при этом большую часть вариации данных.
Как использовать PCA:
- Прежде всего, библиотека scikit-learn предоставляет простой интерфейс для применения PCA:
from sklearn.decomposition import PCA
# Предположим, что X - это ваш массив изображений, уже преобразованный в двумерный формат
pca = PCA(n_components=0.95) # Сохраним 95% вариации
X_reduced = pca.fit_transform(X)
Этот код автоматически выберет количество компонент, необходимых для сохранения 95% вариации в данных. После этого вы сможете подать X_reduced
на вход модели OneClassSVM.
2. Извлечение признаков с помощью сверточных нейронных сетей (CNN)
Другой эффективный подход заключается в использовании предобученных сверточных нейронных сетей для извлечения признаков. Это позволяет вам извлекать более информативные характеристики из изображений.
Как использовать предобученные модели:
- Вы можете использовать библиотеки Keras или TensorFlow для этого. Например, вы можете воспользоваться архитектурой InceptionV3 или MobileNet, которые поставляются с предобученными весами на наборе данных ImageNet.
from keras.applications import MobileNet
from keras.applications.mobilenet import preprocess_input
from keras.models import Model
# Загружаем предобученную модель
base_model = MobileNet(weights='imagenet', include_top=False, pooling='avg')
# Извлечение признаков для каждой картинки
X_features = base_model.predict(preprocess_input(X)) # Не забудьте предпроцессировать данные
После того, как вы извлечете признаки, вы получите, например, 1024 признака для каждого изображения (размерность X_features будет (800, 1024)), что значительно упростит обучение модели OneClassSVM.
3. Использование методов агрегации или специальных стратегий выборки
Если PCA и извлечение признаков с помощью CNN не подходят, вы можете также рассмотреть возможности агрегации данных, такие как:
- Снижение разрешения изображений: Уменьшение разрешения изображений, например, до 480×270, чтобы сразу уменьшить размерность.
- Аугментация изображений: Используйте аугментацию для создания новых образцов изображения, забывая о некотором количестве оригинальных рисунков.
Заключение
Перед тем как начать обучение своей модели на основе OneClassSVM, важно тщательно предобработать изображения и уменьшить размерность признаков. Используйте PCA или извлечение признаков из предобученных нейросетей для значительного снижения размерности и улучшения производительности. Оба подхода не только помогут вам избежать проблем с памятью, но и повысят качество модели, что, в конечном счете, принесет лучшие результаты в ваших задачах анализа данных.