Как создать свой датасет с Киркоровым и Фейсом на Яндекс.Толоке


    Нейронными сетями уже никого не удивишь. Практически каждый человек знает, что такое машинное обучение, линейная регрессия, random forest. Каждый год тысячи людей проходят курсы по машинному обучению на ODS и Coursera. Любой школьник за пару недель теперь может освоить keras и клепать нейроночки. Но в нейронных сетях, как и во всем машинном обучении, помимо создания хорошего алгоритма, необходимы данные, на которых алгоритм будет обучаться.


    Разрешите представиться, меня зовут Куцев Роман. Я работаю в RnD команде в Prisma AI и занимаюсь созданием датасетов под наши задачи.


    Итак, вдруг поступает продуктовый запрос: нам срочно нужна нейронка, которая будет отличать Киркорова от Фейсa (конечно, пример вымышленный, мы такой ерундой не занимаемся).
    Спрашиваю у Антона (главный по нейронкам), в каком виде нужны данные, в ответ слышу: “Две папки, в одной изображения Фейсa, в другой Киркорова, желательно где-то по 500 изображений на класс, и чтобы 299х299 были”.


    Где найти данные?


    1. Смотрим публичные датасеты, такие как ImageNet, COCO, openimages.
    2. Если нужных размеченных данных в популярных публичных датасетах нет, то гуглим, открываем на arxiv.org статьи по этим темам в надежде, что где-нибудь там будет ссылка на нужный нам датасет.
    3. Если первые два пункта провалились, значит нужного датасета нет, и его надо создать!

    Очевидно, что никто раньше не занимался задачей классификации Киркорова и Фейса. Поэтому придется самим создать такой датасет.


    Пайплайн такой:


    1. Скачиваем из гугла по 1к изображений Киркорова и Фейса.
    2. Ресайзим к нужному размеру.
    3. Проверяем их фрилансерами на Яндекс Толоке.

    Для скачивания воспользуемся Google Images Download.


    В терминале пишем:


    googleimagesdownload -k ‘Киркоров’ -l 1000 -t photo -s '>400*300' -o 'Kirkorov'
    googleimagesdownload -k ‘репер Face’ -l 1000 -t photo -s '>400*300' -o 'Face'

    (на самом деле все не так просто, за один запрос можно скачать только 100 изображений, поэтому приходится выкачивать с разными настройками)


    Сразу ресайзнем изображения до размера 299х299, для этого я набросал такую функцию:


    from PIL import Image
    import multiprocessing, time, os
    def resize_img(img_path):
        img = Image.open(os.path.join('Kirkorov',img_path))
        img = img.resize((299,299), Image.ANTIALIAS)
        img.save(os.path.join('Kirkorov_resize',img_path)) 
    
    num_processes = multiprocessing.cpu_count()
    pool = multiprocessing.Pool(processes=num_processes)
    st = time.time()
    pool.map(resize_img, os.listdir('Kirkorov'))
    print("Execution time: ", time.time()-st)

    Посмотрев на изображения, видим, что в основном скачались нужные изображения, но местами присутствует мусор.






    Отлично, первые два пункта готовы, остался третий.


    Если вы до сих пор не знаете, что такое Яндекс Толока, то советую прочитать эту и эту статью.


    В двух словах: Толока — фриланс биржа на стероидах, где заказчик создает задание, загружает данные и фрилансеры его выполняют. Конечно, есть и другие инструменты для разметки, но для данной задачи удобнее всего воспользоваться Толокой.


    Как начать пользоваться Яндекс Толокой:


    1. Регистрируемся на sandbox.toloka.yandex.ru и toloka.yandex.ru в качестве заказчика (sandbox — песочница, в которой вы создаете задания, проверяете на корректность со стороны фрилансеров, и, если все хорошо, переносите его в toloka.yandex.ru).


    2. В личном кабинете toloka.yandex.ru пополняем свой баланс.


    3. В sandbox.toloka.yandex.ru во вкладке "Проекты" выбираем "Создать проект".



    4. Вам будут предложены готовые шаблоны. Из всех шаблонов нам лучше всего подходит шаблон "Категоризация изображений". Выбираем его.



    5. Создаем инструкцию для фрилансеров и название проекта.



    6. Во входных параметрах к заданию у нас будет URL на изображение. В выходных: строка output. Интерфейс задания пишется на html и javascript (это очень удобно, так как практически под любую задачу мы можем сверстать страничку, которая будет показываться исполнителям). Чуть-чуть изменяем шаблон html, и все готово. Сохраняем проект.



    7. Проект готов. Теперь можно добавить пул заданий. В данной статье я не буду создавать пул обучения (надеясь на то, что фрилансеры способны сразу выполнить наше наисложнейшее задание). Но вы всегда создавайте в своем задании пул обучения. Это позволит:


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

    Придумываем название пула (оно видно только нам). Задаем цену 0.01$ за страницу заданий. Жадный Яндекс берет комиссию 0.005$. Время на задание: 10 минут. Перекрытие: 3 (каждая наша фотография будет показываться трем разным людям). Включим "КОНТЕНТ ДЛЯ ВЗРОСЛЫХ", а то мало-ли что плохого мы из интернета могли скачать. И активируем "ОТЛОЖЕННАЯ ПРИЕМКА", чтобы не дать денег тем фрилансерам, которые будут плохо выполнять задание.



    Далее идет пункт: "ТРЕБОВАНИЯ К ПОЛЬЗОВАТЕЛЯМ", в котором мы можем предъявить требования к исполнителям. В нашем случае исполнитель должен быть из России и владеть русским языком. Каждый исполнитель имеет свой рейтинг и мы можем выбрать исполнителей только с хорошим рейтингом. Выберем 80% лучших исполнителей.



    Самым важным и самым сложным в плане освоения является блок контроля качества. Отдельное его описание потянет на целую статью, так что рекомендую ознакомиться с ним самостоятельно. В нашем проекте я выбрал ограничение на быстрые ответы. Если исполнитель 3 раза из 5 отвечает быстрее, чем за 40 секунд, то система его заблокирует.



    Отлично, мы на финишной прямой, осталось чуть-чуть. Сохраняем пул.


    8. В созданном пуле скачиваем пример загрузочного файла. Загружаем наши изображения на Яндекс Диск или к себе на сервер, чтобы они были доступны по ссылке. В поле "INPUT:image" вставляем URL на наши изображения. Пример:


    INPUT:image
    http://kucev.ru/Kirkorov/Kirkorov-pink_17_ 21787_l_jpg.jpg
    http://kucev.ru/Kirkorov/Kirkorov-green_82_ hqdefault_jpg.jpg
    http://kucev.ru/Kirkorov/Kirkorov-pink_25_ hqdefault_jpg.jpg

    Загружаем полученный tsv файл на Яндекс Толоку. Указываем сколько изображений будет показываться исполнителю за один раз.



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



    9. Теперь нам надо проверить, что со стороны исполнителя все отображается правильно. Для этого создаем новый аккаунт на sandbox.toloka.yandex.ru, только теперь в качестве исполнителя. В аккаунте заказчика выбираем вкладку "Пользователи" и добавляем наш новый аккаунт исполнителя в список доверенных пользователей.



    Отлично, если наш пул запущен, то теперь из тестового аккаунта исполнителя доступно наше задание.



    Нажимаем "Продолжить". Вот так будет выглядеть наша страничка для исполнителей:



    Проверяем, что все работает правильно и никаких багов не возникает.


    10. Если вы довольны результатом, то пора отпустить младенца в большой мир, т.е перенести наш проект из sandbox на основную Толоку. Для этого в аккаунте исполнителя во вкладке "Действия над проектом" выбираем "Экспортировать".



    Заходим на toloka.yandex.ru и видим, что наш проект удачно экспортировался.



    Открываем его, еще раз проверяем, что все верно. Как-то раз я допустил ошибку, неправильно сформировав задание и 2000 исполнителей, выполнив его, не смогли отправить результат (до сих пор неизвестно, сколько людей я убил).


    11. Запускаем пул, ждем 20 мин и получаем результат:



    Итого: у нас было 1159 фото. На одной страничке для фрилансера размещалось по 40 фото. Т.е. было 1159 / 40 = 29 наборов заданий. Но мы делали с перекрытием 3, значит всего было показано 29 x 3 = 87 страничек. За одну страничку мы платим 0.01$ + 0.005$. Следовательно, чтобы проверить 1159 фото, у нас ушло 1.3$ или 80 руб. При этом фрилансеры получили всего 0.87$ или 50 руб, приблизительно потратив 97 сек x 87 заданий = 2 часа 20 минут. А готовы ли вы работать за 25 руб в час?


    12. Проверяем задания и скачиваем результат.



    Открываем полученный файл в pandas, групируем по "INPUT:image"


    import pandas as pd
    data = pd.read_csv('assignments_v0(14.05.18).tsv',sep = '\t')
    data['OUTPUT:output'] = data['OUTPUT:output'].map({'NO':0,'YES':1})
    data_groupby = data.groupby('INPUT:image').sum()

    Получили:



    data_groupby['OUTPUT:output'].value_counts()
    3.0    634
    0.0    445
    2.0     57
    1.0     23

    Используя метод голосования, и считая, что на фото Киркоров, если хотя бы два исполнителя проголосовали за него, получили 634 + 57 = 691 фото.



    Подводя итог, хочется сказать, что:


    1. Толока — гибкий инструмент, который можно подстроить под любую задачу.
    2. На Толоке очень дешевая рабочая сила.
    3. На Толоке порядка 10000 исполнителей, что позволяет размечать огромные объемы данных за очень короткий промежуток времени.
    4. Толока обладает очень удобными инструментами для контроля исполнителей, что позволяет создавать качественную разметку датасета.

    Из огромных минусов: нельзя на Толоке размечать персональные данные, так как с исполнителями не подписываются никакие NDA и это будет являеться нарушением 152-ФЗ и GDPR.


    Если вам интересна тема по созданию датасетов, то ставьте плюсы и в следующей статье я расскажу, как создавать датасеты для приложения sticky-ai.

    Open Data Science
    Крупнейшее русскоязычное Data Science сообщество
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 27

      +8
      Спасибо за статью! Но в вашей статье прозвучал хороший вопрос — кто вообще работает за 25 р/час?
        +6
        Никто. Задания с такой ценой и отложенной оплатой просто не берут (по крайней мере те, кто не «на удачу» задания выбирает).
          0
          В основном на Толоке сидят люди из дальних регионов, где работы совсем нет и они готовы работать за любые деньги. На самом деле, если задание сложное и на освоение инструкции исполнителям придется потратить некоторое время, то цена часа вырастает где-то до 70-120 руб.
            +2
            25р в час — это даже для пенсионера из региона на «минималке» не заработок — просто волонтёрство какое-то. Но я не уверен, что даже этой суммы можно достигнуть, не делая задания на «отвяжись».

            Сейчас зарегистрировался, чтобы посмотреть что это вообще такое.
            За 2 часа заработал 8 центов. А ведь «яжпрограммист» — человек изначально подготовленный, и умеющий почти моментально извлекать суть из тонн «воды».
              0

              Готовы то может быть на любые деньги, но для того, чтобы на Толоке быть разметчиком, нужен компьютер и широкополосный доступ к интернету… окупят ли 25р/ч затраты на работу на толоке — не известно.

              0
              Я толокой оплачиваю мобильный. Не то, чтобы я не мог оплатить его иначе, просто это не требует от меня практически никаких трудозатрат.
              +4
              Если исполнитель 3 раза из 5 отвечает быстрее, чем за 40 секунд, то система его заблокирует.

              А на что в этой задаче можно тратить 40 секунд?
                +6
                На странице с заданием размещено 40 фото. В среднем исполнители 40 фото проверяют за 1 мин 37 сек. Попробовав сам наиболее быстро проверить 40 фото, у меня вышло 52 сек, поэтому было решено, что если исполнитель выполняет быстрее, чем за 40 сек, то либо он невнимательно делает, либо является ботом.
                  +2
                  Точно, вижу теперь!
                +5
                Практически каждый человек знает, что такое машинное обучение...

                Очень смелое утверждение.

                  –3
                  оно просто немного опережает время, через лет любой программист что бы оставаться на плаву должен будет знать мл, а через 10 любой человек и гуманитарий будет обязан знать, что бы не остаться на отшибе вселенной
                  • UFO just landed and posted this here
                +5
                Практически каждый человек знает, что такое машинное обучение, линейная регрессия, random forest.

                Ну, конечно. Буквально сегодня слышал, как консьержка с соседкой обсуждали трансдуктивное машинное обучение.
                  +2
                  Скажите, а кто такой Фейс и чем этот человек славен? Киркоров-то известен хотя бы рифмой «звезда-п?? да» в тексте своего экспромпта про розовую кофточку и микрофон, а также тем, что кинул какого-то зарубежного композитора-песенника в ментовку и на деньги, пригласив того сначала в отделение «Сбербанка» договориться о денежном вознаграждении.
                    +1
                    фейс — это лицо молодежи
                    +2
                    Удалось ли успешно обучить на этом датасете распознавалку Киркорова?
                      +1
                      Мы не пробовали) Да и фото Фейса у нас нет, так как я поленился его загружать на Толоку)
                      +3
                      Зря вы не сохраняете пропорции лиц, это достаточно стабильная характеристика, которую удобно детектировать. По-хорошему нужно не просто ужимать изображение в квадрат, а проходиться детектором лиц и обрезать вокруг каждого поле нужного размера. В противном случае сети придётся параллельно иметь шаблоны для определения по-разному искажённых преобразованием лиц.
                        +1
                        Да, вы совершенно правы. Если бы это была реальная задача, а не игрушечный пример, то я:
                        1) Скачал бы фото Киркорова.
                        2) С помощью dlib нашел бы и вырезал все лица
                        3) Удалил бы все лица, которые меньше 299*299, а все, которые больше 299*299, привел бы к нужному размеру.
                        4) И уже полученные лица проверил через Толоку.
                        +1
                        Если нужны bounding boxes, то можно использовать
                        github.com/mnill/People-vision-example
                        0.01-0.02$ за картинку.
                          0
                          Среди стандартных шаблонов Толоки есть задание по выделению произвольных полигонов, оно адаптируется для задачи bounding boxes. Если возникнут трудности, можно обратиться в поддержку заказчиков.
                          +1
                          «Как создать датасет, который отличает оттенки розового на кофточках журналисток?» :)
                            +1
                            Подскажите, это только для классификации работает? Какие-то более сложные типы разметки возможно через Толоку делать? И вообще кто где ищет исполнителей? У нас это целая проблема, расскажите у кого как это происходит?
                              +1
                              Так как на Толоке исполнителям задания подаются в написанной вами html, то можно сделать любой тип разметки, который только можно запихнуть в браузер. С готовыми шаблонами вы можете ознакомиться тут.
                                0
                                Возможно 90% задач это покрывает. У нас, например, разметчикам нужно установить специализированное ПО, потратить время на подробные объяснения задачи, и регулярно проверять качество, потому что его сложно формально проверить. Кто-нибудь в курсе, есть ли на рынке компании, которые занимаются разметкой? Мне тяжело поверить, что только у нас такая проблема, хотя может и так.
                                  0
                                  Регулярную проверку качества и отбор исполнителей можно организовать на Толоке, ограничивая доступ к боевым заданиям на основе значения навыка, получаемого в процессе выполнения проверочных.

                                  Специализированное ПО толокерам устанавливать не получится, но как верно написал kucev выше, интерфейсы заданий в Толоке программируются на JS, поэтому теоретически их можно делать довольно сложными. Ещё могу посоветовать попробовать декомпозировать задачу на несколько частей, которые уже проще краудсорсить.

                                  Если более подробно опишите свою задачу, сможем проконсультировать по её организации в Толоке.

                            Only users with full accounts can post comments. Log in, please.