8 min read

Распознавание объектов (Object Detection)

Распознавание объектов (Object Detection)
Фото: Enguerrand Blanchy / Unsplash

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

Давайте посмотрим, как задача решается с помощью Tensorflow. Для начала импортируем необходимые библиотеки:

import tensorflow as tf
import matplotlib.pyplot as plt

Мы будем обучать нейронную сеть распознавать предметы одежды из Датасета (Dataset) под названием Fashion MNIST. Он содержит 70 000 предметов одежды в 10 различных категориях. Каждый предмет одежды представлен в виде изображения в оттенках серого 28x28. Вот примеры здесь:

Данные Fashion MNIST доступны непосредственно в API tf.keras. Загрузим их:

mnist = tf.keras.datasets.fashion_mnist

Разделим набор на Тренировочные (Train Data) и Тестовые данные (Test Data):

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

Как выглядят эти данные в понятном компьютеру табличном виде? Давайте выведем тренировочное изображение в виде таблицы пикселей с той или иной степенью белого по шкале от 0 до 255:

plt.imshow(training_images[0])
print(training_labels[0])
print(training_images[0])
[[0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.00392157 0.         0.         0.05098039 0.28627451 0.
  0.         0.00392157 0.01568627 0.         0.         0.
  0.         0.00392157 0.00392157 0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.01176471 0.         0.14117647 0.53333333 0.49803922 0.24313725
  0.21176471 0.         0.         0.         0.00392157 0.01176471
  0.01568627 0.         0.         0.01176471]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.02352941 0.         0.4        0.8        0.69019608 0.5254902
  0.56470588 0.48235294 0.09019608 0.         0.         0.
  0.         0.04705882 0.03921569 0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.60784314 0.9254902  0.81176471 0.69803922
  0.41960784 0.61176471 0.63137255 0.42745098 0.25098039 0.09019608
  0.30196078 0.50980392 0.28235294 0.05882353]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.00392157
  0.         0.27058824 0.81176471 0.8745098  0.85490196 0.84705882
  0.84705882 0.63921569 0.49803922 0.4745098  0.47843137 0.57254902
  0.55294118 0.34509804 0.6745098  0.25882353]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.00392157 0.00392157 0.00392157
  0.         0.78431373 0.90980392 0.90980392 0.91372549 0.89803922
  0.8745098  0.8745098  0.84313725 0.83529412 0.64313725 0.49803922
  0.48235294 0.76862745 0.89803922 0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.71764706 0.88235294 0.84705882 0.8745098  0.89411765
  0.92156863 0.89019608 0.87843137 0.87058824 0.87843137 0.86666667
  0.8745098  0.96078431 0.67843137 0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.75686275 0.89411765 0.85490196 0.83529412 0.77647059
  0.70588235 0.83137255 0.82352941 0.82745098 0.83529412 0.8745098
  0.8627451  0.95294118 0.79215686 0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.00392157 0.01176471 0.
  0.04705882 0.85882353 0.8627451  0.83137255 0.85490196 0.75294118
  0.6627451  0.89019608 0.81568627 0.85490196 0.87843137 0.83137255
  0.88627451 0.77254902 0.81960784 0.20392157]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.02352941 0.
  0.38823529 0.95686275 0.87058824 0.8627451  0.85490196 0.79607843
  0.77647059 0.86666667 0.84313725 0.83529412 0.87058824 0.8627451
  0.96078431 0.46666667 0.65490196 0.21960784]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.01568627 0.         0.
  0.21568627 0.9254902  0.89411765 0.90196078 0.89411765 0.94117647
  0.90980392 0.83529412 0.85490196 0.8745098  0.91764706 0.85098039
  0.85098039 0.81960784 0.36078431 0.        ]
 [0.         0.         0.00392157 0.01568627 0.02352941 0.02745098
  0.00784314 0.         0.         0.         0.         0.
  0.92941176 0.88627451 0.85098039 0.8745098  0.87058824 0.85882353
  0.87058824 0.86666667 0.84705882 0.8745098  0.89803922 0.84313725
  0.85490196 1.         0.30196078 0.        ]
 [0.         0.01176471 0.         0.         0.         0.
  0.         0.         0.         0.24313725 0.56862745 0.8
  0.89411765 0.81176471 0.83529412 0.86666667 0.85490196 0.81568627
  0.82745098 0.85490196 0.87843137 0.8745098  0.85882353 0.84313725
  0.87843137 0.95686275 0.62352941 0.        ]
 [0.         0.         0.         0.         0.07058824 0.17254902
  0.32156863 0.41960784 0.74117647 0.89411765 0.8627451  0.87058824
  0.85098039 0.88627451 0.78431373 0.80392157 0.82745098 0.90196078
  0.87843137 0.91764706 0.69019608 0.7372549  0.98039216 0.97254902
  0.91372549 0.93333333 0.84313725 0.        ]
 [0.         0.22352941 0.73333333 0.81568627 0.87843137 0.86666667
  0.87843137 0.81568627 0.8        0.83921569 0.81568627 0.81960784
  0.78431373 0.62352941 0.96078431 0.75686275 0.80784314 0.8745098
  1.         1.         0.86666667 0.91764706 0.86666667 0.82745098
  0.8627451  0.90980392 0.96470588 0.        ]
 [0.01176471 0.79215686 0.89411765 0.87843137 0.86666667 0.82745098
  0.82745098 0.83921569 0.80392157 0.80392157 0.80392157 0.8627451
  0.94117647 0.31372549 0.58823529 1.         0.89803922 0.86666667
  0.7372549  0.60392157 0.74901961 0.82352941 0.8        0.81960784
  0.87058824 0.89411765 0.88235294 0.        ]
 [0.38431373 0.91372549 0.77647059 0.82352941 0.87058824 0.89803922
  0.89803922 0.91764706 0.97647059 0.8627451  0.76078431 0.84313725
  0.85098039 0.94509804 0.25490196 0.28627451 0.41568627 0.45882353
  0.65882353 0.85882353 0.86666667 0.84313725 0.85098039 0.8745098
  0.8745098  0.87843137 0.89803922 0.11372549]
 [0.29411765 0.8        0.83137255 0.8        0.75686275 0.80392157
  0.82745098 0.88235294 0.84705882 0.7254902  0.77254902 0.80784314
  0.77647059 0.83529412 0.94117647 0.76470588 0.89019608 0.96078431
  0.9372549  0.8745098  0.85490196 0.83137255 0.81960784 0.87058824
  0.8627451  0.86666667 0.90196078 0.2627451 ]
 [0.18823529 0.79607843 0.71764706 0.76078431 0.83529412 0.77254902
  0.7254902  0.74509804 0.76078431 0.75294118 0.79215686 0.83921569
  0.85882353 0.86666667 0.8627451  0.9254902  0.88235294 0.84705882
  0.78039216 0.80784314 0.72941176 0.70980392 0.69411765 0.6745098
  0.70980392 0.80392157 0.80784314 0.45098039]
 [0.         0.47843137 0.85882353 0.75686275 0.70196078 0.67058824
  0.71764706 0.76862745 0.8        0.82352941 0.83529412 0.81176471
  0.82745098 0.82352941 0.78431373 0.76862745 0.76078431 0.74901961
  0.76470588 0.74901961 0.77647059 0.75294118 0.69019608 0.61176471
  0.65490196 0.69411765 0.82352941 0.36078431]
 [0.         0.         0.29019608 0.74117647 0.83137255 0.74901961
  0.68627451 0.6745098  0.68627451 0.70980392 0.7254902  0.7372549
  0.74117647 0.7372549  0.75686275 0.77647059 0.8        0.81960784
  0.82352941 0.82352941 0.82745098 0.7372549  0.7372549  0.76078431
  0.75294118 0.84705882 0.66666667 0.        ]
 [0.00784314 0.         0.         0.         0.25882353 0.78431373
  0.87058824 0.92941176 0.9372549  0.94901961 0.96470588 0.95294118
  0.95686275 0.86666667 0.8627451  0.75686275 0.74901961 0.70196078
  0.71372549 0.71372549 0.70980392 0.69019608 0.65098039 0.65882353
  0.38823529 0.22745098 0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.15686275 0.23921569 0.17254902 0.28235294 0.16078431
  0.1372549  0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]]

Если мы обучаем нейронную сеть, по разным причинам будет проще, если мы будем рассматривать все значения как от 0 до 1, процесс, называемый «нормализация». К счастью, в Python такой список легко нормализовать без циклов. Мы делаем это так:

training_images  = training_images / 255.0
test_images = test_images / 255.0

Почему существует два набора – тренировочный и тестовый? Идея состоит в том, чтобы иметь один набор данных для обучения, а затем еще один набор данных, который модель еще не видела, чтобы определить, насколько хорошо он будет классифицировать значения. В конце концов, модель и предназначена для распознавания объектов с данными из реального мира.

Давайте теперь спроектируем модель. Здесь довольно много новых концепций, но не волнуйтесь, вы их освоите:

model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), 
  tf.keras.layers.Dense(128, activation=tf.nn.relu), 
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
  • Sequential: определяет ПОСЛЕДОВАТЕЛЬНОСТЬ слоев в нейронной сети.
  • Flatten: Помните ранее, когда наши изображения были квадратными, когда вы их распечатывали? Flatten просто берет этот квадрат и превращает его в одномерный набор.
  • Dense: добавляет слой нейронов. Каждому слою нейронов нужна функция активации, которая сообщает, что делать. Есть много вариантов, но пока используйте только эти.
  • Функция активации выпрямителя (ReLu) фактически означает «Если X> 0 вернуть X, иначе вернуть 0» — так что он делает это, он только передает значения 0 или выше на следующий уровень в сети.
  • Софтмакс (Softmax) принимает набор значений и эффективно выбирает самое большое, поэтому, например, если выходные данные последнего слоя выглядят как [0,1, 0,1, 0,05, 0,1, 9,5, 0,1, 0,05, 0,05, 0,05], он сохраняет вы просматриваете его в поисках наибольшего значения и превращаете его в [0,0,0,0,1,0,0,0,0]. Это позволяет сделать код короче.

Следующее, что нужно сделать — это построить модель. Мы делаем это, компилируя его с оптимизатором и Функцией потерь (Loss Function), как и раньше, а затем обучаете его, вызывая model.fit() и прося его сопоставить ваши данные обучения с вашими метками обучения, т.е. заставить его выяснить взаимосвязь между обучающие данные и их фактические метки, поэтому в будущем, если у вас будут данные, похожие на обучающие данные, он может сделать прогноз того, как эти данные будут выглядеть.

model.compile(optimizer = tf.keras.optimizers.Adam(),
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(training_images, training_labels, epochs=5)

Обучение разделено на эпохи:

Epoch 1/5
1875/1875 [==============================] - 13s 6ms/step - loss: 0.5011 - accuracy: 0.8236
Epoch 2/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.3728 - accuracy: 0.8648
Epoch 3/5
1875/1875 [==============================] - 6s 3ms/step - loss: 0.3384 - accuracy: 0.8762
Epoch 4/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.3138 - accuracy: 0.8854
Epoch 5/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.2932 - accuracy: 0.8917
<keras.callbacks.History at 0x7fb53ae2f6d0>

По завершении обучения мы увидим значение точности в конце последней эпохи. В данном случае это 0,8917. Это говорит о том, что точность вашей нейронной сети в классификации обучающих данных составляет около 89%. То есть она смогла правильно узнать предмет одежды в 89% случаев.

Но как это будет работать с неизвестными модели данными? Вот почему у нас есть тестовые изображения. Мы можем вызвать model.evaluate(), чтобы узнать о потерях. Давайте попробуем:

model.evaluate(test_images, test_labels)
313/313 [==============================] - 1s 2ms/step - loss: 0.3577 - accuracy: 0.8744
[0.35774385929107666, 0.8744000196456909]

Точность равна примерно 87%. Как и ожидалось, модель, вероятно, не будет так хорошо работать с неизвестными доселе данными. Однако в целом результат можно считать удовлетворительным.

Ноутбук, не требующий дополнительной настройки на момент написания статьи, можно скачать здесь.

Автор оригинальной статьи: Arun Ponnusamy