Примечание. Этот пост также можно прочитать здесь
Обратите внимание, что после написания этого сообщения NudeDetector, NudeClassifier сильно изменились. Основные изменения
- 10-кратное увеличение данных, обнаружение большего количества деталей (Checkout https://github.com/notAI-tech/NudeNet/ )
- Автоматическая загрузка файлов контрольных точек и поддержка Windows.
- В 2 раза более быстрая модель по умолчанию и в 6 раз более быстрый «быстрый» режим обнаружения.
- Поддержка обнаружения видео с помощью интеллектуального выбора кадра.
- Поддержка Tf Lite для NudeCLassifier
Часть 1: обнаружение обнаженной натуры с классификацией изображений
С появлением превосходных библиотек DL и множества реализаций и документов с открытым исходным кодом, классификацию изображений стало очень легко реализовать. То есть если у вас есть набор данных. Доступно множество открытых наборов данных для тестирования и уточнения моделей классификации. Но получить набор данных для конкретной задачи сложно. Обнаружение обнаженной натуры / NSFW - один из таких вариантов использования, когда отсутствуют практически полезные открытые наборы данных.
В первой части этого проекта, состоящего из двух частей, я собираю данные и реализую обнаружение наготы с помощью классификации изображений. Моя цель - создать хороший набор данных с открытым исходным кодом для этого варианта использования и предоставить для него предварительно обученную модель. Во второй части я стремлюсь реализовать обнаружение частных / открытых частей с открытым исходным кодом с помощью Object Detection.
Почему? Я искренне верю, что нельзя изобретать колесо заново. На момент запуска этого проекта Yahoo open_nsfw был единственным доступным прилично работающим модулем обнаружения обнаженной натуры. Он устарел, и данные недоступны для общественности. Нет (AFAIK) проектов с открытым исходным кодом, доступных для цензуры открытых частей.
Сбор изображений обнаженной натуры: для получения этих изображений я начал с Reddit. Я составил список под-реддитов NSFW, в основном собранных из скроллера веб-сайтов (благодаря упорной работе / u / faroix). После использования отличного приложения RipMe для загрузки ~ 1000 изображений из каждого из этих суб-реддитов и просмотра их (не рекомендуется для легкомысленных) я обнаружил серьезную проблему с этими данными.
Почти все собранные изображения из этих суб-реддитов очень высокого качества. Фактически, вместе взятых этих образов получилось ~ 260 ГБ. Это не идеально, поскольку много порнографии картофельного качества. Чтобы уравновесить это, я сканировал эскизы видео с PornHub.
Пока я делал это, другой энтузиаст открытого исходного кода, GantMan, сделал открытый исходный код модели, обученной на данных, собранных alexkimxyz. Итак, я связался с GantMan и получил набор данных, который он использовал.
# Resizing and removing duplicates mogrify -geometry x320 * fdupes -rdN ./
После использования двух вышеуказанных команд для уменьшения нормализации изображений и удаления дубликатов я получил 1,78,601 из PornHub, 1,21,644 из Reddit и 1, 30 266 из набора данных GantMan.
Сбор безопасных изображений:. После того, как я закончил сбор изображений обнаженной натуры, я подумал, что трудная часть уже позади, и я не мог ошибиться. Собрать несколько случайных изображений будет очень легко, но в результате классификатор научится классифицировать всех людей по категории обнаженных. Поскольку нейронные сети пытаются минимизировать потери, отсутствие большого количества человеческих изображений в категории «безопасные» приведет к тому, что наша модель будет «детектором человека» (что является простой задачей), а не «детектор наготы».
Для создания хорошего классификатора мне понадобилось много изображений без обнаженной натуры, на которых изображены люди. Изучив данные sfw GantMan, я заметил, что, хотя общее количество изображений приличное, количество изображений с людьми на них было очень меньше.
Поразмыслив, я понял, что Facebook - отличное место для сбора изображений. с людьми в них. Итак, я просканировал изображения профиля Facebook, используя их Graph API. Я также составил список безопасных под-реддитов и просканировал ~ 1000 изображений с каждого из них, используя ripme. После изменения размера и очистки я получил 68 948 из Facebook, 98 359 из набора данных GantMan и 55 137 из Reddit.
Конвейер обработки: я использовал отличную библиотеку увеличения изображений Augmentor с некоторыми добавленными средствами защиты от сбоев для увеличения изображения на лету, чтобы использовать его с fit_generator Кераса.
Следующий фрагмент - это расширение, используемое для обучающих данных.
# Random rotation, flips, zoom, distortion, contrast, skew and brightness pipeline.rotate(probability=0.2, max_left_rotation=20, max_right_rotation=20) pipeline.flip_left_right(probability=0.4) pipeline.flip_top_bottom(probability=0.8) pipeline.zoom(probability=0.2, min_factor=1.1, max_factor=1.5) pipeline.random_distortion(probability=0.2, grid_width=4, grid_height=4, magnitude=8)pipeline.random_brightness(probability=0.2, min_factor=0.5, max_factor=3)pipeline.random_color(probability=0.2, min_factor=0.5, max_factor=3) pipeline.random_contrast(probability=0.2, min_factor=0.5, max_factor=3) pipeline.skew(probability=0.2, magnitude=0.4)
Обучение: для обучения я арендовал машину с GTX 1080Ti, с 12 ГБ виртуальной памяти и 64 ГБ системной памяти на сайте created.ai за 0,11 доллара в час. Я смог использовать пакет размером 32 с размером входного изображения Xception и 256x256.
Примечание. Реализации моделей классификации изображений, представленные в приложениях Keras, не используют какой-либо тип регуляризации. Для добавления регуляризации (выпадения или l2) выполните цикл по каждому слою и добавьте регуляризацию.
# For l2
for layer in model.layers: layer.W_regularizer = l2(..)
# Or for dropout add dropout between the fully connected layers and redefine the model using functional API.
Используя SGD с импульсом, модель сходится с точностью до 0,9347 по данным GantMan.
Оценка. Найти правильные данные для оценки модуля обнаружения обнаженного тела очень сложно. Нагота / порно имеет тысячи вариаций (см. Правило 34), и построить исчерпывающие тестовые данные практически невозможно. Но чтобы получить простое представление о том, как это работает, я использую данные, собранные Адитьей по адресу https://towardsdatascience.com/comparison-of-the-best-nsfw-image-moderation-apis-2018-84be8da65303. . Обратите внимание, что даже это не очень хорошие тестовые данные. Лучший способ проверить и улучшить что-то подобное - это помощь сообщества. Поскольку его тестовые данные относятся к разным категориям, я сопоставляю категории nsfw_porn, nsfw_explicit_nudity, nsfw_simulated_porn с категорией nude, а категорию sfw - с безопасным. .
Для тестирования с тестовыми данными GantMan я сопоставляю классы «хентай», «порно» с категорией «обнаженное тело», а «рисунки», «нейтральный», «сексуальный» - с категорией безопасности. Это потому, что, согласно его определению классов, обнаженные люди будут помечены как «порно», а обнаженные в мультфильмах - как «хентай».
Как ни странно, все три проекта получают одинаковые оценки, хотя и терпят неудачу на разных изображениях. Например, модель Гантмана, как ни странно, не работает с изображениями Джеффа Голдблюма, тогда как NudeNet - нет. Точно так же NudeNet терпит неудачу с некоторыми изображениями, в отличие от модели GantMan. За пару месяцев работы над этим проектом я наткнулся на множество изображений, для которых API облачного видения Google терпит неудачу. Поскольку большинство этих изображений являются NSFW (да!), я не могу добавьте их сюда. Если вы хотите взглянуть на некоторые из этих примеров, оставьте комментарий.
Обновление: мне удалось найти еще один вручную подобранный набор данных для тестирования. Этот набор данных доступен по адресу https://dataturks.com/projects/Mohan/NSFW(Nudity%20Detection)%20Image%20Moderation%20Datatset.
Проект можно найти по адресу https://github.com/bedapudi6788/NudeNet.
Предварительно обученные модели на https://github.com/bedapudi6788/NudeNet-models/
Чтобы установить и использовать NudeNet, взгляните на следующий фрагмент.
# installing the project
pip install git+https://github.com/bedapudi6788/NudeNet
# Using the classifier
from NudeNet import NudeClassifier
classifier = NudeClassifier('classifier_checkpoint_path')
classifier.classify('path_to_nude_image')
Во второй части этой статьи я реализую обнаружение открытых частей и цензуру с помощью обнаружения объектов. Вы можете найти вторую часть этого сообщения на странице https://medium.com/@praneethbedapudi/nudenet-an-ensemble-of-neural-nets-for-nudity-detection-and-censoring-c8fcefa6cc92?source=friends_link&sk=f0a4786bf005cd4b25e89c
Изменить: данные доступны