Цель состоит в том, чтобы создать классификатор для классификации изображения как «кактус» или «не кактус».

Понимание набора данных

Эта классификационная проблема взята из одной из проблем Kaggle. Цель состоит в том, чтобы создать классификатор для классификации изображения как кактус или не кактус. Обучающая выборка включает 17500 изображений, а валидационная - 4000 изображений. Изображения со следами кактуса находятся в папке cactus и наоборот. Ниже приведены примеры из обучающего набора данных.

Предварительная обработка данных

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

Следовательно, нам нужно будет нормализовать все изображения до одного размера. Согласно нашим экспериментам, оптимальная стратегия - обрезать эти изображения до размера 48 на 48 пикселей. Ниже приведены некоторые из обрезанных изображений. В первой строке показаны исходные изображения, а во второй строке - измененные.

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

Структура и обучение CNN

Сверточная нейронная сеть содержит 3 слоя сверточных слоев и 2 полностью связанных слоя. Каждый сверточный слой имеет фильтр 3 на 3, который принимает шаг 2 с выходом 64 узла. После этого данные проходят через слой максимального объединения, чтобы предотвратить переобучение и извлечь полезную информацию.

model = Sequential()
model.add(Conv2D(64, (3,3), input_shape = X_train.shape[1:]))
model.add(Activation(‘relu’))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation(‘relu’))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation(‘relu’))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Dense(1))
model.add(Activation(‘sigmoid’))
model.compile(loss=”binary_crossentropy”,
optimizer=”adam”,
metrics=[‘accuracy’])
history = model.fit(X_train, Y_train, batch_size=32, epochs=10, validation_split=0.1, use_multiprocessing=True)
model.save(‘model_48_crop’)

Ниже представлен обзор структуры модели.

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

Результат испытаний

Мы используем набор validation_set, предоставленный Kaggle, в качестве тестового набора для окончательного прогноза на нашей обученной модели.

testdata = pd.read_pickle(“pickled_data_validation/crop_images(48, 48).pkl”)
test_images = testdata.loc[:, data.columns != ‘class’]
test_images = test_images.to_numpy()
test_images = test_images.reshape((len(test_images),48, 48, 3))
test_images = test_images/255.0
print(test_images.shape)
test_labels = testdata[‘class’]
test_labels = test_labels.to_numpy()
type(test_labels)
test_labels = test_labels.reshape((len(test_labels),1))
loss, acc = new_model.evaluate(test_images, test_labels, verbose=2)
print(‘Restored model, accuracy: {:5.2f}%’.format(100*acc))

Вот результат. Его точность достигает почти 99%, что удивительно.

Заключение

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