diff --git a/content/posts/2023/how-to-prepare-a-dataset/01.jpg b/content/posts/2023/how-to-prepare-a-dataset/01.jpg new file mode 100644 index 0000000..b4402f4 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/01.jpg differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/02.jpg b/content/posts/2023/how-to-prepare-a-dataset/02.jpg new file mode 100644 index 0000000..7852e87 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/02.jpg differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/03.png b/content/posts/2023/how-to-prepare-a-dataset/03.png new file mode 100644 index 0000000..3a92054 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/03.png differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/04.png b/content/posts/2023/how-to-prepare-a-dataset/04.png new file mode 100644 index 0000000..3430fb1 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/04.png differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/05.png b/content/posts/2023/how-to-prepare-a-dataset/05.png new file mode 100644 index 0000000..3b38cb4 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/05.png differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/06.jpg b/content/posts/2023/how-to-prepare-a-dataset/06.jpg new file mode 100644 index 0000000..c1de79b Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/06.jpg differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/07.png b/content/posts/2023/how-to-prepare-a-dataset/07.png new file mode 100644 index 0000000..54241af Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/07.png differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/08.png b/content/posts/2023/how-to-prepare-a-dataset/08.png new file mode 100644 index 0000000..9a8fbe7 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/08.png differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/09.png b/content/posts/2023/how-to-prepare-a-dataset/09.png new file mode 100644 index 0000000..d696466 Binary files /dev/null and b/content/posts/2023/how-to-prepare-a-dataset/09.png differ diff --git a/content/posts/2023/how-to-prepare-a-dataset/index.md b/content/posts/2023/how-to-prepare-a-dataset/index.md new file mode 100644 index 0000000..6aaa086 --- /dev/null +++ b/content/posts/2023/how-to-prepare-a-dataset/index.md @@ -0,0 +1,285 @@ +--- +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 раз эффективнее, +она может начать работать хуже. Стоит использовать только те аугментации, которые реально помогут, +т.е. те, что отвечают реальным условиям. Если камера будет стоять внутри помещения, +то аугментация «снег» или «туман» только навредит, ведь данных искажений в реальной жизни не будет. + +Итак, мы перечислили основные шаги, которые позволят разработчикам создавать датасеты лучше, +чем они это делали вчера, а клиентам понять как можно улучшить свой датасет до того, +как он будет передан разработчикам. Безусловно, этот список не исчерпывающий, +но наш опыт подсказывает, что эти шаги являются самыми важными.