Udacity Nanodegree Capstone Project: Классификатор пород собак

RedDeveloper
08.03.2023 14:46
Udacity Nanodegree Capstone Project: Классификатор пород собак

Использование конволюционных нейронных сетей (CNN) для идентификации собак (и человеческих лиц) на изображениях и классификации по породам

Высокоуровневый обзор

Вы можете ознакомиться со скриптами проекта и данными на github .

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

Популярные области применения CNN включают: распознавание лиц, медицинскую визуализацию и диагностику, преобразование документов из изображений в текстовые файлы, биометрическую аутентификацию и даже автономное вождение.

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

С помощью CNN можно создавать алгоритмы для выполнения визуальных задач, которые могут оказаться сложными даже для человека - например, классификация пород собак.

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

Люди могут (осознанно или нет) использовать ряд идентифицируемых признаков, чтобы определить породу собаки. Мы можем думать о ее размере, окрасе, размере головы, чертах лица и т.д. CNN способна извлекать такие признаки, причем преимущество заключается в том, что нам даже не нужно указывать, что именно это за признаки.

Описание входных данных

Я использовал набор данных из 8351 изображения собак, содержащий собак 133 различных пород. Данные о собаках были использованы для создания трех различных подмножеств:

  • 6680 изображений тренировочное подмножество;
  • 835 подмножество проверки;
  • 836 изображений тестового подмножества.

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

Набор данных человеческих лиц, состоящий из 13233 человеческих лиц. Подмножество человеческих лиц было использовано для тестирования функции детектора лиц.

Цели проекта

В данном проекте CNN используются для:

  • Распознавать человеческие лица и собак на изображениях;
  • Классифицировать собак в соответствии с их породой - или человеческие лица в соответствии с породой, на которую они больше всего похожи.

Стратегия решения проблемы

Для того чтобы создать алгоритм классификации пород собак, мне необходимо:

  1. Импортировал данные изображений собак и изображений человеческих лиц;
  2. Использовал каскадные классификаторы на основе признаков Хаара для идентификации человеческих лиц на изображениях;
  3. Использовали ResNet50 для создания детектора собак;
  4. Создали CNN с нуля для классификации пород собак;
  5. Использование предварительно обученных узких мест VGG16 для создания CNN для классификации пород собак;
  6. использовали предварительно обученные узкие места модели ResNet50 для создания CNN для классификации пород собак;
  7. использовал CNN, созданную с помощью предварительно обученной модели ResNet50, для создания алгоритма классификации пород собак.

Ожидаемые результаты

Следуя вышеописанным шагам, мы должны создать алгоритм, который:

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

Метрики оценки

Точность использовалась для оценки эффективности моделей. Это стандартный метод для задач классификации, и поскольку мы имеем дело не с очень несбалансированной выборкой (см. ниже в исследовании данных), он не должен быть крайне необъективным. Точность рассчитывается как:

Точность использовалась для оценки эффективности моделей Это стандартный метод для задач

Исследовательский анализ данных

Данные об изображениях собак несколько несбалансированы по породам. Тем не менее, изображений каждой породы достаточно для проведения обучения CNN:

Данные об изображениях собак несколько несбалансированы по породам Тем не менее

Кроме того, распределение по набору данных, похоже, соответствует общему распределению.

Предварительная обработка данных

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

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

# import OpenCV
import cv2
# load image and remove color channels
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# load model
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt.xml')
# find faces in image
faces = face_cascade.detectMultiScale(gray)Tensorflow uses 4D tensors as input to CNNs, so images were:

Для обнаружения собак на изображениях использовалась ResNet50; для определения породы собак использовались признаки Resnet50 и VGG16 узкого места предварительно обученных CNN. Модели Keras CNN используют TensorFlow в качестве бэкенда - для этого в качестве входных данных требуются 4D тензоры. Таким образом, изображения были:

  1. Загружаются как изображения размером 224x224 пикселя с 3 цветовыми каналами (224,224,3);
  2. Преобразуется в 4D тензоры формата (1,224,224,3)
from keras.preprocessing import image 
from tqdm import tqdm
def path_to_tensor(img_path):
 # loads RGB image as PIL.Image.Image type
 img = image.load_img(img_path, target_size=(224, 224))
 # convert PIL.Image.Image type to 3D tensor with shape (224, 224, 3)
 x = image.img_to_array(img)
 # convert 3D tensor to 4D tensor with shape (1, 224, 224, 3) and return 4D tensor
 return np.expand_dims(x, axis=0)

При использовании предварительно обученных моделей ResNet50 или VGG16 узкие места для каждой модели извлекались с помощью 4D тензора.

# Function of the DogClassifierClass (check repo) 
# for extracting ResNet50 bottleneck features

    def __extract_Resnet50(self, tensor):
        '''
        Takes a tensor and extract Resnet50 bottleneck features.
        
        INPUT:
        tensor (numpy.ndarray) 4D image tensor.
        
        RETURNS:
        (numpy.ndarray) array of extracted bottleneck features for Resnet50        
        '''
        return ResNet50(weights='imagenet', include_top=False).predict(preprocess_input(tensor))

Моделирование

Я создал следующую пользовательскую CNN, используя:

  • Два слоя с нулевым заполнением, за которыми следуют слои свертки 2D - таким образом, мы имеем два слоя свертки без потери размера входного сигнала;
  • Еще одна свертка 2D с последующим слоем maxpooling2D, который уменьшает размер входных данных в два раза;
  • Слой flatten для преобразования входных данных в одномерный массив;
  • Плотный слой с активацией ReLu, отсев с вероятностью 0.2;
  • Плотный слой с активацией softmax с числом 133 (это число пород в обучающем множестве).
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
zero_padding2d_1 (ZeroPaddin (None, 226, 226, 3)       0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 224, 224, 32)      896       
_________________________________________________________________
zero_padding2d_2 (ZeroPaddin (None, 226, 226, 32)      0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 224, 224, 32)      9248      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 112, 112, 32)      0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 401408)            0         
_________________________________________________________________
dense_1 (Dense)              (None, 64)                25690176  
_________________________________________________________________
dropout_1 (Dropout)          (None, 64)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 133)               8645      
=================================================================
Total params: 25,708,965
Trainable params: 25,708,965
Non-trainable params: 0
_________________________________________________________________

Использованы модели трансферного обучения, обе использующие узкие места VGG16 и ResNet50:

  • слой GlobalAveragePooling с размером входа (1,2048) для модели ResNet50 и (1,512) для модели VGG16;
  • Плотный слой с активацией softmax с выходом 133.
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
global_average_pooling2d_13  (None, 2048)              0         
_________________________________________________________________
dense_14 (Dense)             (None, 133)               272517    
=================================================================
Total params: 272,517
Trainable params: 272,517
Non-trainable params: 0
_________________________________________________________________

Настройка гиперпараметров

Так как мы имеем дело с предварительно обученными моделями, а создание CNN "с нуля" не было целью проекта, поиск по сетке не использовался. Я пробовал использовать больше слоев в предварительно обученных CNN, но точность не улучшилась.

Результаты

Модели были протестированы на точность. Обратите внимание, что конечная точность может варьироваться от испытания к испытанию:

  • Пользовательская CNN: 2.6316%
  • VGG16: 44,0191%
  • ResNet: 81.6986%

Я также реализовал пользовательский класс DogBreedClasifier с методом classify() - код для использования класса находится как в блокноте jupyter, так и в отдельном файле DogBreedClassifier.py в репо проекта .

Я протестировал алгоритм на некоторых изображениях. Вот несколько примеров:

Я протестировал алгоритм на некоторых изображениях Вот несколько примеров
Я протестировал алгоритм на некоторых изображениях Вот несколько примеров
Я протестировал алгоритм на некоторых изображениях Вот несколько примеров
Я протестировал алгоритм на некоторых изображениях Вот несколько примеров
Я протестировал алгоритм на некоторых изображениях Вот несколько примеров

Заключение

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

Улучшение

Для улучшения алгоритма я бы предложил:

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

Благодарности

Этот проект является частью программы Udacity's Data Scientist Nanodegree Program. Данные, исходные коды и инструкции были предоставлены Udacity.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

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