Цель состоит в том, чтобы создать классификатор для классификации изображения как «кактус» или «не кактус».
Понимание набора данных
Эта классификационная проблема взята из одной из проблем 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%, что удивительно.
Заключение
Основная цель этого поста - поделиться с вами структурой сверточной сети для такого рода задач двоичной классификации, например, классификации изображений кошек и собак. Надеюсь, вы сможете лучше понять этот тип проблемы.