www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Когда Pytorch-трансформеры встречают Фастая (с Google Colab)

Дата публикации Aug 26, 2019

Фото с Kapa65 наPixabay

Обновить:

После публикации этой статьи мне посчастливилось получить ответ от Джереми Ховарда, одного из основателей fastai, который предположил, что мы можем использовать систему обратного вызова fastai, чтобы упростить работу здесь, не регулируя фундаментальный цикл обучения в библиотеке fastai.

Это кажется легким исправлением, однако, я пробовал это в течение долгого времени (с помощью@waydegilliам) но не смог все сделать правильно (тренировочная метрика совсем не улучшается…). У меня есть проблемы с этим нафорум фастайи, к счастью, иметьСильвенпроверил код. Тем не менее, показатель все еще не движется, и цикл обучения не эффективен.

Для вашего удобства я скомпилировал Google Colab со всеми результатами. Буду признателен, если у вас возникнут какие-либо мысли о том, в чем проблема:

Google Колаборатория

Изменить описание

colab.research.google.com

Учитывая незначительный дефект, с которым я столкнулся при использовании системы обратного вызова, приведенное ниже решение, казалось бы, «глупый» способ изменить тренировочную петлю, по-прежнему является наиболее оптимальным способом использования Fasttai и Pytorch-преобразователей.

Введение

Если вы будете следовать тенденции глубокого обучения и особенно НЛП, было бы невозможно, чтобы вы не слышали о Фастае илиPytorch-трансформаторы, Эти две библиотеки предлагают дружественный API и гибкие возможности настройки для практиков NLP для создания прототипов и экспериментов. Fastai - это общая библиотека глубокого обучения с тщательно настроенными API-интерфейсами для адаптации к различным приложениям: например текстовая, визуальная, табличная и коллаборативная фильтрация. Pytorch-transformers - это библиотека современных предварительно обученных моделей для обработки естественного языка (NLP), включая модели SOTA, такие как BERT и GPT2. Стоит также отметить, что оба они построены на вершине Pytorch, поэтому создание связей между ними не будет слишком болезненным. Учитывая преимущества обеих библиотек, не было бы неплохо объединить две библиотеки, чтобы мы могли упростить процесс моделирования, используя оба пакета одновременно?

Ответ - да, и это было хорошо задокументировано вэта замечательная статья, В этой статье предлагается процесс преобразования набора данных в специальную форму, чтобы он мог вписаться в модель BERT, которая, в свою очередь, может быть точно настроена с помощью API-интерфейса fastai. Эта статья также вдохновила на написание следующего поста, в котором сравнивались выступления BERT и ULMFiT.

Интеграция Fastai с BERT

ПРОЛОГ

medium.com

Вышеупомянутые статьи проделали потрясающую работу по объяснению всех необходимых деталей в реализации, таким образом, этот пост не будет обсуждаться дальше, но будет главным образом способствовать решению одной ключевой проблемы, возникающей при обновлении библиотеки Pytorch-transformers (из pytorch-pretrained-bert) ,

У нас есть проблемы

Приведенные выше решения и коды работают нормально до обновления Pytorch-трансформеров. Если вы запускаете через коды из вышеупомянутых статей, которые были написаны до обновления. Скорее всего, вас ударит такое исключение:

Если я вам нравлюсь, у кого не было большого опыта работы с Pytorch-трансформерами, вы можете быть крайне растерянными и удивляться, почему это работает для других, но не на моей машине! Не копая слишком много в отслеживании исключения, я подумал, что это произошло потому, что мой Факел устарел. Я обновил Torch до последней версии, но все же получил исключение.

После прочтения документа Pytorch-transformers я понял, что исключение было вызвано изменением API в пакете Pytorch-transformers. Короче говоря, в старые времена ДО обновления Pytorch-трансформаторов,model()выдаст результат после прямого прохода сети; После обновления метод forward модели создает кортеж, первый элемент которого является исходным выходом модели. Если вы хотите больше деталей, пожалуйстачитай здесь,

# If you used to have this line in pytorch-pretrained-bert:
loss = model(input_ids, labels=labels)# Now just use this line in pytorch-transformers to extract the loss from the output tuple:
outputs = model(input_ids, labels=labels)
loss = outputs[0]

Теперь мы выясним причину, по которой наш код ломается, давайте найдем решение.

Решение

Решение состоит в том, что нам нужно изменить код с Fastai, чтобы приспособить изменениеmodel()поведение в Pytorch-трансформеры.

И этот ключевой раздел кода являетсяloss_batch()вbasic_train.pyи мы можем увидетьmodel()вывод не является кортежем и напрямую отправляется в функцию потерь.

def loss_batch(model:nn.Module, xb:Tensor, yb:Tensor, loss_func:OptLossFunc=None, opt:OptOptimizer=None,
cb_handler:Optional[CallbackHandler]=None)->Tuple[Union[Tensor,int,float,str]]:
"Calculate loss and metrics for a batch, call out to callbacks as necessary."
cb_handler = ifnone(cb_handler, CallbackHandler())
if not is_listy(xb): xb = [xb]
if not is_listy(yb): yb = [yb]
out = model(*xb) # Here the output is NOT a tuple
out = cb_handler.on_loss_begin(out)if not loss_func: return to_detach(out), yb[0].detach()
loss = loss_func(out, *yb)if opt is not None:
loss,skip_bwd = cb_handler.on_backward_begin(loss)
if not skip_bwd: loss.backward()
if not cb_handler.on_backward_end(): opt.step()
if not cb_handler.on_step_end(): opt.zero_grad()return loss.detach().cpu()

Как только мы узнаем точное место в библиотеке, изменение похоже на бриз: просто выберите первый элемент вmodel()выведите как показано ниже и предложите функции новое имя:

def loss_batch_bert(model:nn.Module, xb:Tensor, yb:Tensor, loss_func:OptLossFunc=None, opt:OptOptimizer=None,
cb_handler:Optional[CallbackHandler]=None)->Tuple[Union[Tensor,int,float,str]]:
"Calculate loss and metrics for a batch, call out to callbacks as necessary."
cb_handler = ifnone(cb_handler, CallbackHandler())
if not is_listy(xb): xb = [xb]
if not is_listy(yb): yb = [yb]
out = model(*xb)[0] # we take the first element as the model output
out = cb_handler.on_loss_begin(out)if not loss_func: return to_detach(out), yb[0].detach()
loss = loss_func(out, *yb)if opt is not None:
loss,skip_bwd = cb_handler.on_backward_begin(loss)
if not skip_bwd: loss.backward()
if not cb_handler.on_backward_end(): opt.step()
if not cb_handler.on_step_end(): opt.zero_grad()return loss.detach().cpu()

Теперь, когда у нас есть новыйloss_batch_bert()функция, нам нужно заменить оригиналloss_batch()в Фастай, который загружен в нашей среде. Мы могли бы сделать это:

# To change the loss_batch function in the loaded fastai moduleimport sys
module_basic_train = sys.modules['fastai.basic_train']
module_basic_train.loss_batch = loss_batch_bert
sys.modules['fastai.basic_train'] = module_basic_train

Тогда наш скорректированныйloss_batch_bert()встроен в библиотеку Fastai и должен обслуживать Pytorch-трансформеры. Остальное всё волшебство Фастая: собратьLearner()возрази и сделай примерку!

Просто с двумя циклами обучения мы смогли достичь 98 427% в личном списке лидеров! Неплохо, учитывая небольшой объем тренировок и очень «ванильный» тренировочный цикл.

Примечание, если вы не обновили библиотеку Fastai. Если вы хотите увидеть точность во время процесса обучения, вы можете передать функцию обратного вызова точности. Однако функция точности может быть устаревшей, и в ее операторе возврата содержится одна небольшая ошибка:

((y_pred> thresh) == y_true.byte ()). float (). mean ()# не хватает .byte ()

и это можно исправить, как показано ниже

# The more recent version fastai implemented exactly this version thus you could just directly call a partial funtion
# accuracy_thresh
def accuracy_thresh2(y_pred:Tensor, y_true:Tensor, thresh:float=0.5, sigmoid:bool=True)->Rank0Tensor:
"Computes accuracy when `y_pred` and `y_true` are the same size."
if sigmoid: y_pred = y_pred.sigmoid()
return ((y_pred>thresh).byte()==y_true.byte()).float().mean()

Я надеюсь, что эта статья полезна, особенно для людей, которые не были знакомы с Fastai или Pytorch-трансформерами.

Код можно найти вблокнотВот.

Если вы столкнулись с другими проблемами в этом процессе, пожалуйста, дайте мне знать.

Удачного кодирования!

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map