Гайд Классификация изображений ( Нейросети )

https://qweme.dev
Пользователь
Статус
Оффлайн
Регистрация
25 Май 2022
Сообщения
165
Реакции[?]
87
Поинты[?]
21K
О чем гайд?
В этом руководстве я покажу вам, как создать датасет, обучить нейросеть на его основе и классифицировать изображения.

Что может классификация изображений?
Классификация изображений - это процесс, при котором нейросеть определяет, к какой категории относится данное изображение. В данном посте я буду анализировать качество ремонта квартир на основе фотографий.

Часть 1. Создание датасета изображений
Что такое датасет?
Датасет представляет собой набор изображений, связанных с какой-либо темой. Например, если у нас есть модель, различающая кошек и собак, то датасет будет содержать 1000 изображений кошек и 1000 изображений собак.
В данном случае мы собираем изображения плохих и хороших квартир, загружая их в соответствующие папки:
Код:
dataset
    bad -
        img1.jpg
        img2.jpg
        img3.jpg
        ...
    good -
        img1.jpg
        img2.jpg
        img3.jpg
        ...
Я создал небольшой датасет из 500 изображений на каждую категорию (для более точных результатов рекомендуется собрать более обширный датасет).

Часть 2. Обучение на основе готовой нейросети
Начнем с загрузки датасета из папки:
Python:
from datasets import load_dataset
dataset = load_dataset("imagefolder", data_dir="./dataset", split="train")
dataset = dataset.train_test_split(test_size=0.2)
Для обучения нейросети нужно разделить датасет на тренировочный и валидационный наборы. В данном случае 80% изображений используются для обучения, а остальные 20% для проверки качества обучения.

Затем определяем соответствие между метками и индексами:
Python:
label2id = {
    "bad": 0,
    "good": 1
}
id2label = {
    0: "bad",
    1: "good"
}
Далее загружаем готовую нейросеть для классификации изображений, например, google/vit-base-patch16-224
Python:
from transformers import AutoImageProcessor
checkpoint = "google/vit-base-patch16-224"
image_processor = AutoImageProcessor.from_pretrained(checkpoint)
Теперь создадим преобразования изображений, необходимые для обучения:
Python:
from torchvision.transforms import RandomResizedCrop, Compose, Normalize, ToTensor
normalize = Normalize(mean=image_processor.image_mean, std=image_processor.image_std)
# Это нормализующая трансформация. Она выполняет нормализацию значений пикселей изображения. Нормализация в данном контексте означает приведение значений пикселей к определенному диапазону с использованием средних значений и стандартных отклонений.

size = (
    image_processor.size["shortest_edge"]
    if "shortest_edge" in image_processor.size
    else (image_processor.size["height"], image_processor.size["width"])
)
_transforms = Compose([RandomResizedCrop(size), ToTensor(), normalize])

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

Применим преобразования к изображениям в датасете:
Python:
def transforms(examples):
    examples["pixel_values"] = [_transforms(img.convert("RGB")) for img in examples["image"]]
    del examples["image"]
    return examples
dataset = dataset.with_transform(transforms)
Этот код определяет функцию transforms, которая применяет ранее созданный набор трансформаций _transforms к каждому изображению в наборе данных. Каждое изображение преобразуется в формат RGB (если он ещё не в таком формате), затем проходит через последовательность трансформаций для обрезки, преобразования в тензор и нормализации. Полученные тензоры исходных значений пикселей заменяют изображения в исходном наборе данных. После этого исходные изображения удаляются из набора данных, и обновленный набор данных сохраняется в переменной dataset.

Загрузим необходимые компоненты для обучения:
Python:
import evaluate
from transformers import DefaultDataCollator
data_collator = DefaultDataCollator()
accuracy = evaluate.load("accuracy")
Мы создаем data_collator и подгружаем модель оценки нашей нейросети

Определим функцию вычисления метрик:
Python:
import numpy as np
def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    predictions = np.argmax(predictions, axis=1)
    return accuracy.compute(predictions=predictions, references=labels)
Этот код определяет функцию compute_metrics, которая используется для вычисления метрик оценки модели. Входными данными для этой функции является кортеж eval_pred, который содержит предсказания модели (predictions) и соответствующие метки (labels). Функция сначала преобразует предсказания модели в индексы классов с наибольшими значениями вероятности с помощью функции np.argmax(). Затем она вызывает какую функцию accuracy.compute(), передавая в неё предсказанные индексы классов и реальные метки. Эта функция вычисляет и возвращает значение точности модели на основе предсказаний и меток.

Загрузим модель классификации изображений и подготовим её к обучению:
Python:
from transformers import AutoModelForImageClassification
model = AutoModelForImageClassification.from_pretrained(
    checkpoint,
    ignore_mismatched_sizes=True,
    num_labels=2,
    id2label=id2label,
    label2id=label2id,
)
Перенесем модель на GPU:
Python:
model.to("cuda")
Подготовим аргументы для обучения:
Python:
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
    output_dir="flat-qweme-ai",
    remove_unused_columns=False,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=5e-5,
    per_device_train_batch_size=16,
    gradient_accumulation_steps=4,
    per_device_eval_batch_size=16,
    num_train_epochs=5,
    warmup_ratio=0.1,
    logging_steps=10,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
    push_to_hub=False,
)
output_dir:
Путь к каталогу, в который будут сохраняться файлы и результаты обучения модели.
remove_unused_columns:
Определяет, будут ли удалены неиспользуемые колонки из входных данных во время обучения.
evaluation_strategy:
Стратегия оценки модели, определяющая, когда выполнять процесс оценки на проверочных данных. Здесь установлено на "epoch", что означает выполнение оценки по завершении каждой эпохи обучения.
save_strategy:
Стратегия сохранения модели. Здесь установлено на "epoch", что означает сохранение модели по завершении каждой эпохи обучения.
learning_rate:
Скорость обучения (learning rate) - величина, определяющая, как быстро модель будет адаптироваться к данным.
per_device_train_batch_size:
Количество образцов (примеров) в пакете, которое будет использоваться для обучения на каждом устройстве.
gradient_accumulation_steps:
Количество шагов накопления градиентов перед выполнением обратного распространения ошибки. Это позволяет использовать более крупные пакеты для обучения при ограниченных ресурсах памяти.
per_device_eval_batch_size:
Количество образцов в пакете, используемом для оценки на каждом устройстве.
num_train_epochs:
Количество эпох обучения - сколько раз модель будет проходить через весь набор данных.
warmup_ratio:
Процент эпох, в течение которых будет выполняться "разогрев" (warm-up) оптимизатора перед тем, как начнется изменение скорости обучения.
logging_steps:
Через сколько шагов обучения производить вывод информации о процессе обучения и метриках.
load_best_model_at_end:
Определяет, будет ли лучшая модель автоматически загружена после завершения обучения.
metric_for_best_model:
Метрика, по которой будет выбрана лучшая модель для сохранения.


Запустим процесс обучения:
Python:
trainer = Trainer(
    model=model,
    args=training_args,
    data_collator=data_collator,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    tokenizer=image_processor,
    compute_metrics=compute_metrics,
)
trainer.train()

Часть 3. Оценка результатов
Для оценки результатов, используем следующий код:
Python:
from PIL import Image
from transformers import pipeline
pipe = pipeline("image-classification", model="flat-qweme-ai")
Протестируем модель на конкретном изображении:
Python:
result = pipe(Image.open("test.jpg"))
print("Results:", result)
1693149746175.png
 
Разработчик
Статус
Оффлайн
Регистрация
1 Сен 2018
Сообщения
1,598
Реакции[?]
880
Поинты[?]
114K
О чем гайд?
В этом руководстве я покажу вам, как создать датасет, обучить нейросеть на его основе и классифицировать изображения.

Что может классификация изображений?
Классификация изображений - это процесс, при котором нейросеть определяет, к какой категории относится данное изображение. В данном посте я буду анализировать качество ремонта квартир на основе фотографий.

Часть 1. Создание датасета изображений
Что такое датасет?
Датасет представляет собой набор изображений, связанных с какой-либо темой. Например, если у нас есть модель, различающая кошек и собак, то датасет будет содержать 1000 изображений кошек и 1000 изображений собак.
В данном случае мы собираем изображения плохих и хороших квартир, загружая их в соответствующие папки:
Код:
dataset
    bad -
        img1.jpg
        img2.jpg
        img3.jpg
        ...
    good -
        img1.jpg
        img2.jpg
        img3.jpg
        ...
Я создал небольшой датасет из 500 изображений на каждую категорию (для более точных результатов рекомендуется собрать более обширный датасет).

Часть 2. Обучение на основе готовой нейросети
Начнем с загрузки датасета из папки:
Python:
from datasets import load_dataset
dataset = load_dataset("imagefolder", data_dir="./dataset", split="train")
dataset = dataset.train_test_split(test_size=0.2)
Для обучения нейросети нужно разделить датасет на тренировочный и валидационный наборы. В данном случае 80% изображений используются для обучения, а остальные 20% для проверки качества обучения.

Затем определяем соответствие между метками и индексами:
Python:
label2id = {
    "bad": 0,
    "good": 1
}
id2label = {
    0: "bad",
    1: "good"
}
Далее загружаем готовую нейросеть для классификации изображений, например, google/vit-base-patch16-224
Python:
from transformers import AutoImageProcessor
checkpoint = "google/vit-base-patch16-224"
image_processor = AutoImageProcessor.from_pretrained(checkpoint)
Теперь создадим преобразования изображений, необходимые для обучения:
Python:
from torchvision.transforms import RandomResizedCrop, Compose, Normalize, ToTensor
normalize = Normalize(mean=image_processor.image_mean, std=image_processor.image_std)
# Это нормализующая трансформация. Она выполняет нормализацию значений пикселей изображения. Нормализация в данном контексте означает приведение значений пикселей к определенному диапазону с использованием средних значений и стандартных отклонений.

size = (
    image_processor.size["shortest_edge"]
    if "shortest_edge" in image_processor.size
    else (image_processor.size["height"], image_processor.size["width"])
)
_transforms = Compose([RandomResizedCrop(size), ToTensor(), normalize])

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

Применим преобразования к изображениям в датасете:
Python:
def transforms(examples):
    examples["pixel_values"] = [_transforms(img.convert("RGB")) for img in examples["image"]]
    del examples["image"]
    return examples
dataset = dataset.with_transform(transforms)
Этот код определяет функцию transforms, которая применяет ранее созданный набор трансформаций _transforms к каждому изображению в наборе данных. Каждое изображение преобразуется в формат RGB (если он ещё не в таком формате), затем проходит через последовательность трансформаций для обрезки, преобразования в тензор и нормализации. Полученные тензоры исходных значений пикселей заменяют изображения в исходном наборе данных. После этого исходные изображения удаляются из набора данных, и обновленный набор данных сохраняется в переменной dataset.

Загрузим необходимые компоненты для обучения:
Python:
import evaluate
from transformers import DefaultDataCollator
data_collator = DefaultDataCollator()
accuracy = evaluate.load("accuracy")
Мы создаем data_collator и подгружаем модель оценки нашей нейросети

Определим функцию вычисления метрик:
Python:
import numpy as np
def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    predictions = np.argmax(predictions, axis=1)
    return accuracy.compute(predictions=predictions, references=labels)
Этот код определяет функцию compute_metrics, которая используется для вычисления метрик оценки модели. Входными данными для этой функции является кортеж eval_pred, который содержит предсказания модели (predictions) и соответствующие метки (labels). Функция сначала преобразует предсказания модели в индексы классов с наибольшими значениями вероятности с помощью функции np.argmax(). Затем она вызывает какую функцию accuracy.compute(), передавая в неё предсказанные индексы классов и реальные метки. Эта функция вычисляет и возвращает значение точности модели на основе предсказаний и меток.

Загрузим модель классификации изображений и подготовим её к обучению:
Python:
from transformers import AutoModelForImageClassification
model = AutoModelForImageClassification.from_pretrained(
    checkpoint,
    ignore_mismatched_sizes=True,
    num_labels=2,
    id2label=id2label,
    label2id=label2id,
)
Перенесем модель на GPU:
Python:
model.to("cuda")
Подготовим аргументы для обучения:
Python:
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
    output_dir="flat-qweme-ai",
    remove_unused_columns=False,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=5e-5,
    per_device_train_batch_size=16,
    gradient_accumulation_steps=4,
    per_device_eval_batch_size=16,
    num_train_epochs=5,
    warmup_ratio=0.1,
    logging_steps=10,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
    push_to_hub=False,
)
output_dir:
Путь к каталогу, в который будут сохраняться файлы и результаты обучения модели.
remove_unused_columns:
Определяет, будут ли удалены неиспользуемые колонки из входных данных во время обучения.
evaluation_strategy:
Стратегия оценки модели, определяющая, когда выполнять процесс оценки на проверочных данных. Здесь установлено на "epoch", что означает выполнение оценки по завершении каждой эпохи обучения.
save_strategy:
Стратегия сохранения модели. Здесь установлено на "epoch", что означает сохранение модели по завершении каждой эпохи обучения.
learning_rate:
Скорость обучения (learning rate) - величина, определяющая, как быстро модель будет адаптироваться к данным.
per_device_train_batch_size:
Количество образцов (примеров) в пакете, которое будет использоваться для обучения на каждом устройстве.
gradient_accumulation_steps:
Количество шагов накопления градиентов перед выполнением обратного распространения ошибки. Это позволяет использовать более крупные пакеты для обучения при ограниченных ресурсах памяти.
per_device_eval_batch_size:
Количество образцов в пакете, используемом для оценки на каждом устройстве.
num_train_epochs:
Количество эпох обучения - сколько раз модель будет проходить через весь набор данных.
warmup_ratio:
Процент эпох, в течение которых будет выполняться "разогрев" (warm-up) оптимизатора перед тем, как начнется изменение скорости обучения.
logging_steps:
Через сколько шагов обучения производить вывод информации о процессе обучения и метриках.
load_best_model_at_end:
Определяет, будет ли лучшая модель автоматически загружена после завершения обучения.
metric_for_best_model:
Метрика, по которой будет выбрана лучшая модель для сохранения.


Запустим процесс обучения:
Python:
trainer = Trainer(
    model=model,
    args=training_args,
    data_collator=data_collator,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    tokenizer=image_processor,
    compute_metrics=compute_metrics,
)
trainer.train()

Часть 3. Оценка результатов
Для оценки результатов, используем следующий код:
Python:
from PIL import Image
from transformers import pipeline
pipe = pipeline("image-classification", model="flat-qweme-ai")
Протестируем модель на конкретном изображении:
Python:
result = pipe(Image.open("test.jpg"))
print("Results:", result)
Наш канал
Пожалуйста, авторизуйтесь для просмотра ссылки.
( noad )

Посмотреть вложение 257206
Статья неплохая, но многие вещи не обьясняются, работает по принципу "делай так потому что оно работает".
Чем-то напоминает начало fastbook от fastai -
Пожалуйста, авторизуйтесь для просмотра ссылки.


UPD: дополню:

Теперь создадим преобразования изображений, необходимые для обучения:
Python:
from torchvision.transforms import RandomResizedCrop, Compose, Normalize, ToTensor
normalize = Normalize(mean=image_processor.image_mean, std=image_processor.image_std)
# Это нормализующая трансформация. Она выполняет нормализацию значений пикселей изображения. Нормализация в данном контексте означает приведение значений пикселей к определенному диапазону с использованием средних значений и стандартных отклонений.

size = (
    image_processor.size["shortest_edge"]
    if "shortest_edge" in image_processor.size
    else (image_processor.size["height"], image_processor.size["width"])
)
_transforms = Compose([RandomResizedCrop(size), ToTensor(), normalize])

# ToTensor()
# Преобразует входное изображение в формат тензора PyTorch. Тензоры PyTorch - это многомерные массивы, которые могут быть использованы для обработки данных нейронными сетями.
Этот код изменяет случайным образом размер и область изображения, затем превращает его в формат, понимаемый компьютером, и, делает яркость изображения более равномерной, чтобы подготовить его для использования в нейронных сетях.
Тут вот не объясняется, почему мы случайным образом изменяем изображения, расширяя набор данных. Стоило бы добавить название для этого процесса: "Data augmentation"
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
30 Май 2019
Сообщения
46
Реакции[?]
6
Поинты[?]
0
https://qweme.dev
Пользователь
Статус
Оффлайн
Регистрация
25 Май 2022
Сообщения
165
Реакции[?]
87
Поинты[?]
21K
Статья неплохая, но многие вещи не обьясняются, работает по принципу "делай так потому что оно работает".
Чем-то напоминает начало fastbook от fastai -
Пожалуйста, авторизуйтесь для просмотра ссылки.
Спасибо за отзыв, это был первый материал, в следующих учту
Статья неплохая, но многие вещи не обьясняются, работает по принципу "делай так потому что оно работает".
Чем-то напоминает начало fastbook от fastai -
Пожалуйста, авторизуйтесь для просмотра ссылки.


UPD: дополню:


Тут вот не объясняется зачем мы случайно модифицируем изображение, стоило бы добавить и название подобного процесса - "Data augmentation"
Этот код изменяет случайным образом размер и область изображения, затем превращает его в формат, понимаемый компьютером, и, делает яркость изображения более равномерной, чтобы подготовить его для использования в нейронных сетях.
 
Разработчик
Статус
Оффлайн
Регистрация
1 Сен 2018
Сообщения
1,598
Реакции[?]
880
Поинты[?]
114K
Спасибо за отзыв, это был первый материал, в следующих учту

Этот код изменяет случайным образом размер и область изображения, затем превращает его в формат, понимаемый компьютером, и, делает яркость изображения более равномерной, чтобы подготовить его для использования в нейронных сетях.
Ну вот, зачем он это делает? Ему нравится так делать, или что? Почему так делают? По всей статье раскидываются подобные вопросы, но в целом неплохо
 
Начинающий
Статус
Оффлайн
Регистрация
10 Май 2019
Сообщения
19
Реакции[?]
22
Поинты[?]
2K
Ну вот, зачем он это делает? Ему нравится так делать, или что? Почему так делают? По всей статье раскидываются подобные вопросы, но в целом неплохо
Случайное изменение изображений, также известное как data augmentation, является распространенной техникой, используемой в машинном обучении для увеличения разнообразия обучающих данных без фактического сбора новых данных. Вот причины, по которым она часто используется: - Избежать чрезмерной подгонки: Переподгонка возникает в том случае, когда модель машинного обучения настолько хорошо усваивает обучающие данные, что плохо работает на неизвестных данных (валидационных и тестовых наборах). Случайное изменение изображений позволяет модели видеть "новые" данные в каждый период времени, что помогает предотвратить переобучение, улучшая обобщающие способности модели. - Увеличение размера набора данных: Для эффективного обучения моделей глубокого обучения часто требуется большой объем данных. Если исходный набор данных невелик, то расширение данных позволяет искусственно увеличить его размер, предоставляя модели больше данных для обучения. - Повышение устойчивости модели: Внесение случайных преобразований, таких как повороты, переводы, переворачивания и т.д., повышает устойчивость модели к изменениям входных данных. Это означает, что модель будет лучше справляться с вариациями данных в реальном мире. - Более эффективное обучение признаков: Каждое преобразование может помочь модели узнать больше дискриминационных признаков. Например, если мы переворачиваем изображение, то модель должна распознать, что перевернутый объект - это то же самое, что и оригинал, что может способствовать лучшему обучению признаков. Преобразования, которые вы используете в своем коде, такие как RandomResizedCrop и Normalize, являются обычными методами, применяемыми при расширении данных по причинам, описанным выше. RandomResizedCrop произвольно обрезает и изменяет размер изображений, а Normalize помогает стандартизировать данные, повышая стабильность обучения и скорость сходимости.
 
Сверху Снизу