Распознавание дорожных знаков с использованием CNN и Keras в Python
Мы постоянно сталкиваемся с авариями, когда превышение скорости или отсутствие зрения у водителей приводит к крупным авариям. Зимой риск дорожно-транспортных происшествий возрастает на 40-50% из-за плохой видимости дорожных знаков. Итак, в этой статье мы реализуем распознавание дорожных знаков с помощью сверточной нейронной сети. Это будет очень полезно в автоматических транспортных средствах.
Сверточные нейронные сети
Сверточная нейронная сеть — это сеть глубокого обучения, используемая для извлечения признаков из изображения. Сначала они берут входные изображения, а затем находят на изображении линии, градиенты, формы и границы.
Кроме того, сверточные слои помогают обрабатывать выходные данные для захвата глаз, лиц и т. д. CNN содержит множество сверточных слоев, собранных друг над другом, каждый из которых способен распознавать более сложные формы. С двумя или тремя сверточными слоями можно распознавать рукописные цифры, а с 25 слоями можно различать человеческие лица.
Распознавание дорожных знаков с использованием CNN и Keras в Python
Здесь мы будем использовать эту концепцию для распознавания дорожных знаков.
Импорт библиотек
- Панды — используйте для загрузки фрейма данных в формате 2D-массива.
- NumPy — массивы NumPy работают очень быстро и могут выполнять большие вычисления за очень короткое время.
- Matplotlib — эта библиотека используется для рисования визуализаций.
- Sklearn — содержит несколько библиотек с предварительно реализованными функциями разработки и оценки моделей.
- OpenCV — эта библиотека в основном ориентирована на обработку и обработку изображений.
- Tensorflow — предоставляет ряд функций для реализации сложных функций с помощью отдельных строк кода.
Python3
import matplotlib.image as mpimg import os from tensorflow.keras.callbacks import EarlyStopping from tensorflow.keras.preprocessing import image_dataset_from_directory from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img from keras.utils.np_utils import to_categorical from tensorflow.keras.utils import image_dataset_from_directory from tensorflow.keras.optimizers import Adam from tensorflow.keras.layers import Conv2D, MaxPooling2D from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense from tensorflow.keras.models import Sequential from keras import layers from tensorflow import keras from tensorflow.keras.layers.experimental.preprocessing import Rescaling from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt import tensorflow as tf import pandas as pd import numpy as np from glob import glob import cv2 import warnings warnings.filterwarnings( "ignore" ) |
Загрузка и извлечение набора данных
Набор данных содержит 58 классов дорожных знаков и файл label.csv. Папка в формате zip. Чтобы разархивировать набор данных, мы запустим код ниже.
Python3
# Extracting the compressed dataset. from zipfile import ZipFile data_path = "/content/traffic-sign-dataset-classification.zip" with ZipFile(data_path, "r" ) as zip : zip .extractall() |
Визуализация данных
Визуализация данных означает визуализацию данных для понимания ключевых особенностей набора данных.
Python3
# path to the folder containing our dataset dataset = "../content/traffic_Data/DATA" # path of label file labelfile = pd.read_csv( "labels.csv" ) |
Как только мы загрузим набор данных, теперь давайте визуализируем несколько случайных изображений из разных папок. Для этого мы будем использовать команду plt.imshow().
Python3
# Visualize some images from the dataset img = cv2.imread( "/content/traffic_Data/DATA/10/010_0011.png" ) plt.imshow(img) |
Выход :
Давайте посмотрим еще одно изображение.
Python3
img = cv2.imread( "/content/traffic_Data/DATA/23/023_0001.png" ) plt.imshow(img) |
Выход :
Файл этикетки — этот файл включает 58 строк и 2 столбца. Столбцы содержат идентификатор класса и имя символа. И строки изображают идентификаторы и имена 58 различных классов.
Теперь давайте посмотрим на файл этикетки, распечатав 5 верхних строк.
Python3
labelfile.head() |
Выход:
Давайте посмотрим последние 5 классов из файла этикетки
Python3
labelfile.tail() |
Выход:
Подготовка данных для обучения
В этом разделе мы разделим набор данных на набор train и val. Набор поездов будет использоваться для обучения модели, а набор значений будет использоваться для оценки производительности нашей модели.
Python3
train_ds = tf.keras.preprocessing.image_dataset_from_directory(dataset, validation_split = 0.2 , subset = "training" , image_size = ( 224 , 224 ), seed = 123 , batch_size = 32 ) val_ds = tf.keras.preprocessing.image_dataset_from_directory(dataset, validation_split = 0.2 , subset = "validation" , image_size = ( 224 , 224 ), seed = 123 , batch_size = 32 ) |
Выход:
Found 4170 files belonging to 58 classes. Using 3336 files for training. Found 4170 files belonging to 58 classes. Using 834 files for validation.
Как только мы разделим набор данных, давайте создадим список имен классов и распечатаем несколько изображений вместе с именами их классов.
Python3
class_numbers = train_ds.class_names class_names = [] for i in class_numbers: class_names.append(labelfile[ "Name" ][ int (i)]) |
Давайте визуализируем набор данных поезда и распечатаем 25 изображений из набора данных.
Python3
plt.figure(figsize = ( 10 , 10 )) for images, labels in train_ds.take( 1 ): for i in range ( 25 ): ax = plt.subplot( 5 , 5 , i + 1 ) plt.imshow(images[i].numpy().astype( "uint8" )) plt.title(class_names[labels[i]]) plt.axis( "off" ) plt.show() |
Выход:
Увеличение данных
Иногда данные ограничены, и наша модель плохо работает с ограниченными данными. Для этого метода мы используем увеличение данных. Это метод увеличения количества и разнообразия данных. Мы не собираем новые данные, а преобразуем уже имеющиеся данные.
Python3
data_augmentation = tf.keras.Sequential( [ tf.keras.layers.experimental.preprocessing.RandomFlip( "horizontal" , input_shape = ( 224 , 224 , 3 )), tf.keras.layers.experimental.preprocessing.RandomRotation( 0.1 ), tf.keras.layers.experimental.preprocessing.RandomZoom( 0.2 ), tf.keras.layers.experimental.preprocessing.RandomFlip( mode = "horizontal_and_vertical" ) ] ) |
Архитектура модели
Модель будет содержать следующие слои:
- Четыре сверточных слоя, за которыми следуют слои MaxPooling.
- Слой Flatten для выравнивания выходных данных сверточного слоя.
- Тогда у нас будет три полносвязных плотных слоя, за которыми следует вывод функции активации Softmax.
Python3
model = Sequential() model.add(data_augmentation) model.add(Rescaling( 1. / 255 )) model.add(Conv2D( 128 , ( 3 , 3 ), activation = "relu" )) model.add(MaxPooling2D(( 2 , 2 ))) model.add(Conv2D( 64 , ( 3 , 3 ), activation = "relu" )) model.add(MaxPooling2D(( 2 , 2 ))) model.add(Conv2D( 128 , ( 3 , 3 ), activation = "relu" )) model.add(MaxPooling2D(( 2 , 2 ))) model.add(Conv2D( 256 , ( 3 , 3 ), activation = "relu" )) model.add(MaxPooling2D(( 2 , 2 ))) model.add(Flatten()) model.add(Dense( 64 , activation = "relu" )) model.add(Dropout( 0.2 )) model.add(Dense( 128 , activation = "relu" )) model.add(Dense( len (labelfile), activation = "softmax" )) |
Распечатаем сводку модели.
Python3
model.summary() |
Выход :
Чтобы понять огромное количество параметров и сложность модели, которая помогает нам достичь высокой производительности, давайте посмотрим на plot_model.
Python3
keras.utils.plot_model( model, show_shapes = True , show_dtype = True , show_layer_activations = True ) |
Выход :
Python3
model. compile (loss = tf.keras.losses.SparseCategoricalCrossentropy(), optimizer = "adam" , metrics = [ "accuracy" ]) |
Обучение модели
Теперь мы будем обучать нашу модель, модель отлично работает на эпохах = 50, но вы можете выполнить настройку гиперпараметров для лучших результатов.
Мы также можем использовать функцию обратного вызова для ранней остановки обучения модели.