Введение
Я настоятельно рекомендую вам ознакомиться с Классификация рукописных цифр Mnist с использованием тензорного потока, прежде чем продолжить эту статью. В этой статье я занимался той же классификацией рукописных цифр MNIST, используя простую нейронную сеть.
Сверточные нейронные сети (CNN) представляют собой современную архитектуру, используемую в основном для задач классификации изображений. Они также известны как инвариантные к сдвигу или инвариантные к пространству искусственные нейронные сети. Это означает, что даже если цифра на изображении не находится в точном месте, как при обучении, мы все равно сможем правильно классифицировать изображение.
У них есть приложения для распознавания изображений и видео, рекомендательных систем, классификации изображений, сегментации изображений, анализа медицинских изображений, обработки естественного языка, интерфейсов мозг-компьютер и финансовых временных рядов.
CNN — это регуляризованные версии многослойных персептронов. Многослойные персептроны обычно означают полносвязные сети, то есть каждый нейрон в одном слое связан со всеми нейронами в следующем слое.
достаточно болтовни, давайте погрузимся прямо в
Импорт модулей
Необходимые пакеты -
- Тензорный поток
- matplotlib
- пустышка
- Юпитер
- opencv
import tensorflow as tf
# Loading the dataset mnist = tf.keras.datasets.mnist
# Divide into training and test dataset (x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train.shape # (60000, 28, 28)
Следовательно, обучающие данные содержат 60 000 изображений. Каждое из этих изображений имеет ширину 28 пикселей и высоту 28 пикселей.
import matplotlib.pyplot as plt
plt.imshow(x_train[0])
plt.show()
Изображение в наборе данных является цветным, мы можем преобразовать его в оттенки серого, используя встроенную карту цветов matplotlib.
plt.imshow(x_train[0], cmap = plt.cm.binary)
Нормализация
Исходное изображение черно-белое, но значение находится в диапазоне [0–255]. 0 — это абсолютный черный цвет, а 255 — абсолютный белый цвет. Но для обучения нам нужно преобразовать это в [0–1].
x_train = tf.keras.utils.normalize(x_train, axis = 1)
x_test = tf.keras.utils.normalize(x_test, axis = 1)
plt.imshow(x_train[0], cmap = plt.cm.binary)
# verify that there is a proper label for the image
print(y_train[0])
# 5
Изменение размера изображения для свертки
Вы всегда должны давать массив 4D в качестве входных данных для CNN.
Таким образом, входные данные имеют форму (размер_пакета, высота, ширина, глубина), где первое измерение представляет собой размер пакета изображения, а три других измерения представляют размеры изображения: высоту, ширину и глубину.
Для некоторых из вас, кому интересно, что такое глубина изображения, это не что иное, как количество цветовых каналов. Например, изображение RGB будет иметь глубину 3, а изображение в оттенках серого будет иметь глубину 1.
В нашем случае, поскольку мы имеем дело с изображениями в оттенках серого, мы можем добавить глубину 1.
import numpy as np
IMG_SIZE=28
# -1 is a shorthand, which returns the length of the dataset
x_trainr = np.array(x_train).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
x_testr = np.array(x_test).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
print("Training Samples dimension", x_trainr.shape)
print("Testing Samples dimension", x_testr.shape)
# Training Samples dimension (60000, 28, 28, 1)
# Testing Samples dimension (10000, 28, 28, 1)
Создание глубокой нейронной сети
- Sequential — нейронная сеть с прямой связью
- Плотный — типичный слой в нашей модели.
- Dropout — используется, чтобы сделать нейронную сеть более надежной за счет уменьшения переобучения.
- Flatten — используется для выравнивания данных для использования в плотном слое.
- Conv2d — мы будем использовать двумерную CNN.
- MaxPooling2D — Пулинг в основном помогает в извлечении четких и плавных функций. Это также сделано для уменьшения дисперсии и вычислений. Максимальный пул помогает извлекать низкоуровневые функции, такие как края, точки и т. д. В то время как средний пул используется для плавных функций.
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
# Creating the network model = Sequential()
### First Convolution Layer # 64 -> number of filters, (3,3) -> size of each kernal, model.add(Conv2D(64, (3,3), input_shape = x_trainr.shape[1:])) # For first layer we have to mention the size of input model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2,2)))
### Second Convolution Layer model.add(Conv2D(64, (3,3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2,2)))
### Third Convolution Layer model.add(Conv2D(64, (3,3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2,2)))
### Fully connected layer 1 model.add(Flatten()) model.add(Dense(64)) model.add(Activation("relu"))
### Fully connected layer 2 model.add(Dense(32)) model.add(Activation("relu"))
### Fully connected layer 3, output layer must be equal to number of classes model.add(Dense(10)) model.add(Activation("softmax"))
количество фильтров определяем исходя из сложности задачи.
После каждого слоя фильтры увеличиваются. Это из-за того, как работает CNN. После каждого слоя обнаруживаются более сложные признаки и для него используется больше фильтров.
Например — на примере нашего набора данных MNIST. В первом слое фильтр будет отвечать за обнаружение краев, затем он может обнаруживать кривые или круги, таким образом, после каждого слоя он продолжает обнаруживать более крупные объекты.
В случае бинарной классификации сигмовидная активируется в рекомендуемых
Используйте приведенный ниже фрагмент кода, чтобы лучше понять нейронную сеть.
model.summary()
Compile определяет функцию потерь, оптимизатор и метрики.
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=['accuracy'])
Обучение модели
model.fit(x_trainr, y_train, epochs=5, validation_split = 0.3)
если точность проверки ‹ точность, то модель может быть переобученной. Таким образом, цель состоит в том, чтобы сделать точность проверки и точность почти одинаковыми. В случае переобучения мы должны попробовать добавить выпадающие слои.
# Evaluating the accuracy on the test data
test_loss, test_acc = model.evaluate(x_testr, y_test)
print("Test Loss on 10,000 test samples", test_loss)
print("Test Accuracy on 10,000 test samples", test_acc)
predictions = model.predict([x_testr]) print(predictions)
plt.imshow(x_test[0]) print(np.argmax(predictions[0])) # 7
Проверка наших входных изображений
Я создал изображение с номером в краске Windows.
import cv2
img = cv2.imread('three.png')
plt.imshow(img)
img.shape # (28, 28, 3)
# Converting to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray.shape # (28, 28)
# Resizing to a 28x28 image # Please note my image was already in correct dimension resized = cv2.resize(gray, (28,28), interpolation = cv2.INTER_AREA) resized.shape # (28, 28)
# 0-1 scaling newimg = tf.keras.utils.normalize(resized, axis = 1)
# For kernal operations newimg = np.array(newimg).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
newimg.shape # (1, 28, 28, 1)
predictions = model.predict(newimg) print(np.argmax(predictions[0])) # 3
Следовательно, наша модель CNN смогла правильно определить номер.
Сохранение модели
# Saving a Keras model:
model.save('path/to/location')
Чтобы использовать сохраненную модель, запустите приведенный ниже код.
# Loading the model back:
from tensorflow import keras
model = keras.models.load_model('path/to/location')
Вывод
Классификатор CNN действительно мощный. Нам удалось правильно определить номер. По сравнению с MNIST с использованием простой нейронной сети мы получили гораздо лучшую точность, и эта модель также может обрабатывать широкий спектр входных изображений.
Спасибо за чтение.