Понимание CNN с использованием Keras.

Содержание:

  • Мотивация.
  • Понимание набора данных.
  • Шаг 0: Импортируйте библиотеки и набор данных.
  • Шаг 1: Предварительная обработка данных.
  • Шаг 2: Визуализация данных.
  • Интуиция позади ConvNets.
  • Шаг 3: Обучение модели.
  • Шаг 4: Оценка модели.

Мотивация:

Беспилотные автомобили становятся очень популярными благодаря усилиям таких компаний, как Tesla, по автоматизации своих электромобилей. Чтобы стать автономными 5-го уровня, эти автомобили должны правильно распознавать дорожные знаки и соблюдать правила дорожного движения. После определения этих дорожных знаков он также должен иметь возможность принимать правильные решения надлежащим образом.

Понимание набора данных:

German Traffic Sign Benchmark — это мультиклассовая задача классификации одного изображения, проводимая на Международной объединенной конференции по нейронным сетям (IJCNN) 2011. Загрузите набор данных здесь. Набор данных имеет следующие свойства:

  • Одно изображение, проблема классификации нескольких классов
  • Более 40 классов
  • Всего более 50 000 изображений
  • Большая реалистичная база данных

Шаг 0: Импортируйте библиотеки и набор данных:

На первом этапе мы импортируем все стандартные библиотеки вместе с набором данных, который будет храниться как данные и метки. Tensorflow импортируется для использования Keras, cv2 для решения проблем, связанных с компьютерным зрением, и PIL для обработки различных форматов файлов изображений.

# Importing standard libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import cv2
import tensorflow as tf
from PIL import Image
# Importing dataset
import os
data = []
labels = []
classes = 43
cur_path = os.getcwd()
for i in range(classes):
    path = os.path.join(cur_path, 'train', str(i))
    images = os.listdir(path)
    
    for a in images:
        try:
            image = Image.open(path + '\\'+ a)
            image = image.resize((30, 30))
            image = np.array(image)
            data.append(image)
            labels.append(i)
        except:
            print("Error loading image")

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

Для управления данными мы преобразуем их в массив с помощью numpy. Затем мы проверяем размеры набора данных, используя функцию shape. Затем набор данных разделяется на данные для обучения и тестирования с помощью функции train_test_split с соотношением 80:20. Y_train и Y_test содержат 43 класса в целочисленной форме, что не подходит для нашей модели. Итак, мы преобразуем его в двоичную форму с помощью функции to_categorical.

# Converting to array
data = np.array(data)
labels = np.array(labels)
# Dataset Dimensions - (Number of Images, Width, Length, Color channels)
print("Dataset dimensions : ",data.shape)
output:   
Dataset dimensions :  (39209, 30, 30, 3)
# Splitting the dataset into train and test
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(data, labels, test_size = 0.2, random_state = 42)
# Checking dimensions - (Number of Images, Width, Length, Color channels)
print("X_train shape : ", X_train.shape)
print("X_test shape : ", X_test.shape)
print("Y_train shape : ", Y_train.shape)
print("Y_test shape : ", Y_test.shape)
output:
X_train shape :  (31367, 30, 30, 3)
X_test shape :  (7842, 30, 30, 3)
Y_train shape :  (31367,)
Y_test shape :  (7842,)
# Converting integer class to binary class
from keras.utils import to_categorical
Y_train_categorical = to_categorical(Y_train, 43)
Y_test_categorical = to_categorical(Y_test, 43)

Шаг 2: Визуализация данных:

Мы будем использовать функцию imshow для визуализации определенного изображения в наборе данных. Изображения в этом наборе данных имеют высоту 30 пикселей, ширину 30 пикселей и 3 цветовых канала.

# Visualizing Dataset Images
i = 100
plt.imshow(X_train[i])
print("Sign category :",Y_train[i])

Интуиция позади ConvNets

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

С точки зрения непрофессионала, CNN — это полностью подключенная нейронная сеть с операциями свертки в начале. Эти операции свертки можно использовать для обнаружения определяющих шаблонов в изображениях. Он похож на нейроны в затылочной доле человеческого мозга. Архитектура ConvNets построена с использованием 3 слоев, которые затем складываются для формирования полной архитектуры ConvNet. Ниже приведены три слоя:

  1. Сверточный слой.
  2. Объединяющий слой.
  3. Полное подключение.
  • Сверточный уровень. Сверточный уровень является основной частью ConvNet и выполняет все сложные вычислительные задачи. Ядро или фильтр определенного шаблона проходит через все изображение, чтобы обнаружить определенный тип функции. Результатом этого обхода является двумерный массив, называемый Feature maps. Каждое значение в этой карте функций передается через функцию ReLU для устранения нелинейности.
  • Слой пула. Этот уровень отвечает за уменьшение размерности данных, поскольку он сокращает объем вычислений и время, необходимое для обработки. Существует два типа объединения: средний и максимальный. Как следует из названия, максимальный пул возвращает максимальное значение, а средний пул возвращает средние значения части изображения, покрытой ядром.
  • Полные соединения:двумерный выходной массив, полученный на предыдущем шаге, преобразуется в вектор-столбец посредством процесса выравнивания. Этот вектор передается в многослойную нейронную сеть, которая через ряд эпох учится классифицировать изображения с помощью функции Softmax.

Шаг 3: Обучение модели

# Importing Keras Libraries
from keras.models import Sequential
from keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropout
# Creating Neural network Architecture
# Initialize neural network
model = Sequential()
# Add 2 convolutional layers with 32 filters, a 5x5 window, and ReLU activation function
model.add(Conv2D(filters = 32, kernel_size = (5, 5), activation = 'relu', input_shape = X_train.shape[1:]))
model.add(Conv2D(filters = 32, kernel_size = (5, 5), activation = 'relu'))
# Add max pooling layer with a 2x2 window
model.add(MaxPool2D(pool_size = (2, 2)))
# Add dropout layer
model.add(Dropout(rate = 0.25))
# Add 2 convolutional layers with 32 filters, a 5x5 window, and ReLU activation function
model.add(Conv2D(filters = 64, kernel_size = (3, 3), activation = 'relu'))
model.add(Conv2D(filters = 64, kernel_size = (3, 3), activation = 'relu'))
# Add max pooling layer with a 2x2 window
model.add(MaxPool2D(pool_size = (2, 2)))
# Add dropout layer
model.add(Dropout(rate = 0.25))
# Add layer to flatten input
model.add(Flatten())
# Add fully connected layer of 256 units with a ReLU activation function
model.add(Dense(256, activation = 'relu'))
# Add dropout layer
model.add(Dropout(rate = 0.5))
# Add fully connected layer of 256 units with a Softmax activation function
model.add(Dense(43, activation = 'softmax'))
# Summarizing the model architecture
model.summary()
output:
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 26, 26, 32)        2432      
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 22, 22, 32)        25632     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 11, 11, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 11, 11, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 9, 9, 64)          18496     
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 7, 7, 64)          36928     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 3, 3, 64)          0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 3, 3, 64)          0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 576)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               147712    
_________________________________________________________________
dropout_3 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 43)                11051     
=================================================================
Total params: 242,251
Trainable params: 242,251
Non-trainable params: 0
_________________________________________________________________
# Compile neural network
model.compile(loss = "categorical_crossentropy", optimizer = "adam", metrics = ["accuracy"])
# Train neural network 
history = model.fit(X_train, Y_train_categorical, batch_size = 32, epochs = 15, validation_data = (X_test, Y_test_categorical))
Output after 15 epochs:
Epoch 15/15
31367/31367 [==============================] - 98s 3ms/step - loss: 0.2169 - acc: 0.9485 - val_loss: 0.0835 - val_acc: 0.9787

Шаг 4: Оценка модели:

# Ploting graph - Epoch vs Accuracy
plt.plot(history.history['acc'], label='training accuracy')
plt.plot(history.history['val_acc'], label='val accuracy')
plt.title('Accuracy')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.grid()
plt.legend()
plt.show()

# Ploting graph - Epoch vs Loss
plt.plot(history.history['loss'], label='training loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.title('Loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.grid()
plt.legend()
plt.show()

# Calculating Accuracy Score
from sklearn.metrics import accuracy_score
y_test = pd.read_csv('Test.csv')
labels = y_test["ClassId"].values
imgs = y_test["Path"].values

data = []

for img in imgs:
    image = Image.open(img)
    image = image.resize((30,30))
    data.append(np.array(image))

X_test = np.array(data)

pred = model.predict_classes(X_test)

from sklearn.metrics import accuracy_score
print("Accuracy Score : ",accuracy_score(labels, pred))
Output:
Accuracy Score :  0.9499604117181314

Репозиторий на гитхабе: