Главная » Хабрахабр » [Перевод] AI, практический курс. Сбор и исследование изображений

[Перевод] AI, практический курс. Сбор и исследование изображений

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

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

  1. Набор данных для обучения, содержащий 7000 эмоционально-окрашенных изображений с Flickr для алгоритма извлечения эмоций.
  2. Набор данных для обучения, содержащий произведения Баха, для алгоритма завершения мелодии.
  3. Набор мелодий, служащих шаблонами для модуляции эмоций.

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

Сбор данных с изображениями

Для данного проекта требовался набор изображений, вызывающих семь различных эмоций: счастье, грусть, страх, тревога, трепет, решимость, злость. Для сбора изображений было решено использовать Flickr, популярный сайт по обмену фотографиями, благодаря его размеру и лицензированию Creative Commons*.

К счастью, у Flickr есть API, обеспечивающий набор методов, которые позволяют легко обмениваться данными с Flickr на языке программирования. Поиск по Flickr 7000 изображений вручную — задача пугающая. Для определения списка условий поиска использовалась задача на платформе Amazon Mechanical Turk*. Однако прежде, чем использовать API для сбора изображений, важно знать, что искать, чтобы вызвать соответствующие эмоции.

Flickr API

Для использования методов, предлагаемых Flickr API потребуется создать учетную запись Flickr и запросить ключ API. Для этого обязательно иметь учетную запись Flickr или Yahoo!*. Далее необходимо пройти по этой ссылке и получить ключ.


Скриншот страницы www.flickr.com/services/apps/create/apply

Он включает в себя описание планируемого использования и принятие условий использования. Процесс обработки заявки на некоммерческий ключ довольно прост. В методах, предоставляемых API, он является обязательным параметром. Ключ API представляет собой меру безопасности и используется для предотвращения неправильного использования API.

В данном проекте используется Beej's PythonI Flickr API, который можно использовать с языком Python 3. После получения ключа API можно загрузить и установить набор инструментов API для одного из языков программирования из The App Garden. Необходимо следовать руководству по установке Flickr API.

В основном здесь используется функция API walk, осуществляющая поиск изображения по тегу. Код, использованный для загрузки изображений, приведен ниже. Если изображение найдено, его URL создается из шаблона на farm.staticflickr.com/{server-id}/{id}_{secret}.jpg, где содержимое фигурных скобок заменяется на атрибуты изображения. Теги хранятся в файле .txt и перечисляются по одному в строке. Затем топ-30 изображений для каждого тега (отсортированные по релевантности) извлекаются и организуются в папки, в зависимости от эмоции и условий поиска.

import flickrapi
import urllib.request
import os project_path = '/path/to/your/project'
photos_per_tag = 30
filenames = ['Awe.txt', 'Happiness.txt', 'Fear.txt', 'Determination.txt', 'Anxiety.txt', 'Tranquility.txt', 'Sadness.txt'] def download_files(flickr, t, category, num_photos): # Downloads the files of a specific tag os.mkdir(t) os.chdir(t) s = [] for photo in flickr.walk(tag_mode='all', sort='relevance', tags=t, license=4, per_page=50): url = 'https://farm{}.staticflickr.com/{}/{}_{}.jpg'.format(photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('secret')) s.append(url) if len(s) == num_photos: break for i in range(len(s)): filename = '{}_{}_{}.jpg'.format(category, t, str(i)) urllib.request.urlretrieve(s[i], filename) os.chdir(os.path.join(project_path, category)) if __name__ == '__main__': # Creates flickr object # These keys should be requested from flickr api_key = u'xxxxxxxxxxxx' api_secret = u'xxxxxxxxxxx' flickr = flickrapi.FlickrAPI(api_key, api_secret) # Runs the program, cycles through the emotions and downloads the images for each tag. os.chdir(project_path) for fname in filenames: categ = fname[:-4] with open(fname, 'r') as f: tags = f.read().splitlines() os.mkdir(categ) os.chdir(categ) for t in tags: download_files(flickr, t, categ, photos_per_tag) os.chdir(project_path)

Чтобы использовать данный код, необходимо клонировать репозиторий по ссылке с GitHub. После этого следуйте инструкциям, содержащимся в файле README. Необходимо заменить параметры api_key и api_secret на ключи API, полученные на Flickr. Как упоминалось выше, этот скрипт работает только на Python 3.

После того, как программа отработает, папка выглядит следующим образом:


Набор данных по результатам поиска на Flickr.

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

Отбор изображений

Качество собранных изображений было разным. Некоторые условия поиска, например, цветы (показанные на рисунке) давали пригодные к использованию изображения высокого качества. Однако менее конкретные условия поиска зачастую давали абсолютно непригодные к использованию изображения. Например, по тегу чудо (в связи с эмоцией трепет) было получено изображение торта с чудо-женщиной*, а по тегу амбициозный (в связи с эмоцией решимость) было найдено изображение капусты из Ambitious Farms.

Непригодные к использованию изображения.

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

В результате был пересмотрен подход к выбору набора данных. После просмотра изображений команда пришла к выводу, что более 40 процентов изображений непригодны к использованию. После обсуждения ряда возможностей, таких как ограничение набора изображениями лиц с соответствующими эмоциями, было принято решение использовать изображения из существующих баз данных, которые обычно используются в психологических исследованиях (Geneva Affective PicturE Database (GAPED), Open Affective Standardized Image Set (OASIS) и Image Stimuli for Emotion Elicitation (ISEE)).

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

Источник данных

Процесс сбора данных для нового набора данных был значительно проще. В частности, больше не требовались шаги с Amazon Mechanical Turk и Flickr API. Наборы данных GAPED и OASIS (включающие разметку параметров) доступны в Интернете для скачивания. Набор данных ISEE стал доступен после электронного письма автору с запросом доступа. Если инструкции по загрузке наборов данных недостаточно понятны, вероятнее всего, поиск Google* поможет найти контакты авторов, у которых можно напрямую запросить доступ к наборам данных.

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

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

Теперь, когда наборы данных созданы, проект готов к выполнению следующих шагов — исследованию и предварительной обработке данных.

Исследование данных с изображениями

Поскольку качество значительной части изображений, собранных с Flickr, оказалось низким, было решено использовать изображения из существующих баз данных изображений. В частности, были собраны изображения из трех баз данных для психологических исследований. Каждое изображение включает в себя информацию о рейтинге (не)приятности и интенсивности, собранную с нескольких исполнителей. 1986 изображений из этих баз данных были разбиты на 4 категории. Эти категории покрывали 87% изображений и включали 34% животных, 28% людей, 13% сцен и 12% объектов. Оставшиеся 13% были отнесены к категории «разное».

Животные

Примеры изображений из категории «Животные»

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

Изображения справа — спящий кот, улыбающаяся собака — наоборот, могут вызывать симпатию и счастье.

Люди

Примеры изображений из категории «Люди»

Например, изображение марширующего оркестра, похоже, снято на фоне заполненного фанатами стадиона, наводя на предположение, что на изображении снято некое представление во время спортивных состязаний. Категория изображений «Люди» включает изображения отдельных людей и групп людей, при этом изображения групп людей часто содержат больше информации о контексте. Следует отметить, что не все изображения со множеством людей или с группами имеют дополнительную информацию. Изображение злой женщины, наоборот, лишено контекста — у зрителя нет возможности узнать или догадаться о причине ее злости.

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

Сцены

Категория «Сцены» набора изображений включает разнообразные сцены — от рукотворных строений и объектов до сцен природы и даже космоса.

Примеры изображений из категории «Сцены»

Объекты

Примеры изображений из категории «Объекты»

В этих изображениях отсутствует ситуационный контекст, особенно если сравнивать их с другими категориями в наборе изображений. В категорию «Объекты» набора изображений вошли изображения, сфокусированные на одном объекте, как показано на примерах выше.

Разное

Примеры изображений из категории «Разное»

Часто, как показано на примерах, эти изображение представляли собой сцены с несколькими объектами, но без контекста, характерного для изображений категории «Сцены». Наконец, в наборе осталась подгруппа изображений, которые нельзя было отнести ни к одной из четырех категорий. Этот тип изображений, как правило, содержал нейтральный рейтинг — они не были ни приятными, ни неприятными.

Категории эмоций для базы данных изображений

Чтобы определить категории эмоций для базы данных изображений, мы опирались на нормативные субъективные рейтинги значимости, сопровождающие каждое изображение баз данных Geneva Affective PicturE Database (GAPED) и Open Affective Standardized Image Set (OASIS). Поскольку в GAPED использовалась шкала Лайкерта от 0 до 100, а в OASIS — шкала Лайкерта от 1 до 7, была применена линейная трансформация, приводящая все оценки в непрерывную шкалу от 0 до 100. Затем были исследованы два потенциальных правила категоризации эмоций.

Для реализации этого правила разделения на три категории был использован код на Python: Во-первых, интуитивно желательным является сортировка изображений по уровню приятности с последующим разделением на три части по шкале рейтинга — так, чтобы изображения с оценками 0–33,33 представляли отрицательную категорию, c оценками 33,33–66,67 — нейтральную, а с оценками 66,67–100 — положительную категорию.

import os
import shutil
import csv def organizeFolderGAPED(original, pos, neg, neut): # Копирует каждое изображение базы данных GAPED в соответствующую папку # Создать словарь имен файлов и уровня значимости dict = {} files = os.listdir(original) for file in files: if '.txt' in file: with open(os.path.join(original, file), 'r') as f: for l in f: l = l.split() dict[l[0][:-4]] = l[1] # Перебрать изображения и разделить файлы на категории pos/neg/neut в зависимости от уровня значимости for roots, dirs, files, in os.walk(original): for file in files: if '.bmp' in file: if float(dict[file[:-4]]) < 100/3: shutil.copy(os.path.join(roots, file), neg) elif float(dict[file[:-4]]) > 200/3: shutil.copy(os.path.join(roots, file), pos) else: shutil.copy(os.path.join(roots, file), neut) def organizeFolderOASIS(original, pos, neg, neut): # Копирует каждое изображение базы данных GAPED в соответствующую папку # Создать словарь имен файлов и уровня значимости dict = {} with open('/Users/harrys/Desktop/OASIS.csv') as file: reader = csv.reader(file) for row in reader: dict[row[1]] = row[4] # Перебрать изображения и разделить файлы на категории pos/neg/neut в зависимости от нормированного уровня значимости for roots, dirs, files, in os.walk(original): for file in files: if '.jpg' in file: if (float(dict[file[:-4]])-1)*100/6 < 100/3: shutil.copy(os.path.join(roots, file), neg) elif (float(dict[file[:-4]])-1)*100/6 > 200/3: shutil.copy(os.path.join(roots, file), pos) else: shutil.copy(os.path.join(roots, file), neut) if __name__ == '__main__' : gaped = 'path/to/your/project/directory/GAPED' oasis = 'path/to/your/project/directory/Oasis' pos = 'path/to/your/project/directory/Positive' neg = 'path/to/your/project/directory/Negative' neut = 'path/to/your/project/directory/Neutral' organizeFolderOASIS(oasis, pos, neg, neut) organizeFolderGAPED(gaped, pos, neg, neut)

Данный подход позволил разделить базу данных на категории: 417 отрицательных изображений, 774 нейтральных и 442 положительных. В данном подходе деления на три категории в равных долях неприятные изображения, рейтинг которых не достигал порогового значения, были отнесены к категории нейтральных; например, изображения мертвого тела, плачущего ребенка, кладбища были отнесены к нейтральным. Хотя эти изображения были менее неприятными, чем другие в категории отрицательных, возникло сомнение в их нейтральности.

Значения 0–39 были отнесены к отрицательной категории, 40–60 — к нейтральной, а 61–100 — к положительной. Поэтому было принято решение применить оптимизированное правило категоризации на основе нормального распределения данных, а также улучшить разделение параметров на эмоциональные категории. Для реализации этого правила был использован код на Python:

import os
import shutil
import csv def organizeFolderGAPED(original, pos, neg, neut): # Копирует каждое изображение базы данных GAPED в соответствующую папку # Создать словарь имен файлов и уровня значимости dict = {} files = os.listdir(original) for file in files: if '.txt' in file: with open(os.path.join(original, file), 'r') as f: for l in f: l = l.split() dict[l[0][:-4]] = l[1] # Перебрать изображения и разделить файлы на категории pos/neg/neut в зависимости от уровня значимости for roots, dirs, files, in os.walk(original): for file in files: if '.bmp' in file: if float(dict[file[:-4]]) < 40: shutil.copy(os.path.join(roots, file), neg) elif float(dict[file[:-4]]) > 60: shutil.copy(os.path.join(roots, file), pos) else: shutil.copy(os.path.join(roots, file), neut) def organizeFolderOASIS(original, pos, neg, neut): # Копирует каждое изображение базы данных GAPED в соответствующую папку # Создать словарь имен файлов и уровня значимости dict = {} with open('path/to/your/project/directory/OASIS.csv') as file: reader = csv.reader(file) for row in reader: dict[row[1]] = row[4] # Перебрать изображения и разделить файлы на категории pos/neg/neut в зависимости от нормированного уровня значимости for roots, dirs, files, in os.walk(original): for file in files: if '.jpg' in file: if (float(dict[file[:-4]])-1)*100/6 < 40: shutil.copy(os.path.join(roots, file), neg) elif (float(dict[file[:-4]])-1)*100/6 > 60: shutil.copy(os.path.join(roots, file), pos) else: shutil.copy(os.path.join(roots, file), neut) if __name__ == '__main__' : gaped = 'path/to/your/project/directory/GAPED' oasis = 'path/to/your/project/directory/Oasis' pos = 'path/to/your/project/directory/Positive' neg = 'path/to/your/project/directory/Negative' neut = 'path/to/your/project/directory/Neutral' organizeFolderOASIS(oasis, pos, neg, neut) organizeFolderGAPED(gaped, pos, neg, neut)

С таким правилом категоризации 40–60–40 567 положительных изображений были оценены как более приятные, чем 502 нейтральных, а 564 отрицательных изображения были оценены как менее приятные, чем нейтральные. Таким образом, было сохранено целевое значение эмоциональных категорий и улучшено распределение изображений по категориям. Ниже на рисунке проиллюстрирован уровень приятности, связанный с каждой из категорий. Разная длина усов на диаграмме рассеивания указывает, в какой эмоциональной категории (положительной или отрицательной) наблюдается больший разброс рейтингов по сравнению с нейтральной категорией.


Средние рейтинги приятности для каждой из эмоциональных категорий

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

Эмоциональная категория 1: Отрицательная

Эмоциональная категория 2: Нейтральная

Эмоциональная категория 3: Положительная

Подведем итог. Мы разделили базу данных изображений на нейтральную, отрицательную и положительную эмоциональные категории, используя нормативные рейтинги значимости в диапазоне от 0 до 100, отнеся значения 0–39 к отрицательным, 40–60 к нейтральным, а 61–100 — к положительным. Изображения соответствующим образом распределились по этим эмоциональным категориям. Наконец, в каждую эмоциональную категорию вошли изображения животных, людей, сцен, объектов и разного.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Кардиофлешка ECG Dongle: что нового

Прошло два года с тех пор, как мы показали прототип гаджета, полностью собираемого в РФ. На тот момент производитель пообещал выполнить несколько конкретных действий по улучшению продукта, и, в общем-то, можно сказать, что пришло время посмотреть, что же изменилось. ЭКГ-донгл ...

Может ли искусственный интеллект оставить букмекеров без работы?

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