Создайте свой собственный CNN с помощью Keras

В этой статье я покажу вам, как создать свою собственную сверточную нейронную сеть (CNN) для классификации изображений с помощью языка программирования Python и его библиотеки keras !

Если вы предпочитаете не читать эту статью и хотите ее видеопрезентацию, вы можете посмотреть видео ниже. В нем подробно рассматривается все, что описано в этой статье, и он поможет вам легко начать программировать свою собственную модель сверточной нейронной сети (CNN), даже если на вашем компьютере не установлен язык программирования Python. Или вы можете использовать и видео, и эту статью в качестве дополнительных материалов для изучения CNN!

Начать программирование:

Сначала я напишу описание того, что будет делать эта программа. Таким образом, когда я оглянусь на нее позже в будущем, я или кто-то еще точно будет знать, что она делает.

# Description: This programs classifies images

Затем мне нужно установить зависимости / пакеты. Если у вас еще не установлены эти пакеты, выполните следующую команду в своем терминале, командной строке или на веб-сайте Google Colab (в зависимости от того, где у вас установлен язык программирования Python).

pip install tensorflow keras numpy skimage matplotlib

Импортируйте библиотеки.

import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, Dropout
from tensorflow.keras import layers
from keras.utils import to_categorical
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

Затем загрузите набор данных в переменные x_train (переменная, содержащая изображения для обучения), y_train (переменная, содержащая метки изображений в обучающем наборе), x_test (переменная который содержит изображения для тестирования) и y_test (переменная, содержащая метки изображений в тестовом наборе).

#Load the data
from keras.datasets import cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

Исследуйте данные

Распечатайте тип данных загруженных наборов данных. Это позволит нам узнать, с какими данными мы работаем.

#Print the data type of x_train
print(type(x_train))
#Print the data type of y_train
print(type(y_train))
#Print the data type of x_test
print(type(x_test))
#Print the data type of y_test
print(type(y_test))

Получите форму данных x_train, y_train, x_test и y_test. Вы заметите, что форма набора данных x_train представляет собой 4-мерный массив с 50 000 строками изображения 32 x 32 пикселя с глубиной = 3 (RGB), где R - красный, G - зеленый, а B - синий. Форма данных y_train представляет собой двумерный массив с 50 000 строками и 1 столбцом. Форма набора данных x_test представляет собой 4-мерный массив с 10 000 строками изображения 32 x 32 пикселя с глубиной = 3 (RGB). Форма данных y_test - это двумерный массив с 10 000 строками и 1 столбцом.

#Get the shape of x_train
print('x_train shape:', x_train.shape)
#Get the shape of y_train
print('y_train shape:', y_train.shape)
#Get the shape of x_train
print('x_test shape:', x_test.shape)
#Get the shape of y_train
print('y_test shape:', y_test.shape)

Взгляните на первое изображение (с индексом = 0) в наборе обучающих данных в виде массива numpy. Это показывает изображение как серию значений пикселей.

index = 0
x_train[index]

Показывать изображение как изображение вместо серии значений пикселей с помощью matplotlib.

img = plt.imshow(x_train[index])

Распечатайте этикетку изображения. Обратите внимание, что на напечатанной этикетке была цифра 6, что соответствует этикетке с лягушкой.

print('The image label is: ', y_train[index])

Отобразите классификацию ярлыков по отношению к номеру.

classification = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
#Print the image class
print('The image class is: ', classification[y_train[index][0]])

Используйте One-Hot Encoding, чтобы преобразовать метки в набор из 10 чисел для ввода в нейронную сеть. Цифры, конечно, соответствуют количеству ярлыков для классификации изображений.

y_train_one_hot = to_categorical(y_train)
y_test_one_hot = to_categorical(y_test)

Распечатайте все новые метки в наборе обучающих данных.

print(y_train_one_hot)

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

ПРИМЕЧАНИЕ. Метка 6 = [0,0,0,0,0,0,1,0,0,0].

print('The one hot label is:', y_train_one_hot[0])

Нормализовать пиксели изображений до значения от 0 до 1, обычно это значения от 0 до 255, это поможет нейронной сети.

x_train = x_train / 255
x_test = x_test / 255

Постройте модель сверточной нейронной сети

Чтобы построить модель, нам нужно создать архитектуру с помощью Sequential().

model = Sequential()

Затем мы добавляем первый слой, сверточный слой для извлечения элементов из входного изображения и создаем 32 свернутых элемента ReLu 5 x 5, также известных как карты элементов. Поскольку это первый слой, мы должны ввести размерную форму, которая представляет собой изображение 32 x 32 пикселя с глубиной = 3 (RGB).

model.add(Conv2D(32, (5, 5), activation='relu', input_shape=(32,32,3)))

Следующим слоем будет слой объединения с фильтром 2 x 2 пикселя для получения максимального элемента из карт функций. Это уменьшает размер карт объектов вдвое и также называется подвыборкой.

model.add(MaxPooling2D(pool_size=(2, 2)))

Создайте еще один слой свертки и слой объединения, как раньше, но без input_shape.

model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

Добавьте сглаживающий слой, чтобы уменьшить изображение до линейного массива, также известного как один одномерный вектор, который вводится и соединяется с нейронной сетью.

model.add(Flatten())

Теперь создайте нейронную сеть, в которой первый слой имеет 1000 нейронов и функцию активации ReLu.

model.add(Dense(1000, activation='relu'))

Добавьте выпадающий слой с выпадением 50%.

model.add(Dropout(0.5))

Теперь создайте нейронную сеть, в которой первый слой содержит 500 нейронов и функцию активации ReLu.

model.add(Dense(500, activation='relu'))

Добавьте выпадающий слой с выпадением 50%.

model.add(Dropout(0.5))

Теперь создайте нейронную сеть, в которой первый слой содержит 250 нейронов и функцию активации ReLu.

model.add(Dense(250, activation='relu'))

Создайте последний слой этой нейронной сети с 10 нейронами (по одному для каждой метки) с помощью функции softmax.

model.add(Dense(10, activation='softmax'))

Итак, собранный CNN должен выглядеть так, как показано ниже.

model = Sequential()
model.add(Conv2D(32, (5, 5), activation='relu', input_shape=(32,32,3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(1000, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(250, activation='relu'))
model.add(Dense(10, activation='softmax'))

Составьте модель. Дайте ему categorical_crossentropy функцию потерь, которая используется для классов больше 2, оптимизатор Адама и точность модели.

model.compile(loss='categorical_crossentropy', 
              optimizer='adam',
              metrics=['accuracy'])

Обучите модель, используя метод fit(), что является другим словом для обучения. Мы обучим модель на обучающих данных с размером пакета = 256, эпохами = 10 и разделим данные на обучение на 80% данных и использование остальных 20% в качестве проверки. Обучение может занять некоторое время.

Пакет: общее количество обучающих примеров, представленных в одном пакете.

Эпоха: количество итераций, когда ВЕСЬ набор данных передается вперед и назад через нейронную сеть только ОДИН РАЗ.

Fit: другое слово для обозначения тренировки.

hist = model.fit(x_train, y_train_one_hot, 
           batch_size=256, epochs=10, validation_split=0.2 )

Получить метрики моделей

Получите точность моделей по тестовым данным.

model.evaluate(x_test, y_test_one_hot)[1]

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

#Visualize the models accuracy
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Val'], loc='upper left')
plt.show()

Визуализируйте потерю моделей как для данных обучения, так и для данных проверки.

#Visualize the models loss
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Val'], loc='upper right')
plt.show()

Протестируйте модель

Загрузите данные, которые вы хотите классифицировать, из файла изображения в переменную new_image.

#Load the data
from google.colab import files # Use to load data on Google Colab
uploaded = files.upload() # Use to load data on Google Colab
new_image = plt.imread("cat.4015.jpg") #Read in the image (3, 14, 20)

Показать загруженное изображение.

img = plt.imshow(new_image)

Измените размер изображения на изображение размером 32 x 32 пикселя с глубиной 3 и покажите изображение.

from skimage.transform import resize
resized_image = resize(new_image, (32,32,3))
img = plt.imshow(resized_image)

Получите прогнозы для каждого класса и сохраните их в переменной.

predictions = model.predict(np.array( [resized_image] ))

Показать прогнозы

predictions

Отсортируйте прогнозы от наименьшего к наибольшему так, чтобы наибольшая вероятность имела индекс = 9, а наименьшая вероятность - индекс = 0.

list_index = [0,1,2,3,4,5,6,7,8,9]
x = predictions
for i in range(10):
  for j in range(10):
    if x[0][list_index[i]] > x[0][list_index[j]]:
      temp = list_index[i]
      list_index[i] = list_index[j]
      list_index[j] = temp
#Show the sorted labels in order from highest probability to lowest
print(list_index)

Выведите первые 5 наиболее вероятных классов и соответствующую вероятность.

i=0
for i in range(5):
  print(classification[list_index[i]], ':', round(predictions[0][list_index[i]] * 100, 2), '%')

Похоже, эта модель смогла точно классифицировать данное изображение как кошку с вероятностью 50,65%. Это хорошо, но, судя по собранным ранее метрикам, эта модель не очень точна, ее точность составляет всего 70,43%. Таким образом, хотя точность лучше, чем предположение, она все же может значительно выиграть, если возможно, большее количество обучающих данных и некоторая точная настройка модели.

Давайте сохраним эту модель для дальнейшего использования.

#To save this model 
model.save('my_model.h5')

Чтобы загрузить эту модель позже, без необходимости обучать новую, вы можете сделать следующее.

#To load this model
from keras.models import load_model
model = load_model('my_model.h5')

Вы можете посмотреть видео выше о том, как я кодировал эту программу и код вместе со мной, с несколькими более подробными объяснениями, или вы можете просто щелкнуть ссылку YouTube здесь.

Если вам также интересно узнать больше о машинном обучении, чтобы сразу приступить к работе с проблемами и примерами, я настоятельно рекомендую вам ознакомиться с Практическое машинное обучение с помощью Scikit-Learn и TensorFlow: концепции, инструменты и методы для создания интеллектуальных систем . Это отличная книга, которая поможет новичкам научиться писать программы машинного обучения и понять концепции машинного обучения.

Спасибо, что прочитали эту статью. Надеюсь, она будет вам полезна! Если вам понравилась эта статья и вы нашли ее полезной, пожалуйста, оставьте несколько аплодисментов, чтобы выразить свою признательность. Продолжайте обучение, и если вам нравится машинное обучение, математика, информатика, программирование или анализ алгоритмов, посетите и подпишитесь на мои каналы YouTube (randerson112358 и compsci112358).

Ресурсы:

[1] Учебник по Keras - построить сверточную нейронную сеть в 11 строк

[2] Создайте свой первый классификатор распознавания изображений, используя бэкэнд CNN, Keras и Tensorflow

[3] Создание сверточной нейронной сети (CNN) в Керасе

[4] Машинное обучение от А до Я: скачать наборы практических данных

[5] Построение модели глубокого обучения с использованием Keras

[6] Python | Классификация изображений с помощью keras GeeksforGeeks

[7] Создание мощных моделей классификации изображений с использованием очень небольшого количества данных

[8] Классификация изображений с помощью Keras и глубокого обучения

[9] Керас