Мы учимся обучать сверточную нейронную сеть классифицировать фото и не фото изображения менее чем за 10 минут в бесплатной графической среде Google Colab.

Создание обучающего набора данных

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

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

Нам понадобится 2 набора примеров изображений для каждого из классов. Одна из возможностей — использовать поиск изображений Google, чтобы получить достаточно большой набор изображений, а затем вручную уточнить каждый класс, чтобы оставить только релевантные. Альтернатива, которую мы бы использовали, еще проще. Мы подключаемся к Google Фото и используем Library API для перечисления фотографий и документов/скриншотов и т. д. изображений, затем загружаем и сохраняем их для обучения и проверки.

#https://developers.google.com/photos/library/reference/rest/v1/mediaItems/search#Filters
results = service.mediaItems().search(body={
    'pageSize':20,
    'filters': {
        'contentFilter': {
            'includedContentCategories': [
                "UTILITY"
            ]
        }
    }
}).execute()
items = results.get('mediaItems', [])

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

#https://developers.google.com/photos/library/guides/access-media-items#base-urls
def download_image(base_url, size=None, crop=False):
  url = base_url
  if size:
    (width, height) = size
    url+=f"=w{width}-h{height}"
    if crop:
      url+="-c"
  else:    
    url+="=d" # get with exif
  resp = urllib.request.urlopen(url)
  data = resp.read()
  image = np.asarray(bytearray(data), dtype="uint8")
  image = cv2.imdecode(image, cv2.IMREAD_COLOR)
  return image

Мы загружаем изображения, измененные до 299x299 пикселей, в 2 папки, что позволяет создать обучающую модель CNN с библиотекой Fast.AI, используя удобную оболочку.

!du -h --max-depth=1 "{PATH}"
18M /content/drive/My Drive/Datasets/Photo-vs-NonPhoto/non-photo 
23M /content/drive/My Drive/Datasets/Photo-vs-NonPhoto/photo

Обучение бинарного классификатора CNN

Fast.AI имеет удобный метод создания обучающего модуля CNN для задач классификации из образцов, организованных в папку, соответствующую классам — ImageDataBunch.from_folder. Следует иметь в виду, что мы не хотим применять преобразования увеличения данных к не-фотографиям, поскольку это может привести к непоследовательному сигналу, которого нет в реальной жизни.

# We load samples from folders by class name (photo, non-photo) and split the ~1K samples into training and validation sets
data = ImageDataBunch.from_folder(
    path=PATH,         # path to the dataset
    valid_pct=0.10,    # percentage of samples to use for the validation
    size=299,          # all images are resized to this size
    bs=128,            # the number of images in a traing batch size, change to fit into GPU memory
    ds_tfms=get_transforms(do_flip=False, flip_vert=False, max_rotate=0., max_zoom=0., max_warp=False, max_lighting=False)
).normalize(imagenet_stats)

Мы создаем учащегося ResNet34 CNN и добавляем к нему метрику точности, чтобы понять производительность во время обучения и проверки.

# create a CNN model with weights pre-initialized from ImageNet training
learn = create_cnn(data, models.resnet34)
# add validation metrics to track progress
learn.metrics = [accuracy]

Затем мы обучаем использование трансферного обучения и обучаем только последние полностью подключенные слои нашей сети ResNet34, предварительно обученные на ~ 1,5 млн изображений ImageNet.

Как видите, всего за 2 тренировочных периода и 49 секунд мы достигли точности 82%. Давайте пойдем дальше с тренировкой в ​​один цикл.

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

learn.validate(metrics=[accuracy])
[0.029595109, tensor(0.9938)]

Ничего себе — точность 99,38% всего за 8 минут тренировки! И не только это — создание набора данных, конвейер данных, среда обучения, а также экземпляр графического процессора были предоставлены Google бесплатно.

Наслаждайтесь высвобожденной силой глубокого обучения и экспериментируйте со своими данными с помощью общей записной книжки Colab для этого поста — Классификатор фото против не-фото.

В следующем посте мы обратим внимание на кластеризацию похожих изображений и выбор лучшего из набора.