Як створити простий класифікатор зображень

Класифікація зображень - це дивовижне застосування глибокого навчання. Ми можемо навчити потужний алгоритм для моделювання великого набору зображень. Потім цю модель можна використовувати для класифікації подібного, але невідомого набору зображень.

Немає обмежень у застосуванні класифікації зображень. Ви можете використовувати його у своєму наступному додатку або використовувати для вирішення якоїсь реальної проблеми. Це все залежить від вас. Але для когось, хто є досить новим у цій царині, це може здатися спочатку дуже складним завданням. Як мені отримати свої дані? Як мені побудувати свою модель? Які інструменти слід використовувати?

У цій статті ми обговоримо все це - від пошуку набору даних до навчання вашої моделі. Я спробую зробити речі максимально простими, уникаючи деяких технічних деталей ( PS: Будь ласка, зауважте, що це не означає, що ці деталі не важливі. Я згадаю декілька чудових ресурсів, на які ви можете звернутися, щоб дізнатись більше про ці теми ). Мета цієї статті - пояснити основний процес побудови класифікатора зображень, і саме на цьому ми більше зосередимось тут.

Ми створимо класифікатор зображень для набору даних Fashion-MNIST. Набір даних Fashion-MNIST - це колекція зображень статей Zalando. Він містить 60 000 зображень для навчального набору та 10 000 зображень для даних тестового набору ( ми будемо обговорювати тестові та навчальні набори даних разом із набором даних перевірки пізніше ). Ці зображення належать до ярликів 10 різних класів.

Імпорт бібліотек

Наша мета - навчити модель глибокого навчання, яка може класифікувати заданий набір зображень до одного з цих 10 класів. Тепер, коли у нас є наш набір даних, нам слід перейти до необхідних нам інструментів. Існує багато бібліотек та інструментів, які ви можете вибрати, виходячи із власних вимог проекту. Для цього я дотримуватимусь наступного:

  1. Numpy - бібліотека Python для чисельних обчислень
  2. Pandas - Маніпулювання даними бібліотеки Python
  3. Matplotlib - Візуалізація даних бібліотеки Python
  4. Keras - бібліотека Python на основі tensorflow для створення моделей глибокого навчання
  5. Юпітер - Я буду запускати весь свій код на блокнотах Юпітера. Ви можете встановити його за посиланням. Ви також можете використовувати Google Colabs, якщо вам потрібна краща обчислювальна потужність.

Разом із цими чотирма ми також будемо використовувати scikit-learn. Призначення цих бібліотек стане більш зрозумілим, як тільки ми зануримось у код.

Добре! У нас є готові наші інструменти та бібліотеки. Тепер слід розпочати налаштування нашого коду.

Почніть з імпорту всіх вищезазначених бібліотек. Разом із імпортом бібліотек я також імпортував деякі конкретні модулі з цих бібліотек. Дозвольте мені пройти їх по одному.

import numpy as np import pandas as pd import matplotlib.pyplot as plt import keras from sklearn.model_selection import train_test_split from keras.utils import to_categorical from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Dense, Dropout from keras.layers import Flatten, BatchNormalization

train_test_split: Цей модуль розділяє набір навчальних даних на дані навчання та перевірки. Причиною цього розколу є перевірка, чи наша модель переобладнана чи ні. Ми використовуємо навчальний набір даних для навчання нашої моделі, а потім порівняємо отриману точність з точністю перевірки. Якщо різниця між обома величинами значно велика, то наша модель, ймовірно, переобладнана. Ми ще раз повторимо наш процес побудови моделей та впродовж необхідних змін. Після того, як ми будемо задоволені нашою точністю навчання та перевірки, ми зробимо остаточні прогнози на основі даних тесту.

to_categorical: to_categorical - утиліта keras. Він використовується для перетворення категоріальних міток в одноразове кодування. Скажімо, у нас є три мітки ("яблука", "апельсини", "банани"), тоді одне гаряче кодування для кожного з них буде [1, 0, 0] -> "яблука", [0, 1, 0] -> "апельсини", [0, 0, 1] -> "банани".

Решта імпортованих нами модулів Keras - це згорткові шари. Ми обговоримо згорткові шари, коли почнемо будувати свою модель. Ми також швидко переглянемо, що робить кожен із цих шарів.

Попередня обробка даних

Поки що ми переключимо нашу увагу на отримання наших даних та їх аналіз. Ви завжди повинні пам’ятати про важливість попередньої обробки та аналізу даних. Це не тільки дає вам уявлення про дані, але й допомагає виявити невідповідності.

Дуже незначні коливання даних іноді можуть призвести до руйнівних результатів для вашої моделі. Це робить важливим попередню обробку даних перед використанням їх для навчання. Тож маючи це на увазі, почнемо попередню обробку даних.

train_df = pd.read_csv('./fashion-mnist_train.csv') test_df = pd.read_csv('./fashion-mnist_test.csv')

Перш за все, давайте імпортуємо наш набір даних ( ось посилання для завантаження цього набору даних у вашу систему ). Після імпорту набору даних виконайте наступну команду.

train_df.head()

Ця команда покаже, як виглядають ваші дані. На наступному скріншоті показано результати цієї команди.

Ми можемо бачити, як наші дані зображень зберігаються у вигляді піксельних значень. Але ми не можемо подавати дані на нашу модель у такому форматі. Отже, нам доведеться перетворити його в масиви numpy.

train_data = np.array(train_df.iloc[:, 1:]) test_data = np.array(test_df.iloc[:, 1:])

Тепер настав час отримати наші етикетки.

train_labels = to_categorical(train_df.iloc[:, 0]) test_labels = to_categorical(test_df.iloc[:, 0])

Тут ви бачите, що ми використовували to_categorical для перетворення наших категоріальних даних в одне гаряче кодування.

Тепер ми переформуємо дані та перекинемо їх у тип float32, щоб ми могли зручно ними користуватися.

rows, cols = 28, 28 train_data = train_data.reshape(train_data.shape[0], rows, cols, 1) test_data = test_data.reshape(test_data.shape[0], rows, cols, 1) train_data = train_data.astype('float32') test_data = test_data.astype('float32')

Ми майже закінчили. Давайте просто закінчимо попередню обробку наших даних, нормалізуючи їх. Нормалізація даних зображення приведе до відображення всіх значень пікселів кожного зображення до значень від 0 до 1. Це допомагає нам зменшити невідповідність даних. Перш ніж нормалізувати дані зображення можуть мати великі варіації значень пікселів, що може призвести до якоїсь незвичної поведінки під час тренувального процесу.

train_data /= 255.0 test_data /= 255.0

Свертові нейронні мережі

Отже, попередня обробка даних виконана. Тепер ми можемо почати будувати свою модель. Ми побудуємо згорткову нейронну мережу для моделювання даних зображення. CNN - це модифіковані версії звичайних нейронних мереж. Вони модифіковані спеціально для даних зображень. Подача зображень до звичайних нейронних мереж вимагала б від нашої мережі великої кількості вхідних нейронів. Наприклад, лише для зображення розміром 28x28 нам знадобилося б 784 вхідних нейронів. Це створило б величезну кашу параметрів навчання.

CNN вирішують цю проблему, припускаючи, що вхідним сигналом буде зображення. Основна мета згорткових нейронних мереж - скористатися просторовою структурою зображення та витягти з нього особливості високого рівня, а потім тренуватися над цими особливостями. Це робиться шляхом виконання операції згортки матриці значень пікселів.

The visualization above shows how convolution operation works. And the Conv2D layer we imported earlier does the same thing. The first matrix (from the left) in the demonstration is the input to the convolutional layer. Then another matrix called "filter" or "kernel" is multiplied (matrix multiplication) to each window of the input matrix. The output of this multiplication is the input to the next layer.

Other than convolutional layers, a typical CNN also has two other types of layers: 1) a  pooling layer, and 2) a fully connected layer.

Pooling layers are used to generalize the output of the convolutional layers. Along with generalizing, it also reduces the number of parameters in the model by down-sampling the output of the convolutional layer.

As we just learned, convolutional layers represent high level features from image data. Fully connected layers use these high level features to train the parameters and to learn to classify those images.

We will also use the Dropout, Batch-normalization and Flatten layers in addition to the layers mentioned above. Flatten layer converts the output of convolutional layers into a one dimensional feature vector. It is important to flatten the outputs because Dense (Fully connected) layers only accept a feature vector as input. Dropout and Batch-normalization layers are for preventing the model from overfitting.

train_x, val_x, train_y, val_y = train_test_split(train_data, train_labels, test_size=0.2) batch_size = 256 epochs = 5 input_shape = (rows, cols, 1)
def baseline_model(): model = Sequential() model.add(BatchNormalization(input_shape=input_shape)) model.add(Conv2D(32, (3, 3), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2))) model.add(Dropout(0.25)) model.add(BatchNormalization()) model.add(Conv2D(32, (3, 3), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation="relu")) model.add(Dropout(0.5)) model.add(Dense(10, activation="softmax")) return model

The code that you see above is the code for our CNN model. You can structure these layers in many different ways to get good results. There are many popular CNN architectures which give state of the art results. Here, I have just created my own simple architecture for the purpose of this problem. Feel free to try your own and let me know what results you get :)

Training the model

Once you have created the model you can import it and then compile it by using the code below.

model = baseline_model() model.compile(loss='categorical_crossentropy', optimizer="sgd", metrics=['accuracy']) 

model.compile configures the learning process for our model. We have passed it three arguments. These arguments define the loss function for our model, optimizer and metrics.

history = model.fit(train_x, train_y, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(val_x, val_y)) 

And finally by running the code above you can train your model. I am training this model for just five epochs but you can increase the number of epochs. After your training process is completed you can make predictions on the test set by using the following code.

predictions= model.predict(test_data)

Conclusion

Congrats! You did it, you have taken your first step into the amazing world of computer vision.

You have created a your own image classifier. Even though this is a great achievement, we have just scratched the surface.

There is a lot you can do with CNNs. The applications are limitless. I hope that this article helped you to get an understanding of how the process of training these models works.

Working on other datasets on your own will help you understand this even better. I have also created a GitHub repository for the code I used in this article. So, if this article was useful for you please let me know.

If you have any questions or you want to share your own results or if you just want to say "hi", feel free to hit me up on twitter, and I'll try to do my best to help you. And finally Thanks a lot for reading this article!! :)