Предварительная обработка или подготовка данных популярного набора данных изображений - CIFAR-100
Распознавание изображений - это простая задача для людей, поскольку нам легко различать разные функции. Каким-то образом наш мозг бессознательно тренируется с разными или похожими типами изображений, которые помогают нам различать особенности (изображения), не прилагая особых усилий для выполнения этой задачи. Например, увидев несколько кошек, мы можем узнать почти все виды кошек, с которыми сталкиваемся в нашей жизни. 🐱 Тем не менее, машины нуждаются в длительном обучении для извлечения признаков, что становится проблемой из-за высокой стоимости вычислений, требований к памяти и вычислительной мощности.
В этой статье мы обсудим предварительную обработку одного такого варианта использования. Итак, давайте погрузимся глубже и поймем, как мы можем предварительно обработать набор данных изображения для построения модели сверточной нейронной сети. 🏊🏼
Примечание.
- Я постараюсь прояснить большинство концепций, но, тем не менее, эта статья предполагает базовое понимание сверточной нейронной сети (CNN). 📖
- Для написания кода я использовал блокнот 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, которая может классифицировать изображения. 😊
Связанная статья:
Спасибо всем за то, что прочитали это. Поделитесь своими ценными отзывами или предложениями по поводу этого поста! Приятного чтения! 📗 🖌