У меня есть 32 тысячи черно-белых изображений. Хочу сделать кластеризацию на них.

Вопрос или проблема

Как говорит заголовок, я пытаюсь провести кластеризацию на наборе черно-белых изображений. Эти изображения все 200×200 с черными точками на белом фоне Примеры изображений здесь (это не реальные фотографии из набора данных. Просто общее представление о том, как они выглядят). Идея заключается в том, чтобы, возможно, найти основную закономерность, касающуюся общей формы этих изображений, и, надеюсь, кластеризовать по этому критерию.

Что я сделал до сих пор, так это преобразовал каждое из своих изображений 200 x 200 в массив numpy размером 40,000. Затем я собрал все изображения вместе в один массив numpy размером 32k x 40k.

Я немного не уверен, что делать дальше. Что я сделал следующим, так это использовал TruncateSVD из scikit learn на моем наборе данных и установил параметр ‘n_components=100’ и подогнал и преобразовал его, так что теперь мой набор данных изображений составляет 32k x 100.

С этого момента я не знаю, какой лучший план действий. Должен ли я просто начать использовать алгоритмы k_means на моем наборе данных? И как бы я это визуализировал?

Извините, если это слишком много. Любая помощь/советы будут очень appreciated.

Так как размерность ваших данных очень велика (40000), вы можете попробовать использовать Spherical K-Means на ваших сырых данных. Он использует косинусное сходство для вычисления расстояния между 2 точками. Действительно, евклидово расстояние не так уж информативно в векторных пространствах высокой размерности из-за проклятия размерности. Посмотрите https://stats.stackexchange.com/questions/99171/why-is-euclidean-distance-not-a-good-metric-in-high-dimensions

Или вы можете применить стратегию снижения размерности, такую как усеченное SVD или ACP, как вы сделали, а затем применить классический алгоритм k-means. Так что да, вы должны попробовать применить k-means к вашим данным с 100 размерностями. Может быть, попробуйте с k = 30 или чем-то подобным, так как 100 может быть уже слишком много.

Для кластеризации изображений я не советую вам сразу начинать с кластерных техник. Сначала запустите модель снижения размерности.

Самая мощная техника снижения размерности представлена Автоэнкодерами. Если вы знакомы с глубоким обучением, используйте автоэнкодеры для генерации сжатых, плотных представлений изображений. В качестве альтернативы вы можете использовать “более легкие” модели, такие как PCA, kernel-PCA или какую-либо технику обучения многообразий.

Этот первый шаг имеет преимущество в снижении шума, мультиколлинеарности и разреженности в ваших данных. Что более важно, он может спасти вас от проклятия размерности.

Как только вы сожмете оригинальные данные, я предлагаю вам запустить кластеризацию k-Means (или другую технику, если вы предпочитаете). Его результаты будут гораздо более значимыми и легкими для интерпретации.

Используя предобученную модель (например, VGG16) и извлекая признаки, можно провести кластеризацию изображений. Также смотрите этот пост на SO.

# Импорт
from keras.preprocessing import image
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
import numpy as np
from sklearn.cluster import KMeans
import os, shutil, glob, os.path
from PIL import Image as pil_image
image.LOAD_TRUNCATED_IMAGES = True 
model = VGG16(weights="imagenet", include_top=False)

# Переменные
imdir="C:/indir/" # Папка с изображениями
targetdir = "C:/outdir/" # Папка для копирования кластеризованных изображений
number_clusters = 10

# Цикл по файлам и получение признаков
filelist = glob.glob(os.path.join(imdir, '*.jpg'))
filelist.sort()
featurelist = []
for i, imagepath in enumerate(filelist):
    try:
        print("    Статус: %s / %s" %(i, len(filelist)), end="\r")
        img = image.load_img(imagepath, target_size=(224, 224))
        img_data = image.img_to_array(img)
        img_data = np.expand_dims(img_data, axis=0)
        img_data = preprocess_input(img_data)
        features = np.array(model.predict(img_data))
        featurelist.append(features.flatten())
    except:
        continue

# Кластеризация
kmeans = KMeans(n_clusters=number_clusters, random_state=0).fit(np.array(featurelist))

# Копирование изображений с переименованием по кластеру 
# Проверка, существует ли целевая папка
try:
    os.makedirs(targetdir)
except OSError:
    pass
# Копирование с именем кластера
print("\n")
for i, m in enumerate(kmeans.labels_):
    try:
        print("    Копирование: %s / %s" %(i, len(kmeans.labels_)), end="\r")
        shutil.copy(filelist[i], targetdir + str(m) + "_" + str(i) + ".jpg")
    except:
        continue

Ответ или решение

Согласно вашему запросу относительно кластеризации 32 тысяч черно-белых изображений размером 200×200 пикселей, позвольте предложить вам комплексный подход, который включает несколько этапов. Этот подход поможет вам аналитику выявить шаблоны и структуры, которые могут быть полезны для дальнейшего анализа.

1. Подготовка данных

Вы уже преобразовали каждое изображение в массив NumPy, что является разумным шагом. Тем не менее, перед тем как приступать к кластеризации, имеет смысл изучить данные более глубоко. Ваша матрица имеет размерность 32,000 x 40,000, что может затруднить эффективность алгоритмов кластеризации. Поэтому необходимо рассмотреть методы снижения размерности данных.

1.1 Снижение размерности

Вы уже попробовали использовать Truncated SVD, что является хорошим началом. Однако, также рекомендую вам попробовать Автокодировщики. Это более продвинутый метод, который подходит для изображений, так как он может эффективно извлекать важные признаки, сохраняя при этом структурную целостность данных. Autoencoder может помочь уменьшить размерность и выделить ключевые особенности в ваших изображениях.

Пример кода для автокодировщика

from keras.models import Model
from keras.layers import Input, Dense

input_img = Input(shape=(40000,))
encoded = Dense(1000, activation='relu')(input_img)
encoded = Dense(500, activation='relu')(encoded)
encoded = Dense(100, activation='relu')(encoded)

decoded = Dense(500, activation='relu')(encoded)
decoded = Dense(1000, activation='relu')(decoded)
decoded = Dense(40000, activation='sigmoid')(decoded)

autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')

# Обучение автокодировщика
autoencoder.fit(images, images, epochs=50, batch_size=256, shuffle=True)

После того как автокодировщик будет обучен, используйте его для извлечения признаков и преобразуйте ваши изображения в 32,000 x 100.

2. Кластеризация

Теперь, когда у вас есть выделенные признаки, вы можете перейти к кластеризации. Рекомендуется использовать K-Means – это один из самых популярных алгоритмов для решения задач кластеризации.

2.1 Настройка K-Means

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

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=20, random_state=0).fit(reduced_data)

3. Визуализация результатов

Для визуализации результатов кластеризации можно использовать методы, такие как t-SNE или PCA для проекции данных обратно в 2D пространство. Это поможет увидеть распределение и структуры среди кластеров.

import matplotlib.pyplot as plt
from sklearn.manifold import TSNE

tsne = TSNE(n_components=2)
reduced_tsne = tsne.fit_transform(reduced_data)

plt.scatter(reduced_tsne[:, 0], reduced_tsne[:, 1], c=kmeans.labels_)
plt.title('t-SNE visualization of clustered data')
plt.show()

4. Дополнительные методы

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

Заключение

Таким образом, процесс кластеризации ваших 32,000 изображений можно рассматривать как пошаговую задачу, начинающуюся с подготовки данных, затем следует снижение размерности, а затем применение алгоритмов кластеризации. Не забудьте визуализировать результаты, чтобы проанализировать полученные группы более глубоко. Выделение характерных признаков и использование сложных методов может привести к более успешной кластеризации.

Оцените материал
Добавить комментарий

Капча загружается...