286 lines
26 KiB
Markdown
286 lines
26 KiB
Markdown
|
---
|
|||
|
title: "🖼️ О важности датасета и о том, как сделать его лучше"
|
|||
|
date: 2023-09-20T20:57:17+03:00
|
|||
|
draft: false
|
|||
|
tags: [ML, tutorial]
|
|||
|
---
|
|||
|
|
|||
|
> Копия [статьи](https://www.technologika.ru/blog/how-to-create-great-dataset)
|
|||
|
с ресурса **technologika.ru**
|
|||
|
|
|||
|
Краеугольный камень любого проекта, связанного с компьютерным зрением — датасет.
|
|||
|
Это не просто набор изображений, который передается нейросети.
|
|||
|
Датасет — это базовый блок, который определит качество
|
|||
|
и точность определения объектов в рамках вашего проекта.
|
|||
|
|
|||
|
Нельзя просто собрать набор изображений из гугла и успокоиться —
|
|||
|
полученная куча изображений не будет нести гордое название «датасет»
|
|||
|
и испортит проект, вынуждая разработчика и компьютерное железо тренировать модель снова и снова.
|
|||
|
|
|||
|
Часто работа над датасетом занимает самое большое количество времени
|
|||
|
чем над каким-либо еще этапом разработки системы компьютерного зрения,
|
|||
|
и это неспроста. Чем лучше будет подготовлен датасет,
|
|||
|
тем меньше времени потребуется на отладку модели, ее тренировки,
|
|||
|
поиск и устранение неточностей распознавания, а также в целом сделает модель «умнее».
|
|||
|
|
|||
|
Мы подготовили 7 основных шагов, которые превратят набор картинок из гугла
|
|||
|
не просто в мощный базовый блок системы компьютерного зрения,
|
|||
|
но и основной инструмент по выявлению и устранению ошибок распознавания.
|
|||
|
|
|||
|
![](01.jpg)
|
|||
|
|
|||
|
## Шаг 1: Размерность
|
|||
|
|
|||
|
Размер самих изображений, находящихся в датасете, не так важен:
|
|||
|
перед подачей модели на обучение данные нормализуются,
|
|||
|
чтобы соответствовать размеру сетки, например, **300x300** пикселей.
|
|||
|
|
|||
|
Размер входного слоя нейросети — размер изображений, с которыми будет работать сетка.
|
|||
|
|
|||
|
При формировании датасета важно иметь ввиду размерность сетки, с которой предстоит работать,
|
|||
|
и максимально близко подгонять размер изображений к размеру модели.
|
|||
|
Если этого не делать, то можно наткнуться на немало сюрпризов.
|
|||
|
|
|||
|
Например, один наш клиент обратился нам за помощью:
|
|||
|
его нейросеть должна была определять марку автомобиля и его номер,
|
|||
|
и если с первым обученная модель справлялась на «ура», то со вторым не справлялась вовсе.
|
|||
|
Ответы вроде «неподходящая модель», «маленькое количество данных»,
|
|||
|
«невыполнимая для компьютерного зрения на данном этапе задача» оказались неверны,
|
|||
|
а реальный ответ был куда проще - клиент не принял во внимание размер модели нейросети,
|
|||
|
с которой работал.
|
|||
|
|
|||
|
![](02.jpg)
|
|||
|
|
|||
|
Нейросети, использованной в данном проекте, на вход давали изображения с шириной **1024** пикселя,
|
|||
|
а входной размер самой модели — **300х300** пикселей. Изображения сильно сжимались в размере,
|
|||
|
и если автомобиль мог пережить данную трансформацию и оставался узнаваемым,
|
|||
|
то номер превращался в неузнаваемую кашу из пикселей. Если бы наш клиент прочитал это руководство
|
|||
|
к идеальному датасету, он бы смог сам довольно просто решить свою проблему
|
|||
|
всего лишь обрезав изображения, приблизив их тем самым к размеру его модели нейросети.
|
|||
|
|
|||
|
![](03.png)
|
|||
|
|
|||
|
Если для решения поставленной задачи критично важно использовать изображения большого размера,
|
|||
|
то уже существуют **object detection** модели, которые могут работать с большими изображениями.
|
|||
|
Например, модель **YOLOv5x6** может работать с изображениями шириной до **1280** пикселей.
|
|||
|
Данные модели очень полезны в условиях распознавания маленьких объектов
|
|||
|
на больших фотографиях, например, на спутниковых снимках.
|
|||
|
|
|||
|
## Шаг 2: Реальные условия
|
|||
|
|
|||
|
Главное правило любого датасета — изображения должны быть максимально приближены к реальным условиям,
|
|||
|
в которых будет работать модель нейросети. До начала сбора изображений важно знать какие именно
|
|||
|
изображения будет получать на вход модель, где будет стоять камера, разрешение камеры.
|
|||
|
|
|||
|
Важно понимать, что если камера имеет маленькое разрешение
|
|||
|
и будет захватывать маленькие по размеру изображения, то и фото в датасете должны быть небольшими.
|
|||
|
Новички в разработке систем машинного обучения часто игнорируют это правило,
|
|||
|
предполагая, что чем больше и детализированнее изображение будет подано сетке в момент обучения,
|
|||
|
тем лучше она выучит предмет и тем выше будут показатели точности на реальных данных.
|
|||
|
|
|||
|
Пренебрежение данным шагом может «подкосить» даже проект с современной нейросетью и большим датасетом.
|
|||
|
Один из наших клиентов поставил перед собой задачу определять птиц, попавших в объектив веб-камеры.
|
|||
|
Во время составления датасета клиент собирал фото птиц разных видов из гугла:
|
|||
|
четкие, насыщенные изображения, на которых птица видна как правило в фас или в бок
|
|||
|
и занимает большую часть самого изображения.
|
|||
|
На валидационном датасете нейросеть показывала отличные разультаты.
|
|||
|
Однако в реальных условиях нейросеть работала крайне плохо.
|
|||
|
|
|||
|
Реальность оказалось далека от гугла. Птицы, запечатленные на заднем дворе
|
|||
|
с помощью простой веб-камеры, выглядели куда более тускло,
|
|||
|
часто были расположены к камере спиной или были видны лишь частично.
|
|||
|
Сами изображения были куда меньше, хуже по качеству, часто содержали разные помехи
|
|||
|
— капли дождя или насекомое на объективе, засвет солнцем, туман.
|
|||
|
Нейросеть просто не могла определить что находилось на таком изображении,
|
|||
|
ведь птицы на фото из датасета выглядели совсем по-другому.
|
|||
|
|
|||
|
Нам пришлось провести большую работу по сбору фотографий птиц в реальных условиях,
|
|||
|
после чего система заработала с высокими показателями точности.
|
|||
|
|
|||
|
Данный шаг часто представляет довольно большую сложность, т.к. у клиентов часто нет возможности собрать
|
|||
|
реальные фото объектов до того, как проект будет запущен. Однако его нельзя игнорировать,
|
|||
|
ведь от того, насколько данные в датасете близки к реальным данным, зависит качество распознавания.
|
|||
|
|
|||
|
## Шаг 3: Проверка формата и аннотаций
|
|||
|
|
|||
|
Этот шаг особенно важен для проектов, которые используют уже готовый датасет,
|
|||
|
найденный на просторах интернета. Важно проверить, что изображения в датасете находятся в том формате,
|
|||
|
с которым сможет работать выбранный фреймворк. Современные фреймворки работают
|
|||
|
с большим количеством разных форматов, однако до сих пор встречаются проблематичные форматы,
|
|||
|
например, **jfif**.
|
|||
|
|
|||
|
Если изображения не будут находиться в нужном формате,
|
|||
|
процесс тренировки просто не сможет быть закончен,
|
|||
|
поэтому важно оказать этой как может показаться мелочи достаточно внимания.
|
|||
|
|
|||
|
Необходимо также проверить аннотации и их формат. Изображения в датасете могут отвечать всем
|
|||
|
вышеперечисленным требованиям, но если аннотации не будут в том формате,
|
|||
|
с которым работает фреймворк и архитектура модели нейросети, то ничего работать не будет.
|
|||
|
|
|||
|
В одних форматах аннотации, т.е. расположение **bounding** бокса на изображении,
|
|||
|
указывается в абсолютных значениях, в других — в относительных. Некоторые фреймворки,
|
|||
|
например **YOLO**, просят для каждого изображения `cat.jpg` приложить файл `cat.txt` с аннотацией,
|
|||
|
а другие, например **TensorFlow**, просит аннотации в формате `.csv`,
|
|||
|
некоторые просят приложить для тренировочного датасета один файл `train.txt`,
|
|||
|
который содержит все аннотации разом.
|
|||
|
|
|||
|
На этапе работы с датасетом важно знать с какой моделью будет вестись работа,
|
|||
|
ведь от этого зависит формат аннотаций и формат самих изображений.
|
|||
|
|
|||
|
## Шаг 4: Разбивка датасета на TRAIN и VALIDATE
|
|||
|
|
|||
|
Разбивка датасета на `Train` и `Validate` — важный этап работы с датасетом,
|
|||
|
делающий тренировку нейросети возможной.
|
|||
|
Как правило, при разбивке датасета пользуются следующими правилами:
|
|||
|
|
|||
|
70-80% изображений идут в `Train`, 20-30% — в `Validate`.
|
|||
|
|
|||
|
![](04.png)
|
|||
|
|
|||
|
**Train** — то, на чем учится нейросеть, из чего извлекает свойства объекта под вопросом.
|
|||
|
После окончания эпохи тренировки нейросеть должна проверить правильно ли она выучила
|
|||
|
как выглядит объект, для чего она обращается к сету **Validate**.
|
|||
|
|
|||
|
Используя обретенные с помощью **Train** знания, нейросеть пытается угадать какой объект находится
|
|||
|
на изображении из **Validate**. Если предположение нейросети оказалось неправильным,
|
|||
|
то делается анализ ошибки для предотвращения такой ошибки в следующих итерациях.
|
|||
|
|
|||
|
Без сета **Validate** невозможно обучить модель.
|
|||
|
Данный способ часто применяется в системах машинного обучения,
|
|||
|
работает достаточно хорошо и является неким негласным стандартом работы с датасетом.
|
|||
|
|
|||
|
Однако наши разработчики используют несколько иной подход:
|
|||
|
|
|||
|
70% изображений идут в `Train`, 20% идут в `Validate`, 10% — в `Test`.
|
|||
|
|
|||
|
![](05.png)
|
|||
|
|
|||
|
По нашему опыту, изначально датасет нужно разбивать так, чтобы оставались изображения,
|
|||
|
которые нейросеть еще не видела. Процесс обучения остается прежним — сетка изучает изображения
|
|||
|
в **Train** и проверяет свои знания на изображениях из **Validate**,
|
|||
|
однако после завершения тренировки мы добавляем дополнительный этап — тестирование.
|
|||
|
Нейросеть анализирует изображения из **Test**, которые она ни разу не видела,
|
|||
|
а мы можем проверить работает ли нейросеть на самом деле.
|
|||
|
Данный этап позволяет выяснить где ошибается нейросеть, какие классы вызывают у нее сложности.
|
|||
|
|
|||
|
## Шаг 5: Утечка данных
|
|||
|
|
|||
|
Для начала кратко поясним что такое утечка данных и почему это плохо.
|
|||
|
|
|||
|
Допустим мы хотим научить нейросеть отличать кроликов от зайцев.
|
|||
|
Возьмем два изображения зайца, которые отличаются друг от друга
|
|||
|
небольшим изменением положения его тела:
|
|||
|
|
|||
|
![](06.jpg)
|
|||
|
|
|||
|
Для человека данные изображения разные, поэтому они оба могут попасть в датасет.
|
|||
|
Далее мы как обычно разбиваем наш датасет на **Train** и **Validate**, однако случилось так,
|
|||
|
что первое изображение зайца попало в **Train**, а второе — в **Validate**.
|
|||
|
Начинаем тренировку нашей нейросети, она извлекает свойства зайца с первого изображения,
|
|||
|
после завершения эпохи нейросети показывают второе изображение зайца.
|
|||
|
Наша модель безошибочно угадает, что это заяц, а не кролик,
|
|||
|
ведь почти точно такое же изображение она видела в **Train**.
|
|||
|
Получилась ситуация, когда нейросеть не выучила информацию, а запомнила.
|
|||
|
|
|||
|
![](07.png)
|
|||
|
|
|||
|
Как только наша нейросеть получит на вход изображение, где заяц сильно повернул голову,
|
|||
|
развернулся или лег на спину — она тут же растеряется и не сможет понять что ей показывают.
|
|||
|
|
|||
|
Данные, которые перетекают из **Train** в **Validate** не дают нейросети учиться.
|
|||
|
В процессе обучения значение `accuracy` будет приближено к 100%,
|
|||
|
однако в реальных условиях ситуация будет куда более плачевной.
|
|||
|
|
|||
|
К вопросу утечки данных нужно подходить серьезно.
|
|||
|
Многие при разбивке датасета сначала используют **Shuffle**, затем берут первые 70%
|
|||
|
и помещают в **Train**, оставшееся — в **Validate**, но данных подход приводит к утечке данных.
|
|||
|
Важно сделать так, чтобы в сете **Validate** не было картинок, которые есть в **Train**.
|
|||
|
|
|||
|
![](08.png)
|
|||
|
|
|||
|
Чтобы избежать утечки данных, можно использовать скрипты и библиотеки, которые удаляют дубликаты.
|
|||
|
Можно настроить порог удаления, например, удалять идентичные картинки или схожие на 90% картинки.
|
|||
|
Чем больше дубликатов и похожих изображений будет удалено, тем лучше для нейросети.
|
|||
|
|
|||
|
На нашей практике мы сталкивались с ситуациями, когда утечка данных значительно влияла
|
|||
|
на качество определения. В одном из наших проектов нейросеть стабильно ошибалась
|
|||
|
при определении объектов из определенного класса.
|
|||
|
Ручным тестированием мы обнаружили утечку данных. После удаления дубликатов ошибка пропала.
|
|||
|
|
|||
|
Часто можно встретить мнение, что датасет нужно делать как можно более объемным,
|
|||
|
чем больше датасет — тем лучше качество распознавания.
|
|||
|
Однако в случае с утечкой данных, лучше уменьшить количество данных,
|
|||
|
повысив тем самым качество датасета.
|
|||
|
|
|||
|
Вообще стоит отметить, что датасет по идее неприкосновенен,
|
|||
|
но его иногда нужно «перетряхивать» в поисках неточностей, дубликатов, неравномерно наполненных классов.
|
|||
|
|
|||
|
## Шаг 6: База данных
|
|||
|
|
|||
|
Работая с большим датасетом, где речь идет о десятках и сотнях тысяч изображений
|
|||
|
и десятках классов и подклассов, сложной структуре и изображениях из множества разных источников,
|
|||
|
мы практикуем создание простой, но очень полезной базы данных,
|
|||
|
содержащей основную информацию об изображениях.
|
|||
|
|
|||
|
Зачем это нужно? При работе с большим датасетом гораздо удобнее
|
|||
|
и быстрее анализировать информацию посредством базы данных,
|
|||
|
а некоторые виды анализа возможны только с БД.
|
|||
|
|
|||
|
Сама база данных имеет очень простую структуру и содержит в себе информацию об изображениях:
|
|||
|
|
|||
|
Название Абсолютный путь Данные об аннотации Класс, к которому принадлежит изображение Свойства изображения, например, вид птицы, марка автомобиля, источник изображения (веб-камера, гугл) и пр.
|
|||
|
|
|||
|
База данных позволяет быстро работать с датасетом, например, собирать статистику по датасету,
|
|||
|
чтобы понять его структуру, увидеть дисбаланс по классам,
|
|||
|
проверить количество изображений из разных источников для каждого класса.
|
|||
|
|
|||
|
С помощью БД можно составлять графики по количеству изображений,
|
|||
|
который позволяет визуально легко определить недостаток качественных
|
|||
|
(с точки зрения тренировки модели) изображений и дисбаланс изображений по классам.
|
|||
|
|
|||
|
Например, анализируя качество определения видов птиц мы заметили,
|
|||
|
что нейросеть плохо определяет воробьев. Проанализировав датасет с помощью БД мы увидели,
|
|||
|
что треть изображений из класса «воробей» были взяты из гугла.
|
|||
|
Пройдя по всем классам, мы определили пороговое значение гугловских изображений,
|
|||
|
в нашем случае — 20%. Если в классе «плохих» изображений было больше, то модель начинала ошибаться.
|
|||
|
|
|||
|
Данный анализ был бы невозможен или очень затруднен, если бы мы вручную просматривали каждый класс
|
|||
|
и не имели перед собой общую статистику. Стоит отметить, что создание базы данных имеет смысл
|
|||
|
только при работе с большими датасетами.
|
|||
|
|
|||
|
Все эти работы проделываются до начала обучения, ведь как вы могли понять
|
|||
|
из всего вышеизложенного обучение — не главный вопрос, а вот подготовка является основным
|
|||
|
и самым важным этапом разработки. Разработчику и клиенту важно знать свой датасет,
|
|||
|
знать из чего он состоит, какую структуру имеет. Это позволит быстро устранять ошибки определения.
|
|||
|
|
|||
|
## Шаг 7: Аугментация
|
|||
|
|
|||
|
**Аугментация** — быстрый, простой и эффективный способ увеличить объем датасета
|
|||
|
в условиях недостаточного количества изображений. С помощью специальных инструментов,
|
|||
|
например, открытой библиотеки на **Python**,
|
|||
|
можно трансформировать одно изображение и в результате получить несколько разных:
|
|||
|
|
|||
|
![](09.png)
|
|||
|
|
|||
|
Существует два типа аугментаций:
|
|||
|
|
|||
|
**Pre training augmentation** — модификация изображений до начала тренировки.
|
|||
|
Данный тип аугментаций важно проводить только после разбивки датасета на **Train**
|
|||
|
и **Validate Intraining augmentation** — аугментации, встроенные в фреймворк по умолчанию.
|
|||
|
|
|||
|
Почему же важно проводить до тренировочную аугментацию только после разделения датасета?
|
|||
|
Дело в том, что может произойти частичная утечка данных: аугментированные изображения могут попасть
|
|||
|
в **Validate**, с точки зрения обучения модели нейросети аугментированные фото являются дубликатами,
|
|||
|
что плохо сказывается на тренировочном процессе.
|
|||
|
|
|||
|
Аугментировать датасет можно и нужно, но главная мысль этого шага — не увлекаться аугментациями.
|
|||
|
При увеличении объема датасета в 7 раз сетка не станет в 7 раз эффективнее,
|
|||
|
она может начать работать хуже. Стоит использовать только те аугментации, которые реально помогут,
|
|||
|
т.е. те, что отвечают реальным условиям. Если камера будет стоять внутри помещения,
|
|||
|
то аугментация «снег» или «туман» только навредит, ведь данных искажений в реальной жизни не будет.
|
|||
|
|
|||
|
Итак, мы перечислили основные шаги, которые позволят разработчикам создавать датасеты лучше,
|
|||
|
чем они это делали вчера, а клиентам понять как можно улучшить свой датасет до того,
|
|||
|
как он будет передан разработчикам. Безусловно, этот список не исчерпывающий,
|
|||
|
но наш опыт подсказывает, что эти шаги являются самыми важными.
|