Предварительная обработка или подготовка данных популярного набора данных изображений - CIFAR-100

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

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

Примечание.

  1. Я постараюсь прояснить большинство концепций, но, тем не менее, эта статья предполагает базовое понимание сверточной нейронной сети (CNN). 📖
  2. Для написания кода я использовал блокнот jupyter.

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

Итак, приступим. 🏃🏻

Что такое СИФАР-100? 🤔

CIFAR-100 - это помеченное подмножество набора данных из 80 миллионов крошечных изображений, где CIFAR означает Канадский институт перспективных исследований. Изображения были собраны Алексом Крижевски, Винодом Наиром и Джеффри Хинтоном. Набор данных состоит из 60000 цветных изображений (50000 обучающих и 10000 тестовых) размером 32 × 32 пикселей в 100 классах, сгруппированных в 20 суперклассов. У каждого изображения есть точная метка (класс) и грубая метка (суперкласс).

Как получить набор данных CIFAR-100? 🙋

Версия этого набора данных для Python может быть загружена с веб-сайта University of Toronto Computer Science. Загруженные файлы представляют собой маринованные объекты Python, созданные с помощью cPickle. Пока не беспокойтесь об этом. Мы вместе пройдем через каждый шаг, чтобы использовать этот набор данных.

Как загрузить этот набор данных? 🚛

После загрузки набора данных с веб-сайта нам нужно загрузить его в наш блокнот jupyter. Файлы, полученные с сайта, представляют собой маринованные объекты Python. Структура папок после распаковки выглядит так:

Мы видим, что у нас есть отдельные обучающие и тестовые файлы, а также метафайл.

Модуль Python Pickle или cPickle можно использовать для сериализации или десериализации объектов в Python. Здесь я использую рассол. Метод load () в Pickle можно использовать для чтения этих файлов и анализа их структуры. Прочтите это, чтобы узнать больше о травлении.

Pickle нужны двоичные данные, поэтому мы будем открывать файлы как «rb» и загружать их с помощью метода pickle load () с кодировкой «latin1».

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

import pickle
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import rcParams
%matplotlib inline
import keras
from keras.utils import to_categorical

Вот код для чтения этих файлов.

#function to read files present in the Python version of the dataset
def unpickle(file):
    with open(file, 'rb') as fo:
        myDict = pickle.load(fo, encoding='latin1')
    return myDict

Прочтите это, чтобы узнать, почему мы чаще всего используем latin1 в качестве кодировки.

Теперь загрузим наш обучающий набор.

trainData = unpickle('train')
#type of items in each file
for item in trainData:
    print(item, type(trainData[item]))

Результат выглядит так:

filenames <class 'list'>
batch_label <class 'str'>
fine_labels <class 'list'>
coarse_labels <class 'list'>
data <class 'numpy.ndarray'>

В учебном файле есть перечисленные выше элементы. Coarse_labels и fine_labels - это метки изображений (20, 100 соответственно), файл данных содержит данные изображения в форме массива NumPy, имена файлов - это список, в котором указаны имена файлов, а batch_label - метка пакета. .

Давайте проверим длину набора данных.

print(len(trainData['data']))
print(len(trainData['data'][0]))

Результат выглядит так:

50000
3072

Итак, в наборе обучающих данных 50 000 изображений, и каждое изображение представляет собой трехканальное изображение размером 32 × 32 пикселя (32 × 32 × 3 = 3072).

Давайте взглянем на уникальные прекрасные этикетки.

print(np.unique(trainData['fine_labels']))

Результат выглядит так:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]

Итак, существует 100 различных меток для изображений в диапазоне от 0 до 99.

Давайте теперь посмотрим на уникальные грубые этикетки.

print(np.unique(trainData['coarse_labels']))

Результат выглядит так:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]

Итак, существует 20 различных грубых меток для изображений от 0 до 19.

Давайте проверим, что есть в файле batch_label.

print(trainData['batch_label'])

Результат выглядит так:

training batch 1 of 1

Здесь у нас есть только один пакет, поэтому batch_label - это строка, указывающая это.

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

testData = unpickle('test')
metaData = unpickle('meta')
#metaData
print("Fine labels:", metaData['fine_label_names'], "\n")
print("Coarse labels:", metaData['coarse_label_names'])

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

Fine labels: ['apple', 'aquarium_fish', 'baby', 'bear', 'beaver', 'bed', 'bee', 'beetle', 'bicycle', 'bottle', 'bowl', 'boy', 'bridge', 'bus', 'butterfly', 'camel', 'can', 'castle', 'caterpillar', 'cattle', 'chair', 'chimpanzee', 'clock', 'cloud', 'cockroach', 'couch', 'crab', 'crocodile', 'cup', 'dinosaur', 'dolphin', 'elephant', 'flatfish', 'forest', 'fox', 'girl', 'hamster', 'house', 'kangaroo', 'keyboard', 'lamp', 'lawn_mower', 'leopard', 'lion', 'lizard', 'lobster', 'man', 'maple_tree', 'motorcycle', 'mountain', 'mouse', 'mushroom', 'oak_tree', 'orange', 'orchid', 'otter', 'palm_tree', 'pear', 'pickup_truck', 'pine_tree', 'plain', 'plate', 'poppy', 'porcupine', 'possum', 'rabbit', 'raccoon', 'ray', 'road', 'rocket', 'rose', 'sea', 'seal', 'shark', 'shrew', 'skunk', 'skyscraper', 'snail', 'snake', 'spider', 'squirrel', 'streetcar', 'sunflower', 'sweet_pepper', 'table', 'tank', 'telephone', 'television', 'tiger', 'tractor', 'train', 'trout', 'tulip', 'turtle', 'wardrobe', 'whale', 'willow_tree', 'wolf', 'woman', 'worm'] 
Coarse labels: ['aquatic_mammals', 'fish', 'flowers', 'food_containers', 'fruit_and_vegetables', 'household_electrical_devices', 'household_furniture', 'insects', 'large_carnivores', 'large_man-made_outdoor_things', 'large_natural_outdoor_scenes', 'large_omnivores_and_herbivores', 'medium_mammals', 'non-insect_invertebrates', 'people', 'reptiles', 'small_mammals', 'trees', 'vehicles_1', 'vehicles_2']

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

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

#storing coarse labels along with its number code in a dataframe
category = pd.DataFrame(metaData['coarse_label_names'], columns=['SuperClass'])
#storing fine labels along with its number code in a dataframe
subCategory = pd.DataFrame(metaData['fine_label_names'], columns=['SubClass'])
print(category)
print(subCategory)

Взгляд на два фрейма данных:

Давайте теперь посмотрим на наши данные.

X_train = trainData['data']
X_train

На выходе получается массив NumPy.

array([[255, 255, 255, ...,  10,  59,  79],
       [255, 253, 253, ..., 253, 253, 255],
       [250, 248, 247, ..., 194, 207, 228],
       ...,
       [248, 240, 236, ..., 180, 174, 205],
       [156, 151, 151, ..., 114, 107, 126],
       [ 31,  30,  31, ...,  72,  69,  67]], dtype=uint8)

Чтобы выполнить задачу распознавания и классификации изображений, должна быть построена сверточная нейронная сеть, для которой требуется 4D-массив в качестве входных данных. Итак, данные должны быть преобразованы, чтобы они приобрели эту форму.

Например, в наборе обучающих данных было 50000 изображений с формой (50000, 3072), поэтому нам нужно преобразовать эти изображения, чтобы получить следующую форму, используя операцию изменения формы и транспонирования массива NumPy:

(Количество экземпляров × ширина × высота × глубина)

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

Напишем код для этого преобразования изображений.

#4D array input for building the CNN model using Keras
X_train = X_train.reshape(len(X_train),3,32,32).transpose(0,2,3,1)
#X_train

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

Визуализация:

#generating a random number to display a random image from the dataset along with the label's number and name
#setting the figure size
rcParams['figure.figsize'] = 2,2
#generating a random number
imageId = np.random.randint(0, len(X_train))
#showing the image at that id
plt.imshow(X_train[imageId])
#setting display off for the image
plt.axis('off')
#displaying the image id
print("Image number selected : {}".format(imageId))
#displaying the shape of the image
print("Shape of image : {}".format(X_train[imageId].shape))
#displaying the category number
print("Image category number: {}".format(trainData['coarse_labels'][imageId]))
#displaying the category name
print("Image category name: {}".format(category.iloc[trainData['coarse_labels'][imageId]][0].capitalize()))
#displaying the subcategory number
print("Image subcategory number: {}".format(trainData['fine_labels'][imageId]))
#displaying the subcategory name
print("Image subcategory name: {}".format(subCategory.iloc[trainData['fine_labels'][imageId]][0].capitalize()))

Результат выглядит так:

Выведем еще несколько изображений.

#16 random images to display at a time along with their true labels
#setting the figure size
rcParams['figure.figsize'] = 8,8
#number of columns and rows in which images needs to be displayed
num_row = 4
num_col = 4
#to get 4 * 4 = 16 images together
imageId = np.random.randint(0, len(X_train), num_row * num_col)
#creating subplots
fig, axes = plt.subplots(num_row, num_col)
#main title of the plot
plt.suptitle('Images with True Labels', fontsize=18)
#displaying images as subplots
for i in range(0, num_row):
    for j in range(0, num_col):
        k = (i*num_col)+j
        axes[i,j].imshow(X_train[imageId[k]])
       axes[i,j].set_title(subCategory.iloc[trainData['fine_labels'][imageId[k]]][0].capitalize())
        axes[i,j].axis('off')

Из визуализации видно, что качество изображений низкое, а положение объекта на изображении сильно различается. Было бы сложно обучить модель распознавать и классифицировать такие изображения. 🙆🏻

Давайте теперь поработаем над тестовым набором данных.

#transforming the testing dataset
X_test = testData['data']
X_test = X_test.reshape(len(X_test),3,32,32).transpose(0,2,3,1)
y_train = trainData['fine_labels']
y_test = testData['fine_labels']

Чтобы делать прогнозы, метки изображений были преобразованы в структуру категориальной матрицы из существующей структуры массива 1D NumPy.

#number of classes in the dataset
n_classes = 100
y_train = to_categorical(y_train, n_classes)
y_test = to_categorical(y_test, n_classes)

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

Вот ссылка на репозиторий GitHub, где есть весь этот код. Не стесняйтесь использовать это в своей работе для обучения классической модели CNN, которая может классифицировать изображения. 😊

Связанная статья:



Спасибо всем за то, что прочитали это. Поделитесь своими ценными отзывами или предложениями по поводу этого поста! Приятного чтения! 📗 🖌

LinkedIn