ПИТОН | ДАННЫЕ | ПРОГРАММИРОВАНИЕ

Введение в контроль версий данных

Пошаговое руководство по реализации собственного DVC на Python с использованием Hangar

Что такое контроль версий данных (DVC)?

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

В программной инженерии решением этой проблемы является Git. Если вы когда-нибудь писали код, то, вероятно, вам знакома красота Git. Git позволяет нам фиксировать изменения, создавать разные ветки из исходного кода и объединять наши ветки обратно с оригиналом, и это лишь некоторые из них.

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

Кроме того, в среде машинного обучения у нас также будет несколько версий одной и той же «модели», обученной на разных версиях одного и того же набора данных (например, переобучение модели для включения новых точек данных). Если не провести должный аудит и версию, это создаст запутанную сеть наборов данных и экспериментов. Мы точно этого не хотим!

Таким образом, DVC — это система, которая включает в себя отслеживание наших наборов данных путем регистрации изменений в конкретном наборе данных. Существует множество решений DVC, как бесплатных, так и платных. Недавно я обнаружил Hangar, полностью открытый пакет Python DVC. Давайте посмотрим, что он может сделать, не так ли?

Работа с Ангаром

Пакет ангара является чистой реализацией Python и доступен через pip. Его основная функциональность также тесно связана с git, что значительно облегчает обучение. У нас также есть возможность либо взаимодействовать с ангаром через командную строку, либо использовать его специальный клиент Python.

Некоторые доступные функции включают в себя:

  • оформить заказ — переключиться на новую ветку или контрольную точку
  • зафиксировать — добавить текущие изменения в текущую ветку
  • ветвь – создать ссылку на конкретную фиксацию.
  • объединить — объединить изменения из одной ветки в другую
  • diff — сравнить изменения между двумя ветвями
  • push — загрузить локальную версию в удаленный репозиторий
  • pull/fetch — обновить локальную версию набора данных из удаленного репозитория.
  • журнал — показать историю коммитов

Примечание: удаленный репозиторий — единственный источник текущей правды.

Положительным моментом здесь является то, что Hangar не построен поверх git, а скорее эмулирует функциональность git. Это делает его быстрее.

Мы можем установить ангар через pip, используя:

pip install hangar

После установки Hangar мы можем импортировать пакет прямо в Python.

Первое, что нам нужно сделать для работы с Hangar, это создать хранилище данных. Мы можем импортировать класс Repository из пакета Hangar и использовать его для определения нашего репозитория.

Если мы впервые работаем с определенным репозиторием, мы также должны инициализировать его с помощью функции init().

Прежде чем мы сможем продолжить наш пример управления версиями данных, давайте сначала обсудим методологию Hangar.

Приближаясь к ангару

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

Репозиторий

Мы можем думать о репозитории как о складе нашего проекта. Репозиторий — это, по сути, коллекция и история выполненных коммитов.

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

Набор данных

Это просто. Набор данных, как вы уже догадались, наш набор данных. Но что такое набор данных? Возьмем для аналогии набор данных Титаник. Что составляет набор данных?

Это отдельные образцы? Это контролируемые переменные? И здесь мы можем проявить творческий подход к вещам. Hangar описывает набор данных как набор столбцов. Мы займемся этим дальше.

Колонка

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

  • add_bytes_column — байты
  • add_ndarray_column — массивы
  • add_str_column — строка

Например, если у нас есть набор данных из изображений 28x28, мы выберем столбец массива (где каждый образец имеет форму 28x28) для представления фактических числовых данных. Мы можем использовать байты или строковые столбцы для хранения метки, а также строковый столбец для хранения имени файла изображения.

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

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

Данные

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

С этим покончено, давайте приступим к остальной части нашего примера.

Предполагая, что у нас есть набор данных табличной классификации — df — мы просто будем хранить весь набор данных в одном столбце в виде байтов.

Начнем с создания WriterCheckout. Объект WriterCheckout позволяет нам включить определенную ветку (в нашем случае у нас есть только одна ветка: master) с доступом для записи (т.е. с возможностью записи и фиксации изменений в активной ветке). Мы делаем это с помощью master = repo.checkout(write=True).

Затем мы можем указать Hangar создать столбец байтов с именем «data», вызвав функцию add_bytes_column. Поскольку это наша первая фиксация, наш столбец все еще пуст. Для нашей первой фиксации мы можем зафиксировать наши данные с индексом 0. Поскольку мы указали наш столбец как объект bytes, мы должны сначала преобразовать наши данные в объект bytes. В конечном итоге мы можем вызвать функцию commit, чтобы зафиксировать и сохранить наши изменения. Ниже мы показываем пример кода того, что мы только что обсуждали.

Примечание. Hangar не позволяет использовать более одной WriterCheckouts во избежание конфликтов. Таким образом, если WriterCheckout не используется, обязательно закройте его. Если блокировка записи уже находится в обращении, нам будет разрешено оформить заказ только в режиме только для чтения.

Если мы хотим добавить еще один коммит в тот же столбец, мы следуем тому же процессу, но вместо этого фиксируем master['data'][1] и так далее для будущих коммитов. К каждому коммиту также будет привязан хеш-ключ.

Филиал в Ангаре

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

Create Branch -> Checkout Branch -> Make Changes -> Commit -> Merge

Мы можем создавать ветки, используяrepo.create_branch(name='test'), и объединять их следующим образом:

master.merge(message='message for merge', dev_branch='test')

Каждому коммиту в Hangar присваивается хеш-ключ. Мы можем использовать этот хэш, чтобы точно определить точку ветвления:

test_branch2 = repo.create_branch(name='test2', base_commit=<SOME_HASH_KEY>)

Вызвавrepo.log(), мы можем получить сводку журнала текущих веток и их последнего коммита. Пример журнала будет выглядеть примерно так:

* a=cf94cf8b4c5758c885c6b84d58c4fbe22f379510 (test2): added new test branch
* a=a8fe61916764b873f13c80a14ce4fda610b74df9 (test) (master): Base Dataset

Мы можем получить разницу и конфликты между ветвями следующим образом:

repo.diff('master', 'test2')

Заключительные замечания

В этом посте мы рассмотрели пакет Hangar как решение с открытым исходным кодом для DVC в Python. Это все, что предлагает Hangar? Точно нет! Мы познакомились с основами и узнали, как начать работу с Hangar. Как всегда, я настоятельно рекомендую вам ознакомиться с их документацией и попрактиковаться на собственном примере использования.

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



Хочешь угостить меня кофе?



Хотите связаться?

Я хотел бы услышать ваши мысли по теме, или что-либо AI действительно. Напишите мне по адресу [email protected], если вы хотите связаться с нами.

ЛинкединТвиттер