Роберт (Манро) Монарх, —ML- эксперт Apple о том, как сочетать методы Active Learning и Transfer Learning.
Перед началом
В моей предыдущей статье, написанной для PyTorch (Active Learning with PyTorch), я рассмотрел построение блоков для активного обучения. Вам следует начать с неё, если вы не знакомы с Active Learning. Также вам следует посмотреть мои статьи о двух типах активного обучения: Uncertainty Sampling & Diversity Sampling, а также почитать про методы Advanced Active Learning, чтобы комбинировать полученные знания.
В моей бесплатной библиотеке PyTorch также есть наглядные примеры всех алгоритмов активного обучения, включая новые, представленные в этой статье.
Для начала вам следует самостоятельно реализовать более простые стратегии Active Learning, прежде чем переходить к более продвинутым методам, описанным в этой статье.
Что такое Transfer Learning?
Трансферное обучение — это процесс получения модели машинного обучения, созданной для одной конкретной задачи, и ее адаптации к другой.
Адаптировать технологию от одного варианта использования к другому — это весело. Я никогда не забуду ощущений, которые испытал когда выглянул из окна поезда недалеко от Сан-Франциско. Тогда я увидел машину, мчащуюся наравне с поездом в воде лагуны Брисбена. Кто-то переделал DeLorean из «Назад в будущее» в судно на воздушной подушке.
Вы можете испытывать такое же удовольствие каждый раз, когда модель машинного обучения, созданная для одной цели, адаптируется к совершенно новому варианту использования. Если этим вариантом использования является Active Learning, то фактически, мы берем одну из самых весёлых частей машинного обучения для решения важнейшей проблемы: как люди и ИИ могут решать задачи вместе?
Transfer Learning в современном машинном обучении обычно означает использование существующей нейронной модели, а затем повторное обучение последнего слоя (или нескольких последних слоев) для новой задачи, которую можно представить следующим образом:
В Transfer Learning вам вам нужно гораздо меньше примеров, помеченных людьми, особенно сравнивая с тем, если бы вы обучали модель с нуля. Иными словами, вы можете получить модели с более высокой точностью, с меньшим количеством данных.
Как заставить вашу модель предсказывать собственные ошибки
Новые метки для Transfer Learning могут быть любыми категориями. Сюда входит информация о самой задаче! Вот первая из трех основных идей для Active Transfer Learning:
Идея 1: Вы можете использовать трансферное обучение, чтобы спросить свою модель, где она запуталась, заставив ее предсказывать собственные ошибки.
В этой статье рассматриваются три варианта активного трансферного обучения, самый простой из которых — это бинарная задача «правильно / неправильно» для прогнозирования того, где модель может делать ошибки:
Этот процесс состоит из трех этапов:
- Примените модель к проверочному набору данных и определите, какие элементы проверки были классифицированы правильно и неправильно. Это будут ваши новые данные обучения: теперь ваши элементы проверки имеют дополнительную метку «Верно» или «Неправильно».
- Создайте выходной слой для модели и обучите этот слой предсказывать метки «Правильно» / «Неправильно» своим новым обучающим датасетом.
- Пропустите свои немаркированные элементы данных через новую модель и выберите элементы, которые, как предполагается, являются «неправильными», с максимальной достоверностью.
PyTorch делает этот процесс невероятно простым за счет способности передавать активацию каждого нейрона обратно другим процессам, что позволяет нам построить Active Transfer Learning-модель с передачей данных поверх нашей исходной модели. Предположим, у нас есть простая сеть с одним скрытым слоем и функцией forward()
.
def forward(self, feature_vec, return_all_layers=False): hidden1 = self.linear1(feature_vec).clamp(min=0)
output = self.linear2(hidden1)
log_softmax = F.log_softmax(output, dim=1) if return_all_layers:
return [hidden1, output, log_softmax]
else:
return log_softmax
Затем мы можем перебрать наши данные проверки и присвоить каждому элементу проверки значение, будь оно «правильным» или «неправильным». Затем сохраните скрытый слой в качестве входных данных для нашей новой модели:
correct_predictions = [] # validation items predicted correctly
incorrect_predictions = [] # validation items predicted incorrectly
item_hidden_layers = {} # hidden layer of each item, by idfor item in validation_data:
# assume "item" contains id, label & features of each data point
id = item["id"]
label = item["label"]
feature_vector = item["feature_vector"]hidden, logits, log_probs = model(feature_vector, True) item_hidden_layers[id] = hidden # record hidden layer value
if is_correct(label, log_probs):
correct_predictions.append(item)
else:
incorrect_predictions.append(item)
Затем мы можем обучить новую модель предсказанию «Верно» или «Неправильно», используя скрытый слой в качестве нового входного (feature) вектора. Предположим, в нашем коде мы назвали эту новую модель correct_model
.
После обучения новой модели единственная (немного) сложная часть состоит в том, что нам нужно получить прогнозы от обеих моделей для немаркированных данных: один прогноз для получения скрытого слоя из первой модели, а затем второй прогноз для новой модели «Правильно/ Неправильно»:
active_transfer_preds = []with torch.no_grad(): #A
v=0
for item in unlabeled_data:
id = item["id"]
label = item["label"]
feature_vector = item["feature_vector"]# get prediction from initial model
# get predictions from correct/incorrect model
hidden, logits, log_probs = model(feature_vector, True)
correct_log_probs = correct_model(hidden, False)
На этом этапе кодаcorrect_log_probs
есть вероятность того, что неразмеченный элемент будет предсказан правильно. Выбирая элементы с наименьшей степенью уверенности в правильности, вы отбираете образцы, которые должны обладать наивысшей ценностью, чтобы человек мог их рассмотреть и присвоить им метку.
Этот код представляет собой упрощенную версию кода в файле advanced_active_learning.py
: https://github.com/rmunro/pytorch_active_learning/blob/master/advanced_active_learning.py
Вы можете сразу запустить его— (нахождение сообщений, связанных с бедствиями) — со следующей командой:
python advanced_active_learning.py --transfer_learned_uncertainty=10
Это запустит весь процесс, который по итогу представит вам 10 наиболее сомнительных элементов, которым вы сможете указать правильные метки.
На этом этапе модель может быть не лучше, чем более простые алгоритмы выборки неопределенности, так что также неплохо сначала реализовать более простые методы в качестве основы. Но пока не останавливайтесь: это первый шаг к созданию более мощной версии этого алгоритма.
Самым большим преимуществом, которое мы получаем от трансферного обучения по сравнению с более простыми методами, является то, что наша стратегия активного обучения становится адаптивной. Распространенная проблема со стратегиями активного обучения заключается в том, что они отбирают немаркированные элементы, относящиеся к одной части пространства функций. (и поэтому не имеют разнообразия). Следовательно нехобходимы методы выборки разнообразия, такие как кластеризация. Это нужно, чтобы избежать этой проблемы. Существуют методы расширенного активного обучения, которые комбинируют выборку неопределенности и разнородность по отдельности, но методы в этой статье имеют преимущество, т.к. объединяют две модели в единую архитектуру.
Часто бывает сложно получить человеческие метки в режиме реального времени, и более практично отобрать большое количество немаркированных предметов и пометить их как партию. Таким образом, в этих случаях Active Transfer Learning для адаптивной репрезентативной выборки может быть адаптивным во время процесса выборки, даже если мы еще не знаем, какие будут метки.
Активное трансферное обучение для репрезентативной выборки
Во многих реальных кейсах ваши данные меняются со временем. Например, в случае использования автопилотного транспортного средства — встречаются новые типы объектов, и область действия может быть расширена, например, движением по открытой воде в дополнение к дорогам.
Representative Sampling — это форма Diversity Sampling, которая нацелена на выборку немаркированных элементов, которые больше всего похожи на прикладную область модели машинного обучения (относительно текущего датасета для обучения).
Поскольку наши выбранные элементы позже получат метки от человека, мы можем предположить, что они станут частью обучающих данных, где не будет необходимости знать, что это за метка.
Шаги выглядят так:
- Возьмите данные проверки из того же дистрибутива, что и данные обучения, и присвойте им метку «Training». Возьмите немаркированные данные из нашего целевого домена и дайте ему метку «Application».
- Обучите новый выходной слой предсказанию меток Training/Application, предоставив ему доступ ко всем слоям модели.
- Примените новую модель к немаркированным данным и выберите элементы, которые наиболее достоверно предсказываются как «Application».
- Предположим, что вновь выбранные элементы позже получат метку и станут частью обучающих данных: измените метку этих элементов с «Application» на «Training», а затем повторите всё с шага 2.
Это невероятно мощный алгоритм, поскольку он позволяет избежать выборки элементов только из одной части пространства функций. Вместо этого он отбирает образцы разнообразного набора предметов перед нанесением какой-либо маркировки человеком.
Идея 2: Вы можете предположить, что элемент без метки позже получит метку, даже если вы еще не знаете, что это за метка.
Active Transfer Learning для Adaptive Sampling (ATLAS)
Самое изощренное использование Active Transfer Learning — это Active Learning для Adaptive Sampling (ATLAS). Он объединяет принципы двух предыдущих моделей в этой статье: прогнозирование неопределенности и адаптация к данным до добавления каких-либо человеческих меток.
Здесь помогает наша аналогия с путешествием во времени. Представьте, что вы превратили своё авто в машину времени, но чтобы путешествовать во времени вам нужно проехать по дороге со скоростью 88 миль в час. Вы можете отправить эту машину в будущее, зная, что через годы дорога тоже будет там, даже если вы еще не знаете, как эта дорога будет выглядеть или что еще будет вокруг дороги. Затем вы можете начать строить планы на будущее, учитывая в них, что автомобиль тоже будет там, даже без полного знания этого контекста.
Мы можем сделать то же самое с нашими моделями, предполагая, что у нас есть знания о данных, которые мы позже помечаем и используем для принятия будущих решений. Если быть точным — для выборки еще большего количества данных для проверки человеком:
Шаги выглядят так:
- Примените модель к набору данных проверки и определите, какие элементы проверки были классифицированы правильно и неправильно. Это ваши новые данные для обучения: теперь ваши элементы проверки имеют дополнительную метку «Верно» или «Неправильно».
- Создайте новый выходной слой для модели и обучите этот новый слой своим новым обучающим данным, предсказывая новые метки «Правильно» / «Неправильно».
- Пропустите свои немаркированные элементы данных через новую модель и выберите элементы, которые, как предполагается, являются «неправильными», с максимальной достоверностью.
- Предположим, что вновь выбранные элементы позже получат метки и что модель позже будет правильно предсказывать эти элементы после обучения на них: измените метку этих элементов с «Неправильно» на «Верно», а затем повторите всё с шага №2.
Скомбинировав методы Active Transfer Learning для выборки неопределенности и адаптивной репрезентативной выборки, мы имеем модель, которая может предсказывать своё будущее состояние. Она не знает, каковы будут ярлыки для элементов, из которых производится первоначальная выборка, но она знает, что они получат ярлык, после чего она сможет принимать более разумные решения по отбору образцов на основе ожидаемого будущего события.
Идея 3: вы можете предположить, что ваша модель правильно предсказывает метку неразмеченных элементов, которая идентична элементам, которые позже получат метку, даже если вы еще не знаете, какую именно.
Этот код находится в том же файле, что и выше, advanced_active_learning.py
: https://github.com/rmunro/pytorch_active_learning/blob/master/advanced_active_learning.py
Вы можете запустить его из командной строки с помощью:
python advanced_active_learning.py --atlas=10
Вот одностраничная шпаргалка, на которую вы можете ссылаться при построении алгоритмов из этой статьи:
Вы также можете скачать PDF-версию шпаргалки здесь:
http://www.robertmunro.com/Active_Transfer_Learning_Cheatsheet.pdf
Эта статья и шпаргалка взяты из моей книги “Human-in-the-Loop Machine Learning”: https://www.manning.com/books/human-in-the-loop-machine-learning. Главы моей книги публикуются по мере их написания, и теперь доступна глава, содержащая методы активного переноса обучения, включая ATLAS!
Прочитайте эту книгу для более глубокого изучения вариантов архитектуры, которые вы можете сделать для Active Transfer Learning. Вот несколько примечаний для начала:
- Это (математически) эквивалентно удалению последнего слоя и повторному обучению нового слоя (как на изображениях выше) или взятию выходных данных из последнего скрытого слоя (-ев) и использовании его в качестве входных данных для новой модели (как в примерах кода). Я думаю, что первый слой более интуитивно понятен визуально, но второй менее подвержен ошибкам в коде, потому что он чисто добавочный. Следовательно, вам не нужно беспокоиться о том, как изменение вашей модели может повлиять на другие части вашего кода. Если вы предпочитаете иную реализацию Transfer Learning в вашем собственном коде, это нормально. Это также верно для тех случаев, когда вы хотите поиграть с настройкой существующих слоев с новыми данными/метками вместо полного удаления слоев: это совместимо с методами Active Transfer Learning, которыми я здесь поделился.
- Обратите внимание, что пример репрезентативной выборки использует все скрытые слои, а также добавляет новый дополнительный слой, в то время как примеры неопределенности и ATLAS представляют собой простое двоичное предсказание после последнего скрытого слоя. Это задумано как хорошая отправная точка для ваших архитектур, но вы можете экспериментировать с разными архитектурами во всех случаях. Обоснование этих отправных точек заключается в том, что последние уровни нашей модели не различают низкую активацию плохо представленных элементов (в данных), от элементов, которые представлены лучше, но имеют функции, не имеющие отношение к модели в её текущей форме. Таким образом, репрезентативная выборка должна лучше работать с информацией из более ранних слоев. Для контраста: в примерах, где используется выборка неопределенностии и ATLAS задействован только последний уровень: последний слой модели уже оптимизирован для минимизации неопределенности. Следовательно, маловероятно найти больше сигнала в ранних слоях. Так модель будет более расположена к переобучению (если вы включить более ранние слои).
- Вы можете рассмотреть несколько моделей и / или прогнозы переменных из одной модели с помощью выборки Монте-Карло. Эти примеры основаны на данных проверки из того же распределения, что и ваша обучающая область, и вы можете легко переобучить конкретные элементы в этом наборе проверки. Если вы разделяете тренировочные данные 90:10 в обучение — повторите проверку (как в примерах кода)для всех комбинаций 90:10. Обратите внимание, что для примеров Uncertainty Sampling и ATLAS вы создаете только один новый двоичный предиктор, поэтому вам не нужно слишком много данных, чтобы результаты были надежными. Это хорошее свойство этих моделей: одно дополнительное двоичное предсказание легко обучить с относительно небольшим объемом данных и часто без ручной настройки.
- Active Transfer Learning может работать с более сложными задачами, такими как обнаружение объектов, семантическая сегментация, маркировка последовательностей и создание текста. Практически любой тип нейронной модели может добавить новый слой для предсказания меток «Верно / Неправильно» или «Training / Application», так что это очень универсальный метод. Я расскажу о том, как лучше всего подойти к этим и другим вариантам использования в следующей главе книги!