Вероятность этикеток и вывод нескольких этикеток

Это третья часть серии статей о том, как максимально эффективно использовать GPT-3 для задач классификации текста (см. первую часть о сокращении числа выходящих за рамки прогнозов и часть вторую про подсказки тонкой настройки со спектрами вероятностей). В этом посте будет описан метод получения результатов с несколькими метками и улучшения результатов классификации.

В Edge Analytics мы используем GPT-3 и другие передовые технологии NLP для создания комплексных решений. Ознакомьтесь с нашей недавней работой с inVibe с использованием GPT-3 для улучшения процесса исследования рынка!

Что такое GPT-3?

GPT-3 означает Генеративный предварительно обученный трансформатор 3. Она создана компанией OpenAI и на момент написания является самой большой моделью в своем роде, состоящей из более 175 миллиардов параметров. Он также был предварительно обучен с использованием одного из крупнейших текстовых корпусов, состоящих из около 499 миллиардов токенов (примерно 2 триллиона символов), что включает значительную часть всего текста, доступного в Интернете.

GPT-3 использует текстовый интерфейс. Он принимает последовательность текста (т. Е. «Подсказку») в качестве входных данных и выводит последовательность текста, которая, по его мнению, должна быть следующей (т. Е. «Предсказание» или «завершение»). Благодаря этому удивительно простому интерфейсу GPT-3 может давать впечатляющие результаты. Уловка состоит в том, чтобы создать правильную подсказку для извлечения нужных знаний, закодированных в GPT-3.

На момент написания GPT-3 находится в частной бета-версии. Вам необходимо подать заявку на доступ на сайте OpenAI. Мы рекомендуем посмотреть это видео на YouTube, чтобы получить хорошее представление о процессе и несколько советов по получению доступа.

Интерпретация вероятностей метки

Есть еще один метод, который мы используем в Edge Analytics, чтобы получить максимальную отдачу от GPT-3, и он связан с тем, как мы интерпретируем выходные данные API. API GPT-3 не просто возвращает предсказанный текст; он также возвращает некоторые метаданные о прогнозе, такие как продолжительность запроса и точная версия используемой базовой модели. Особый интерес для нас представляет поле под названием top_logprobs, которое содержит натуральный логарифм вероятности для каждого возможного токена для каждой части прогноза. Формат поля top_logprobs затрудняет интерпретацию на первый взгляд. Однако с помощью некоторых дополнительных этапов обработки мы можем использовать его для повышения точности и преобразования вывода с одной меткой в ​​вывод с несколькими этикетками.

Давайте посмотрим на конкретный пример. Мы будем использовать следующую подсказку:

Classify each of the following foods as either a fruit or a vegetable.
Food: apple
Label:

Если мы просто посмотрим на спектры вероятностей на игровой площадке, мы увидим, что главный прогноз GPT-3 - «фруктовый» с вероятностью ~ 33%. Может показаться, что GPT-3 не очень уверен в предсказанном ярлыке. Однако это еще не все. Как мы вскоре увидим, причина того, что эта вероятность относительно мала, связана с форматированием. GPT-3 не уверен, следует ли писать метку с заглавной буквы, следует ли ее ставить пробелом или заключать в кавычки. В действительности, «фрукт», «фрукт» и «фрукт» имеют одинаковое семантическое значение, только с небольшими различиями в форматировании. Мы должны попытаться учесть подобные сходства, чтобы получить наиболее точный прогноз.

Вот первые три элемента в массиве top_logprobs (хотя для нашего примера этого достаточно, в некоторых случаях может потребоваться рассмотреть больше, чем только первые три элемента):

"top_logprobs": [
  {
    "\n": -6.6079745,
    " vegetable": -4.0431094,
    " ": -6.2982974,
    " Fruit": -1.9344363,
    " Veget": -4.888889,
    "Ve": -10.074649,
    "ve": -9.217822,
    "fruit": -6.2173643,
    "F": -8.124118,
    " fruit": -0.1926153
  },
  {
    "\n": -0.0059370887,
    " vegetable": -6.9535685,
    " ": -5.4001474,
    " Fruit": -11.35315,
    " Veget": -8.579499,
    "Ve": -12.559547,
    "ve": -11.902375,
    "fruit": -12.914117,
    "F": -14.043984,
    " fruit": -8.356797
  },
  {
    "get": -6.502035,
    "\n": -0.4551382,
    " vegetable": -8.820861,
    " ": -4.151076,
    "Ve": -4.243354,
    "ve": -5.310599,
    "fruit": -5.189734,
    "F": -1.1317282,
    "able": -8.674933,
    " fruit": -7.591307
  }
]

Во-первых, давайте преобразуем эти числа в более знакомый нам формат. В документации это точно не сказано, но, как вы уже догадались, числа в top_logprobs - это просто натуральный логарифм вероятности. Преобразовать их в вероятность от 0 до 1 просто:

import numpy as np
def logprob_to_prob(logprob: float) -> float:
    return np.exp(logprob)
>>> logprob_to_prob(-1.9344363)
0.14450570373415098

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

def prob_for_label(label: str, logprobs: List[Dict[str, float]]) -> float:
    """
    Returns the predicted probability for the given label as
    a number between 0.0 and 1.0.
    """
    # Initialize probability for this label to zero.
    prob = 0.0
    # Look at the first entry in logprobs. This represents the
    # probabilities for the very next token.
    next_logprobs = logprobs[0]
    for s, logprob in next_logprobs.items():
        # We want labels to be considered case-insensitive. In
        # other words:
        #
        #     prob_for_label("vegetable") =
        #         prob("vegetable") + prob("Vegetable")
        #
        s = s.lower()
        if label.lower() == s:
            # If the prediction matches one of the labels, add
            # the probability to the total probability for that
            # label.
            prob += logprob_to_prob(logprob)
    return prob

Обратите внимание, что иногда токены в logprobs не совсем равны метке, а скорее являются префиксами метки. Вот здесь и появляется рекурсия. Например, если лексема в logprobs - «Vege», мы перефразируем проблему, перебирая остальную часть logprobs и ища остальную часть метки (в данном случае «таблицу»).

def prob_for_label(label: str, logprobs: List[Dict[str, float]]) -> float:
    """
    Returns the predicted probability for the given label as
    a number between 0.0 and 1.0.
    """
    # Initialize probability for this label to zero.
    prob = 0.0
    # Look at the first entry in logprobs. This represents the
    # probabilities for the very next token.
    next_logprobs = logprobs[0]
    for s, logprob in next_logprobs.items():
        # We want labels to be considered case-insensitive. In
        # other words:
        #
        #     prob_for_label("vegetable") =
        #         prob("vegetable") + prob("Vegetable")
        #
        s = s.lower()
        if label.lower() == s:
            # If the prediction matches one of the labels, add
            # the probability to the total probability for that
            # label.
            prob += logprob_to_prob(logprob)
        elif label.lower().startswith(s):
            # If the prediction is a prefix of one of the labels, we
            # need to recur. Multiply the probability of the prefix
            # by the probability of the remaining part of the label.
            # In other words:
            #
            #     prob_for_label("vegetable") =
            #         prob("vege") * prob("table")
            #
            rest_of_label = label[len(s) :]
            remaining_logprobs = logprobs[1:]
            prob += logprob * prob_for_label(
                rest_of_label,
                remaining_logprobs,
            )
    return prob

На этом этапе все, что нам нужно сделать, это вызвать prob_for_label для каждой из наших меток: «овощ» и «фрукт». В конце этого процесса мы получаем вывод с несколькими метками с вероятностью от 0,0 до 1,0 для каждой возможной метки:

{
  "fruit": 0.78,
  "vegetable": 0.05,
  "other": 0.17
}

Резюме

В этом посте мы описали метод использования logprobs для повышения точности текстовых классификаторов на основе GPT-3. В приведенном выше примере этот метод дает нам более полную картину вероятности для ярлыка «фрукт». Наивный подход оценил вероятность в 33%, что, казалось, указывает на то, что GPT-3 не был уверен в своем прогнозе. Однако наш новый метод показывает, что вероятность ближе к 78%, что говорит нам, что GPT-3 достаточно уверен в ответе.

Второе важное преимущество заключается в том, что этот метод дает нам вывод с несколькими метками, которые в противном случае не предоставляются напрямую API GPT-3. Мы можем использовать результаты с несколькими метками, чтобы понять, что на самом деле думает GPT-3, и уточнить наши прогнозы. Например, для анализа настроений, если и «положительный», и «отрицательный» имеют относительно высокую вероятность, это может быть хорошим показателем того, что наиболее подходящим ярлыком действительно должен быть «смешанный».

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

GPT-3 в Edge Analytics

Edge Analytics помогла нескольким компаниям создать решения, использующие GPT-3. В более широком смысле мы специализируемся на науке о данных, машинном обучении и разработке алгоритмов как на периферии, так и в облаке. Мы обеспечиваем сквозную поддержку на протяжении всего жизненного цикла продукта, от быстрых исследовательских прототипов до алгоритмов AI / ML производственного уровня. Мы сотрудничаем с нашими клиентами, от компаний из списка Fortune 500 до инновационных стартапов, чтобы воплотить их идеи в жизнь. Имеете в виду сложную проблему? Свяжитесь с нами по адресу [email protected].

Максимальное использование классификаторов текста на основе GPT-3: Часть 1, Часть 2, Часть 3