Я читаю «Глубокое обучение с помощью Python» Франсуа Шолле и, будучи новичком в области глубокого обучения, решил применить то, что узнал, к набору данных Kaggle. Я выбрал Intel Image Classification, потому что это базовый набор данных для применения моих новых навыков.

О наборе данных классификации изображений Intel:

  • Около 25000 изображений размером 150 x 150 пикселей каждое.
  • Существует шесть категорий: Здания (0), Лес (1), Ледник (2), Горы (3), Море (4) и Улица (5).

  • Каталог состоит из 3 папок: Seq_train (14 тыс. образцов), Seq_test (7 тыс. образцов) и Seq_pred (3 тыс. образцов).

Подготовка набора данных:

Мы ничего не можем сделать с папками изображений, а значит нам нужно конвертировать эти директории в наборы данных. Функция TensorFlow image_dataset_from_directory позволяет нам вводить папку с разными классами и возвращает BatchDataset со всеми обучающими образцами и обучающими метками.

BatchDataset – это объект, состоящий из тензоров выборок и меток:

train_dir = pathlib.Path("Intel_Image_classification//archive (1)//seg_train//seg_train")
test_dir = pathlib.Path("Intel_Image_classification//archive (1)//seg_test//seg_test")
train_dataset = tf.keras.preprocessing.image_dataset_from_directory( #!!! Reminder, make label_mode = catagorical
    train_dir,
    image_size=(150, 150), # Size of the images
    batch_size=64) # Creating Batches of size 64

for images, labels in train_dataset: # Enumerating through the images and labels
    print(images.shape)# Returns (64,150,150,3)
    print(images[4])
    print(labels.shape)# Returns (64,)
    print(labels[4])
    break

Другой метод предварительной обработки импорта, который нам нужно применить к данным, — это их нормализация. Это означает, что нам нужно изменить масштаб векторов с [0,255] на [0,1]. Преимущество уменьшения масштаба заключается в том, что градиентный спуск будет быстрее и будет легче сходиться. Мы будем масштабировать данные позже в процессе построения модели.

Построение и обучение многослойной плотной модели:

Первая модель, которую мы будем использовать, — это базовая многослойная плотная модель. Мы будем использовать Sequential API для этой модели. Sequential API — это просто список различных слоев, которые мы хотим использовать в нашей модели. Эта модель Dense будет состоять из 6 Dense Layers, 1 Flatten Layer и 1 Rescaling Layer:

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Rescaling(scale=1./255)
    layers.Flatten(),
    layers.Dense(1024,activation="relu"),
    layers.Dense(512,activation="relu"),
    layers.Dense(128,activation="relu"),
    layers.Dense(64,activation="relu"),
    layers.Dense(32,activation="relu"),
    layers.Dense(6, activation="softmax")
])
  1. Сначала мы масштабируем наши данные с [0,255] на [0,1], чтобы быстрее пройти градиентный спуск.
  2. Мы используем слой Flatten(), который превратит наши трехмерные тензоры в одномерные. Например, вектор формы (150,150,3) преобразуется в вектор формы (675000). Вот как Dense Layers лучше всего воспринимает тензоры изображений. * При построении CNN этот шаг изначально не потребуется.
  3. Далее мы будем использовать 5 плотных слоев с уменьшающимися единицами и функциями активации ReLU. Функция активации ReLU заменит все отрицательные числа нулем и имеет тенденцию сходиться быстрее, чем другие функции активации. Мы используем убывающие единицы, потому что по мере того, как мы углубляемся в модель, мы изучаем менее сложные и абстрактные функции.
  4. Последний слой имеет 6 единиц, потому что он выводит (0–5) один из шести различных классов изображений. Мы используем функцию активации softmax, которая вернет распределение вероятности того, к какому классу, скорее всего, относится изображение.

Мы будем обучать эту модель с помощью функций model.compile() и model.fit(). В качестве параметров мы будем использовать оптимизатор rmsprop, потери sparse_categorical_crossentropy и показатель точности. Для функции model.fit() я выбрал 10 эпох, потому что мой компьютер не очень быстрый, и каждая эпоха занимала около 83 секунд.

model.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy",metrics=["accuracy"])
history = model.fit(
    train_dataset,
    batch_size=64,
    epochs=10)

Конечным результатом была точность 62,5%. Эта ошибка не очень хороша и может быть некоторое улучшение. Используя Matplotlib, мы построили график зависимости точности от эпохи:

Построение и обучение модели на основе CNN:

Чтобы повысить точность, теперь мы будем использовать сверточные слои в нашей модели. Архитектура будет состоять из 2 слоев Conv2D, 2 слоев MaxPooling2D, 1 слоя Dropout, 1 слоя Flatten и 1 слоя Dense:

model = keras.Sequential(
    [
        keras.Input(shape=(150,150,3)),
        layers.Rescaling(scale=1./255),
        layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
        layers.MaxPooling2D(pool_size=(2, 2)),
        layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
        layers.MaxPooling2D(pool_size=(2, 2)),
        layers.Flatten(),
        layers.Dropout(0.5),
        layers.Dense(6, activation="softmax"),
    ]
)
  1. Мы используем увеличивающиеся размеры фильтра для сверточных слоев, потому что мы начинаем с изучения абстрактных деталей, а каждый последующий слой изучает более общие детали. Еще один средний блог, который объясняет, как работают сверточные слои.
  2. MaxPooling — это уменьшение выборки карт объектов на 1/2. Максимальное объединение будет извлекать входные данные из карты объектов и выводить максимальное значение из этого окна.
  3. Мы сглаживаем данные, прежде чем пропустить их через плотные слои.
  4. Слой Dropout предотвратит переоснащение, игнорируя случайные нейроны в модели и не присваивая определенные веса определенным нейронам. Это, в свою очередь, делает модель более вероятной для обобщения будущих данных.

При обучении этой модели мы будем использовать те же параметры, что и модель Dense, за исключением того, что мы изменим оптимизатор на оптимизатор adam. Оптимизатор Адама является эффективным алгоритмом при работе с большими объемами данных, а также при классификации изображений.

model.summary()
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy",metrics=["accuracy"])
history = model.fit(
    train_dataset,
    batch_size=64,
    epochs=10)

К счастью, после обучения этой модели мы получили точность 95,77%. Это огромное улучшение по сравнению с моделью Dense.

Я попытался улучшить эту точность с помощью Data Augmentation, но повышения точности не произошло. Увеличение данных — это когда вы изменяете мелкие детали изображения (например, вращение, отражение, масштабирование) и добавляете их в свой набор данных.

data_augmentation = keras.Sequential(
    [
        layers.RandomFlip("horizontal"),# Horizontal flip to 50% of the images
        layers.RandomRotation(0.1), # Random Rotation between [-10%(-36 degrees), 10%(36 degrees)]
        layers.RandomZoom(0.2), # Random zoom factor between [-20%, 20%]
    ]
)

Благодаря этим двум примерам можно многое узнать о мелких деталях, благодаря которым нейронная сеть работает. На мой взгляд, лучший способ научиться — это экспериментировать с разными параметрами, разными типами слоев, разными оптимизаторами и стратегиями предварительной обработки. Kaggle — отличный ресурс для отработки навыков машинного обучения.

Спасибо, что прочитали эту статью, и я надеюсь, что вы что-то узнали.