--- 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 раз эффективнее, она может начать работать хуже. Стоит использовать только те аугментации, которые реально помогут, т.е. те, что отвечают реальным условиям. Если камера будет стоять внутри помещения, то аугментация «снег» или «туман» только навредит, ведь данных искажений в реальной жизни не будет. Итак, мы перечислили основные шаги, которые позволят разработчикам создавать датасеты лучше, чем они это делали вчера, а клиентам понять как можно улучшить свой датасет до того, как он будет передан разработчикам. Безусловно, этот список не исчерпывающий, но наш опыт подсказывает, что эти шаги являются самыми важными.