Как преобразовать изображения (.jpg) в векторные для классификации изображений

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

В настоящее время я работаю над проектом, который включает классификацию изображений как изображений собак или кошек. Интерес заключается в том, что я хочу сделать это без использования сверточных нейронных сетей, в основном потому, что я пока не совсем их понимаю и не хочу просто копировать чей-то код с Github.

Я знаю, что алгоритмы классификации в Sci-Kit Learn требуют, чтобы данные на входе x были в векторизованной форме, чтобы классификатор мог соответствовать данным, но я не уверен, как это сделать. Легко сделать это с текстовыми данными (feature_selection.text.CountVectorizer/TfidfVectorizer), но я понятия не имею, как это работает с изображениями. Как я могу преобразовать файлы изображений .jpg в векторы/матрицы, чтобы модели на SK-Learn это поняли?

Заранее спасибо, и прошу прощения, если это глупый вопрос.

Вы можете использовать функцию imread из библиотеки imageio с np.array из numpy:

from imageio import imread
import numpy as np
filename="/path/to/dog.jpg"
vectorized_picture = np.array(imread(filename))

При вводе этих данных в ML-движок, вам, вероятно, потребуется преобразовать их в столбиковую матрицу (по крайней мере, в курсе машинного обучения от профессора Эндрю Нга на Coursera, который я прохожу). Если так, вы можете это сделать следующим образом:

reshaped_vectorized_picture = vectorized_picture.reshape(1, -1).T

Вам нужно установить обе библиотеки через apt, brew или pip (предпочтительный вариант)

pip install numpy imageio

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

Но это работает по-другому с точки зрения изображений. Изображение — это не что иное, как двумерный массив значений его пикселей. Если у вас есть цветное изображение размером 512×512, это не что иное, как массив формы 512x512x3 (3 обозначает цветовой канал) со значениями от 0 до 255.

Вы можете извлечь это, считав через библиотеки, такие как opencv, imageio, PIL и т.д.

Я использую модуль skimage, вы можете импортировать его следующим образом:

from skimage import data

Вы можете импортировать изображение в одну переменную следующим образом:

picture_imported = imageio.imread('picture.jpg')

Но эта переменная является imageio.core.util.Array. Чтобы получить это как ndarray, просто:

picture = np.copy(picture_imported)

Изображение содержит в себе некоторые значения. Предположим, на изображении человек стоит перед деревом, поэтому мы можем сказать, что каждый объект определяется разными значениями, предположим, для дерева значение присваивается 1, для человека — 2, а для фона — 0. Однако это только для примера, в действительности значения варьируются от 0 до 255 для каждого пикселя для черно-белого изображения, и для RGB-изображения существует 3 канала.

Эти значения пикселей обозначают интенсивность пикселей. Меньшие числа, ближе к нулю, представляют более темные оттенки, а большие числа, ближе к 255, представляют более светлые или белые оттенки. (Если честно, я тоже не знаю, как эти значения назначаются, но можем предполагать).

После всего этого мы выполняем нормализацию каждого пикселя (масштабирование данных в диапазон 0-1 называется нормализацией). Масштабирование пикселей в диапазоне от 0 до 1 можно сделать, установив аргумент rescale путем деления максимального значения пикселя на минимальное значение пикселя: 1/255 = 0.0039.

И, насколько я понимаю, после получения наших масштабированных значений эти значения используются как векторы для выполнения дальнейших операций, таких как вычисления со сверточными слоями и т.д.
…..исправьте меня, если я ошибаюсь…

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

Преобразование изображений в векторную форму представляет собой важный шаг в задаче классификации изображений, особенно если вы работаете с библиотеками машинного обучения, такими как Sci-Kit Learn, которые ожидают в качестве входных данных векторы определенной формы. Задача, стоящая перед вами, заключается в классификации изображений как "собака" или "кошка", при этом вы хотите обойтись без использования сверточных нейронных сетей (CNN). Рассмотрим подробно, как можно преобразовать изображения в векторы для использования в алгоритмах Sci-Kit Learn.

Теоретическая основа

Изображение представляет собой двумерный массив чисел, где каждое число в массиве соответствует интенсивности пикселя. Для цветных изображений каждый пиксель имеет три значения, представляющие цветовые каналы — красный, зеленый и синий (RGB). Эти значения, как правило, находятся в диапазоне от 0 до 255.

Преобразование изображения в вектор предполагает развертывание этого двумерного массива в одномерный вектор. Например, у изображения размером 64×64 пикселя будет 4096 пиксельных значений для черно-белого изображения, или 12288 (4096×3) для цветного изображения. Векторизация позволяет алгоритмам машинного обучения интерпретировать каждый пиксель (и, следовательно, всю картинку) как числовую характеристику объекта.

Пример реализации

Рассмотрим пример использования Python и библиотеки NumPy для векторизации изображения:

from imageio import imread
import numpy as np

filename = "/path/to/dog.jpg"
# Считывание изображения
image = imread(filename)
# Проверяем размерность изображения
print("Image shape:", image.shape)
# Если изображение цветное, преобразуем его в серый формат (опция)
if len(image.shape) == 3:
    # Превращаем цветное изображение в чёрно-белое (серое)
    image = np.mean(image, axis=2).astype('int')

# Векторизуем изображение
vectorized_image = image.flatten()

print("Vector shape:", vectorized_image.shape)

В коде выше изображение сначала загружается с помощью функции imread из библиотеки imageio. Затем, в зависимости от формата, оно может быть преобразовано в серый, чтобы уменьшить размерность (например, из 64x64x3 в 64×64). После чего применяется метод flatten(), чтобы развернуть массив в одномерный вектор.

Применение на практике

Подготовленный вектор можно использовать в качестве входных данных для любого алгоритма машинного обучения, поддерживаемого Sci-Kit Learn, например, дерева решений, SVM, случайного леса и других. Основное внимание следует уделить предварительной обработке данных, чтобы улучшить характеристики векторов для классификации.

Нормализация

Рекомендуется нормализовать данные путем приведения их к диапазону от 0 до 1. Это можно сделать путем деления всех значений пикселей на 255. Нормализация упрощает задачу алгоритмам машинного обучения, поскольку устраняет шкалу различных характеристик:

# Нормализация пикселей
normalized_vector = vectorized_image / 255.0

Пример использования с Sci-Kit Learn

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

from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score

# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=42)

# Создаем и обучаем модель
model = SVC(kernel='linear')
model.fit(X_train, y_train)

# Предсказание и проверка точности
predictions = model.predict(X_test)
accuracy = accuracy_score(y_test, predictions)

print(f"Accuracy: {accuracy:.2f}")

Заключение

Процесс векторизации изображений относительно прост, если рассматривать их как набор числовых данных. Идея состоит в том, чтобы эффективно преобразовать пространственную информацию в удобоваримую форму для алгоритмов машинного обучения. Отказ от использования CNN вынуждает искать традиционные подходы, такие как обработка вручную полученных векторных значений. Это весьма полезно для понимания основ и ключевых процессов в машинном обучении, что важно для любого специалиста в области данных.

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

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