Задание посвящено защите от атак на нейронные сети, основанных на встраивании бэкдоров во время обучения. Бэкдор — свойство модели реагировать на триггер в тестовых примерах определенным образом. Чаще всего в качестве желаемой реакции для атакующего является предсказание конкретного и заведомо неверного класса для данного тестового примера. Бэкдор встраивается в модель в результате обучения на примерах с триггером и целевой неверной меткой, то есть на отравленных данных. В нашем задании рассматривается классификатор картинок в качестве такой модели.
Есть два основных сценария атаки с бэкдором:
- Атакующий отравляет датасет и передает его жертве для обучения. Ранние статьи по бэкдорам для нейронных сетей работали в этом сценарии. В дальнейшем выяснилось, что без модификации процесса обучения и с возможностью влиять только на датасет эффективное встраивание бэкдора возможно лишь для простых триггеров, таких как маленькая наклейка фиксированного содержания. Кроме заметного триггера, жертва может определить, что датасет отравлен, сопоставлением метки класса с отравленной картинкой, если имеет достаточно терпения на ручной просмотр датасета. Это большой недостаток сценария, поэтому теперь в статьях рассматривают сценарий ниже.
- Атакующий контролирует процесс обучения модели. Пользователь модели (жертва) получает от атакующего напрямую или через интернет (github) готовую модель с бэкдором. Жертва не знает деталей процесса обучения, в том числе использовались ли при обучении отравленные данные. Поэтому жертва вынуждена делать реверс-инжиниринг триггера и/или следить за поведением модели (например, скрытых слоев сети) на тестовых данных. В таком сценарии возможны мощные атаки, в которых наличие триггера в картинке крайне сложно определить человеческому глазу, поскольку триггер представляет собой слабое возмущение всей или большей площади картинки.
Задание состоит из двух частей. Первая часть предполагает первый сценарий, за ее успешное выполнение (без второй части) за задание выставляется оценка «4». Вторая часть оценивается только при условии успешного выполнения первой и позволяет получить оценку «5». Для каждой части решения студентов будут сравниваться с базовым (baseline) решением от преподавателя.
Часть задания выполнена успешно iff значение метрики Accuracy для решения студента выше baseline как для чистых, так и для отравленных картинок из тестовой выборки. Оба показателя для каждой части задания заносятся в leaderboard. Решения ранжируются по убыванию accuracy на отравленных картинках, то есть по второму показателю.
Дедлайн для обеих частей задания: 18 декабря 23:59. В это время проверяющая система будет остановлена, а лучшее решение каждого студента будет подвергнуто ручной проверке преподавателем (на предмет плагиата, читерства и т.п.).
Все перечисляемые ниже наборы — подмножества ImageNet, отравленные простым (первая часть) или продвинутым (вторая часть) триггером. Наборы имеют такую же структуру в файловой системе, как и ImageNet, и для их загрузки может быть использован класс ImageFolder
в pytorch.
В первой части используются три размеченных набора картинок — dev, train и test. Публикуется только набор dev, оставшиеся находятся в проверяющей системе и скрыты от студентов. Набор dev может использоваться студентами для анализа/экспериментов до отправки решений в проверяющую систему. Доступ к набору dev позволяет определить триггер и целевой класс, однако не следует слишком сильно полагаться на эту информацию, потому что триггер и целевой класс в train несколько отличаются.
Скачать набор dev для первой части: ссылка
Проверка заключается в обучении модели с нуля на наборе train и предсказании с подсчетом двух показателей accuracy на test. Набор train подается решению в виде пути в файловой системе, поэтому студенту в его функции для обучения разрешены произвольные действия над всем набором как до, так и после собственно обучения. Набор test подается в функцию студента для предсказания небольшими батчами, то есть без возможности предварительного анализа набора целиком.
Во второй части используются три набора картинок — dev, clean и test. Публикуются первые два набора вместе с обученной моделью с бэкдором. Небольшой набор dev состоит исключительно из картинок, на которых обученная модель ошибается. При этом среди них есть как чистые картинки, так и отравленные невидимым триггером. Этот набор предназначен для исследования студентами возможных индикаторов присутствия триггера в картинке. Набор clean, также небольшого размера, содержит размеченные чистые картинки. Он тоже полезен для разработки алгоритма нейтрализации бэкдора до отправки решений в проверяющую систему.
В проверяющей системе набор dev недоступен. Более того, триггер обученной модели с бэкдором, которая подается на вход решению студента, несколько отличается от триггера опубликованной модели, хотя эти триггеры и синтезированы одним и тем же методом. Проверяющая система позволяет решению выполнить произвольные действия над моделью перед инференсом, в том числе использующие набор clean, копия которого находится в системе. Проверка заключается в предсказании и подсчете двух показателей accuracy на наборе test. Cтуденту разрешено каким-либо образом анализировать тестовые примеры и поведение модели в своей функции для предсказания, однако следует учитывать, что тестовые примеры поступают в решение небольшими батчами и что для первых батчей подсчет каких-либо статистик будет затруднителен.
Решения отправляются в проверяющую систему через telegram-бота. До отправки решений бот потребует ввести ФИО и номер студенческого билета. К решению предъявляются следующие требования, общие для двух частей задания:
- Решение отправляется боту zip-архивом, размер которого не превышает 10 МБ
- В архиве есть файлы
requirements.txt
иsolution.py
, находящиеся в корне (то есть не в какой-либо директории внутри архива). Также там могут присутствовать другие python-модули и даже директории-пакеты, импортируемые изsolution.py
- Максимальное время выполнения программы — 20 минут, по истечении этого времени процесс убивается, и решение считается незасчитанным (об этом уведомляет бот)
При отправке архива решение ставится в очередь. Для каждого студента в очереди может находиться не более одного решения. Загрузка нового решения в момент, когда предыдущее еще не начало проверяться, приведет к удалению предыдущего решения из очереди без проверки, при этом новое решение все равно поставится в конец очереди.
По окончании проверки бот отправляет сообщение. После этого при помощи команды /status
можно посмотреть результаты последнего и лучшего решений (лучшее решение определяется по accuracy на отравленных картинках). Если выполнение решения по какой-то причине завершилось ошибкой, бот отправляет содержимое stderr.
Проверяющая система работает в Docker-контейнере с Python версии 3.10. Системе доступен GPU Tesla A100 80 GB, а также большое количество процессорных ядер (128) и RAM (1 TB). Следующие пакеты Python установлены в операционную систему контейнера:
- numpy
- Pillow
- torch (версия 1.13.0+cu116)
- torchvision (версия 0.14.0+cu116)
- scipy
Крайне нежелательно наличие этих пакетов в файле requirements.txt
в составе решения, просьба их исключать из этого файла. При получении решения проверяющая система специально для него создает виртуальное окружение с доступом к пакетам ОС, куда ставятся все пакеты из requirements.txt
. По окончании проверки окружение удаляется.
В модуле solution.py
должен быть определен класс Model
. У класса должны быть как минимум три метода:
__init__(self, train_root: str) -> None
train(self) -> None
predict(self, batch: torch.Tensor) -> torch.Tensor
Батч расположен на GPU, поэтому просьба предсказания тоже оставлять на GPU. К батчу применяются те же трансформации и нормализация, что и для валидационных данных в этом примере. Проверяющая система однократно запускает train()
и затем итерируется по набору test, многократно запуская predict()
.
В модуле solution.py
должен быть определен класс BackdooredModel
. У класса должны быть методы:
-
__init__(self, net: torch.nn.Module, clean_root: str) -> None
Классу подается обученная модель с бэкдором, уже расположенная на GPU. Архитектура модели известна студентам и совпадает с архитектурой публикуемой версии модели. -
prepare(self) -> None
Произвольные действия, направленные на защиту модели, в том числе использующие набор clean. -
predict(self, batch: torch.Tensor) -> torch.Tensor
Аналогичен первой части задания.
Проверяющая система однократно вызывает prepare()
и затем итерируется по набору test, многократно запуская predict()
.
Загружаемое решение может содержать обе части задания. Однако в целях простоты проверяющей системы время выполнения всего решения все еще будет ограничено 20 минутами.