Привет мир !!!

В своем стремлении к обучению Computer vision я начинаю с небольших наборов данных и менее сложных задач. Итак, сегодня я пробую свои силы в задаче kaggle, которая по сути является Image Classification задачей от Kaggle.

пожалуйста, посетите github для ноутбука jupyter

Описание

Чтобы оценить влияние изменения климата на флору и фауну Земли, крайне важно количественно определить, как деятельность человека, такая как лесозаготовки, добыча полезных ископаемых и сельское хозяйство, влияет на наши охраняемые природные территории. Исследователи из Мексики создали проект VIGIA, целью которого является создание системы автономного наблюдения за охраняемыми территориями. Первым шагом в таких усилиях является способность распознавать растительность на охраняемых территориях. В этом конкурсе вам предстоит создать алгоритм, который сможет идентифицировать определенный тип кактуса на аэрофотоснимках.

Оценка

Представления оцениваются по площади под кривой ROC между прогнозируемой вероятностью и наблюдаемой целью.

Данные

Этот набор данных содержит большое количество уменьшенных изображений 32 x 32, содержащих аэрофотоснимки столбчатого кактуса (Neobuxbaumia tetetzo). Kaggle изменил размер изображений из исходного набора данных, чтобы сделать их одинаковыми по размеру. Имя файла изображения соответствует его идентификатору.

Мы должны создать классификатор, способный предсказать, содержит ли изображение кактус.

Файлы

  • train/ — изображения тренировочного множества
  • test/ — изображения тестового набора (вы должны предсказать их метки)
  • train.csv — метки обучающего набора, указывает, есть ли на изображении кактус (has_cactus = 1)
  • sample_submission.csv — образец файла отправки в правильном формате.

Подход

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

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn, gc, time, os, math
from sklearn.model_selection import train_test_split
import tensorflow as tf
print(tf.__version__)
from tensorflow.keras.preprocessing.image import load_img, ImageDataGenerator
seed = 42
np.random.seed(seed)
tf.random.set_seed(seed)

2.3.0

загрузить данные

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

визуализировать данные

Первое, что нужно сделать в машинном обучении, — это самостоятельно понять данные, прежде чем подгонять какую-либо модель. Лучше понимать данные и иметь хорошее представление об особенностях (например, в случае табличных данных), которые могут помочь в подборе кривой и последующей интерпретации модели. В нашем случае мы выберем случайным образом несколько образцов и увидим распределение положительных (на изображении кактусов) и отрицательных (на изображении нет кактусов) классов.

fig,ax = plt.subplots(2,5, figsize=(10,7))
for i, index in enumerate(train_df[train_df["has_cactus"] == 1]["id"][:5]):
    path = os.path.join(train_dir, index)
    img = load_img(path)
    ax[0,i].set_title("Cactus")
    ax[0,i].imshow(img)
    
for i, index in enumerate(train_df[train_df["has_cactus"] == 0]["id"][:5]):
    path = os.path.join(train_dir, index)
    img = load_img(path)
    ax[1,i].set_title("No Cactus")
    ax[1,i].imshow(img)

разделить данные на train и val

Далее мы создадим проверочное разделение, чтобы оценить наше обучение на наборе данных поезда.

print("before split train shape", train_df.shape)
train_df, val_df = train_test_split(train_df, 
                                    test_size=0.2,
                                    stratify=train_df["has_cactus"],
                                    shuffle=True, 
                                    random_state=seed)
train_df = train_df.reset_index(drop=True)
val_df = val_df.reset_index(drop=True)
print("after split train/val shape", train_df.shape, val_df.shape)

перед раздвоенной формой поезда (17500, 2)

после раздельного поезда/вала (14000, 2) (3500, 2)

подготовить данные для моделирования

Загрузка данных с помощью TensorFLow/Keras API из папки, где изображения всех классов собраны в одну папку. Я имею в виду, что для каждого класса нет подпапки. Итак, мы будем использовать класс ImageDataGenerator, который генерирует пакеты тензорных изображений с увеличением данных в реальном времени. Из этого класса мы будем использовать метод flow_from_dataframe, который поможет нам сопоставить идентификаторы изображений с соответствующими изображениями из каталога и сгенерирует пакеты изображений. Мы будем только изменять масштаб и не будем выполнять какие-либо другие аугментации изображений.

img_width, img_height = 32,32
target_size = (img_width, img_height)
batch_size = 32
train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_dataframe(dataframe=train_df,
                                  directory=train_dir,
                                  x_col='id',
                                  y_col='has_cactus',
                                  target_size=target_size,
                                  class_mode='binary',
                                  batch_size=batch_size,
                                  seed = seed)
val_generator = 
val_datagen.flow_from_dataframe(dataframe=val_df,
                                directory=train_dir,
                                x_col='id',
                                y_col='has_cactus',
                                target_size=target_size,
                                class_mode='binary',
                                batch_size=batch_size,
                                seed = seed)

Найдено 14000 проверенных имен файлов изображений, принадлежащих к 2 классам.

Найдено 3500 проверенных имен файлов изображений, принадлежащих к 2 классам.

создание модели CNN с нуля

Создание модели с нуля не всегда является хорошей идеей. У нас не так много доступных образцов, чтобы мы могли полностью использовать (сойтись) сложную модель без переобучения. Кто-то (может быть, научно-исследовательский институт, технологические гиганты и т. д.) мог работать над похожей проблемой и, возможно, обучил огромную модель для нескольких эпох, выполнил точную настройку и позже выложил вес этой модели в открытый доступ. Таким образом, рекомендуется создать модель с нуля и использовать ее в качестве базовой модели, а затем использовать предварительно обученную модель, чтобы улучшить показатели успеха.

Мы будем создавать простую модель сверточных нейронных сетей (CNN), используя слои keras и его functional API for Models. Мы будем использовать Adam (по умолчанию learningRate=0.001) в качестве оптимизатора, binary_crossentropy в качестве потерь и AUC в качестве показателей. Для Callbacks мы использовали LearningRateScheduler для снижения скорости обучения и EarlyStopping на случай, если val_loss не улучшится. Запустить его на 20 эпох должно быть хорошим началом.

inputs = Input(shape=(*target_size, 3))
x = Conv2D(32, (3,3), activation='relu')(inputs)
x = MaxPool2D((2,2))(x)
x = Dropout(0.25)(x)
x = Conv2D(64, (3,3), activation='relu')(x)
x = MaxPool2D((2,2))(x)
x = Dropout(0.25)(x)
x = Conv2D(128, (3,3), activation='relu')(x)
x = MaxPool2D((2,2))(x)
x = Dropout(0.25)(x)
x = GlobalMaxPool2D()(x)
x = Dense(128, activation='relu')(x)
x = Dropout(0.25)(x)
outputs = Dense(1, activation='sigmoid')(x)
model = Model(inputs, outputs)
model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['AUC'])
model.summary()

визуализировать кривую обучения

Очень полезный фрагмент кода для визуализации кривых обучения от tensorflow.

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()),1])
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0,1.0])
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()

предсказание на тестовых данных

test_df = pd.read_csv("sample_submission.csv")
test_dir = '/cp/kaggle/aerial-cactus-identification/test'
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(directory=test_dir,
                                 target_size=target_size,
                                 class_mode='binary',
                                 batch_size=1,
                                 shuffle=False,
                                 seed=seed)

Найдено 4000 изображений, принадлежащих к 1 классу.

# predict on test images
preds = model.predict(test_generator)
test_df["has_cactus"] = preds

Обучение

  • Как загрузить данные с помощью TensorFLow/Keras из каталога изображений.
  • Как визуализировать данные.
  • Как подготовить данные для аугментации.
  • Как написать модель CNN с нуля, используя функциональный API модели keras.
  • Как визуализировать кривые обучения точности/потери для данных train/val.

Прочтите другие мои истории на страницах github iWriteHere или свяжитесь со мной в twitter и linkedin.