Следующий проект машинного обучения был завершен в рамках программы Data Scientist Nanodegree, которую я завершил в апреле 2020 года. Весь код можно найти на моем Github.

1. Введение

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

Во время проекта я создал CNN из Scatch и два CNN, используя технику Transfer Learning, используя разные архитектуры.

2. Исследование данных

Прежде чем мы углубимся в создание CNN, давайте сначала рассмотрим набор данных, предоставленный Udacity и имеющий следующее распределение.

There are 133 total dog categories.
There are 8351 total dog images.
There are 6680 training dog images.
There are 835 validation dog images.
There are 836 test dog images.

Чтобы исследовать изображения в наборе данных, я создал функцию для отображения изображения по индексу.

# Function to display image
def display_image(x):
    '''
    function shows images in training set
    INPUT: integer between 0 and 6680
    OUTPUT: image
    '''
    img = cv2.imread(train_files[x])
    cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.imshow(cv_rgb)
    plt.show()

См. Несколько примеров ниже.

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

Как видно на изображении выше, набор данных довольно хорошо распределяется среди 133 пород. Итак, когда мы тренируемся, у нас будет дальняя классификация.

3. Создайте CNN для классификации пород собак.

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

Итак, давайте погрузимся в код и продумаем код CNN с нуля. Мы собираемся использовать Keras в качестве нашей библиотеки для нейронной сети.

from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.models import Sequential
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, padding='same', activation='relu', input_shape=(224, 224, 3)))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=32, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(GlobalAveragePooling2D())
model.add(Dropout(0.15))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.15))
model.add(Dense(num_classes, activation='softmax'))
model.summary()
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

Я определил слой с тремя фильтрами со структурой 16,32,64 и с фильтром с максимальным объединением, чтобы уменьшить размерность данных. Я также использовал два слоя исключения и два плотных слоя, чтобы оптимизировать CNN и уменьшить изменения, связанные с переобучением.

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

Test accuracy: 7.7751%

Как и следовало ожидать, наша модель не сработала, но на то есть несколько причин. Во-первых, нам нужно понять, что нашему CNN сначала необходимо понять изображение, углы, размеры и части собак. Вот почему наша модель не сработала, нам, вероятно, придется улучшить наш набор данных и добавить еще много слоев. Но чем больше вы добавляете слоев, тем сложнее и время обучения увеличивается.

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

Модель VGG16

VGG16 - это модель сверточной нейронной сети, предложенная К. Симоняном и А. Зиссерманом из Оксфордского университета в статье Очень глубокие сверточные сети для распознавания крупномасштабных изображений. Модель достигает 92,7% точности тестов из топ-5 в ImageNet, который представляет собой набор данных из более чем 14 миллионов изображений, принадлежащих к 1000 классам. (Нейроулей)

VGG16_model = Sequential() VGG16_model.add(GlobalAveragePooling2D(input_shape=train_VGG16.shape[1:])) VGG16_model.add(Dense(133, activation='softmax'))  VGG16_model.summary()
VGG16_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

Test accuracy: 44.6172%

Используя эту предварительно обученную нейросеть, я ускоряюсь с 7% до 44%. Мы могли бы еще больше улучшить эти результаты, добавив новые слои и, если возможно, получив больше данных для улучшения результатов и точности.

Архитектура модели ResNet50

ResNet-50 - это сверточная нейронная сеть с 50-слойной глубиной. Вы можете загрузить предварительно обученную версию сети, обученную более чем на миллионе изображений из базы данных ImageNet. Предварительно обученная сеть может классифицировать изображения по 1000 категориям объектов, таким как клавиатура, мышь, карандаш и многие животные. (Mathworks)

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

resnet50_model = Sequential()
resnet50_model.add(GlobalAveragePooling2D(input_shape=train_resnet50.shape[1:]))
resnet50_model.add(Dense(133, activation='softmax'))
resnet50_model.summary()
resnet50_model.compile(loss='categorical_crossentropy', optimizer='nadam', metrics=['accuracy'])

После некоторых тестов с добавлением слоев, таких как фильтры, отсевы и другие, лучшая точность была достигнута путем добавления глобального среднего уровня объединения и плотного слоя, активированного с помощью SoftMax. По мере того, как средний пул уменьшает общее количество параметров, действие softmax лучше всего работает с несколькими классификациями.

Test accuracy: 82.1770%

ЗАКЛЮЧЕНИЕ

Мы смогли повысить точность нашей модели CNN с 7% до 82% с помощью трансферного обучения. Этот окончательный результат довольно хорош, для увеличения результатов, возможно, можно использовать некоторые другие методы, такие как увеличение данных, различные архитектуры модели или дополнительные данные для обучения.

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

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

Использовали ли вы какой-либо из этих методов? Или есть другие идеи?

Если вам понравился этот пост, пожалуйста, дайте ему несколько хлопков (вы можете оставить до 50) или вы можете прокомментировать, если у вас есть какие-либо вопросы, я сделаю все возможное отвечать! 🙌

Спасибо!