Понимание 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. Ниже приведены три слоя:
- Сверточный слой.
- Объединяющий слой.
- Полное подключение.
- Сверточный уровень. Сверточный уровень является основной частью 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