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

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

Кураторские наборы валидации

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

Мотивирующий пример

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

def nextDate(year: Int, month: Int, day: Int) = …

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

assert nextDate(2021, 2, 8) == (2021, 2, 9);

Мы, конечно, не могли предоставить тесты для всех возможных входных данных, поэтому тестировщикам нужно выбрать, какие входные данные попробовать, чтобы получить уверенность в правильной реализации функции. Если бы это была модель с машинным обучением, мы бы выбрали случайную выборку из распределения соответствующих входных данных. Например, мы можем случайным образом выбрать 500 дат между 1 января 1900 года и 31 декабря 2099 года. При написании тестов вручную тестировщики программного обеспечения обычно не выбирают случайные входные данные, а целенаправленно выбирают входные данные для тестирования различных аспектов программы.

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

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

Не все входные данные равны

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

Идея о том, что не все ошибки модели одинаково важны, также отражена в упомянутой ранее цитате Джорджа Бокса:

«Поскольку все модели неверны, ученый должен быть готов к тому, что неправильно. Неуместно беспокоиться о мышах, когда за границей водятся тигры». - Джордж Бокс, 1976 г.

Важные и менее важные ошибки: рассмотрим случай с голосовым помощником. Есть команды, которые чаще всего используются пользователями, такие как «Какая завтра погода» или «Позвони маме», тогда как ошибки в менее распространенных фразах, например, «Добавить асафетиду в мой список покупок», могут быть более простительны. Таким образом, вместо того, чтобы рассматривать все входные данные как равные, мы должны определить важные варианты использования, которые, возможно, стоит протестировать отдельно, и убедиться, что обновление модели не нарушит их. В сценарии обнаружения рака мы могли бы ожидать, что определенные виды рака более важны для обнаружения, чем другие, более поддающиеся лечению виды.

Справедливость и систематические ошибки. В огромном количестве литературы о справедливости в машинном обучении (см. также главу о справедливости) указывается на предвзятость в моделях и системах. При тех же настройках голосового помощника системы допускают гораздо больше ошибок, когда говорящие принадлежат к группе меньшинств (например, сообщается, что на 35% больше неправильно идентифицируемых слов от людей, которые были чернокожими; см. Статью в New York Times). В примере с обнаружением рака точность может сильно различаться в зависимости от пола, возраста и этнических групп. Меньшинства часто недопредставлены в обучающих и тестовых данных (часто даже в большей степени, чем они недопредставлены в популяции пользователей в производственной среде), и такие различия могут быть даже не замечены.

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

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

Нарезка ввода

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

Теперь вопрос заключается в том, как определить и выбрать подходящие наборы тестов.

Хороший способ поиска важных субпопуляций и дисбалансов между субпопуляциями – это нарезать (или разбить) все входное распределение и отобрать выборки для каждой секции. При необходимости нам может потребоваться собрать больше данных для определенных разделов, чем обычно, если бы мы просто случайным образом выбирали из целевой совокупности.

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

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

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

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

Концептуально такое разделение входного пространства очень похоже на традиционную стратегию тестирования тестирование класса эквивалентности. При использовании этого метода анализируется спецификация программы, чтобы сгруппировать возможные входные данные в классы эквивалентности по нескольким измерениям. Анализируя спецификацию и знание предметной области вокруг примера nextDate, можно сгруппировать набор всех возможных дат в 8 групп: отрицательные числа (например, -1), 0, 1–27, 28, 29, 30, 31 и числа. больше 31. Кроме того, можно также сгруппировать годы на високосные и невисокосные, а также на годы до 2038 года и после 2038 года, а также можно сгруппировать месяцы по длине и так далее. Как правило, классы эквивалентности могут быть получены из спецификаций разными способами: по задачам, по диапазонам входных данных, по условиям ошибок, по ожидаемым ошибкам и т. д. При традиционном тестировании программного обеспечения тестировщик затем создает тестовый пример для каждой группы (известное как тестирование класса слабой эквивалентности) или каждого взаимодействия групп (известное как тестирование класса сильной эквивалентности). В контексте машинного обучения вместо создания каждого отдельного теста мы создали бы набор тестов с несколькими помеченными входными данными для каждого среза, чтобы измерить точность предсказания в каждом срезе.

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

Применение в реальных условиях: система Overton в Apple. Apple внутри компании использует систему под названием Overton, которая фокусирует внимание специалиста по данным на повышении точности модели для различных срезов входного пространства, по одному срезу за раз. . Он предоставляет специалистам по данным способы программного разделения данных на основе различных критериев и создает отдельные отчеты о точности для каждого слоя. Затем специалисты по данным обычно сосредотачиваются на улучшении модели для одного среза за раз. Например, они могут исследовать особенно сложные или неэффективные задачи в голосовых помощниках, как правило, улучшая обучающие данные для этого среза (эти системы в основном используют слабый контроль, поэтому обучающие данные в первую очередь улучшаются за счет добавления дополнительных функций маркировки, чтобы пометить больше производственных данных для обучение). Исследователи данных могут написать функцию среза для обнаружения запросов, связанных с питанием или запросов со сложными неоднозначностями среди входных данных. Найдя срезы с результатами с низкой точностью, они могут затем приложить усилия для предоставления более маркированных обучающих данных для этого среза. То есть этот подход позволяет специалистам по данным сосредоточиться на более решаемой проблеме повышения точности отдельных срезов пользовательских входных данных, а не пытаться улучшить модель для всего входного пространства сразу.

Тестирование возможностей модели

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

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

Как только мы определим интересующую возможность, мы сможем подобрать подходящие тестовые данные. Если доступно достаточно тестовых данных, мы можем просто выделить их из общего пула тестовых данных, как обсуждалось выше. Чаще всего мы специально отбираем данные для проверки возможностей. Например, мы могли бы сгенерировать множество предложений с отрицанием положительных предложений и отрицанием отрицательных предложений и, возможно, даже предложений с двойным отрицанием, чтобы проверить способность модели понимать отрицание. Точно так же мы можем специально создавать предложения, в которых автор и другие субъекты имеют разные чувства, чтобы проверить, правильно ли модель усвоила концепцию приоритета автора. Мы также можем создавать варианты сканирования в сценарии обнаружения рака, добавляя искусственный шум к частям сканирования или регулируя яркость. Опять же, мы не ищем ни одного неверного прогноза, но мы хотим курировать наборы тестов для каждой возможности, состоящие из нескольких входных данных, особенно тех входных данных, которые сложно получить правильно, не изучив целевую возможность.

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

Определение возможностей. Основная проблема при тестировании возможностей модели машинного обучения – определить соответствующие возможности. Здесь мы снова возвращаемся к проблеме отсутствия четких спецификаций. Тем не менее, для многих задач у нас может быть хорошее концептуальное понимание ингредиентов, которые, вероятно, необходимы для того, чтобы модель выполняла задачу, аналогичную человеческой. Например, в своей статье ACL 2020 Ribeiro et al. упомянем среди прочего следующие возможности коммерческого инструмента анализа настроений:

  • Словарь+POS: Модель обладает необходимым словарным запасом и может правильно обрабатывать слова в разных частях предложения.
  • Настроение: модель понимает наиболее распространенные слова, которые несут позитивные и негативные настроения.
  • Таксономия: модель правильно обрабатывает синонимы, антонимы и т. д.,
  • Устойчивость к опечаткам: модель не искажается из-за простых опечаток, таких как замена двух символов, например, "no thakns"
  • Нерелевантность: модель правильно игнорирует нерелевантные части предложений, такие как URL-адреса.
  • Именованные объекты: модель правильно идентифицирует и обрабатывает именованные объекты; например, смена двух мест или людей не повлияет на настроение всего предложения, например, «Я скучаю по #nerdbird в Сан-Хосе» vs «Я скучаю по #nerdbird в Денвере».
  • Маркировка семантической роли: модель признает настроение автора более важным, чем мнение других, например. "Некоторые люди думают, что вы превосходны, но я думаю, что вы противны"
  • Справедливость: модель не связывает настроения только на основе гендерных частей предложений.
  • Упорядочивание: модель понимает порядок событий и его отношение к настроению предложения, например, она должна обнаруживать утверждения о прошлых и текущих мнениях и сообщать текущее как настроение, например, «Раньше я ненавидел это авиакомпанией, хотя теперь она мне нравится».
  • Отрицание: способность правильно определять, как отрицание в предложениях влияет на настроение, например, "Это не паршивое обслуживание клиентов"

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

Снова сравнивая возможности с традиционными модульными тестами, возможности могут относиться к простым тестам минимальной функциональности, таким как простой тест, устанавливающий, что основная функциональность действительно работает, или они могут тестировать определенные сложные части проблемы, такие как обработка ожидаемых крайних случаев. Можно даже протестировать антипаттерны быстрого поведения, которые модель не должна демонстрировать, как только они будут идентифицированы как общий источник неверных прогнозов. Традиционные методы создания тестов, основанные на анализе частей спецификации, могут дать вдохновение, даже если у нас нет четкого описания проблемы (например, анализ теорий того, как люди подходят к проблеме, или анализ распространенных ошибок). Например, анализ граничных значений — это классический метод тестирования для анализа границ заданного поведения и создания тестовых случаев конкретно в этих границах (например, начало и конец месяца для nextDate) или за пределами границ (например, 0 или 13 для месяцев в nextDate). Эти методы могут послужить источником вдохновения для поиска краеугольных случаев и сложных концепций для тестирования в качестве возможностей в ML.

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

Интересным потенциальным преимуществом возможностей тестирования является то, что это может помочь нам выбрать модели, которые лучше обобщают данные вне распределения. Идея, подробно изложенная в статье Д'Амура и др. заключается в том, что среди многих возможных моделей, которые имеют аналогичную точность при традиционной оценке точности тестовых данных из того же распределения, что и обучающие данные, те модели, которые изучили предполагаемые возможности, более устойчивы к пониманию данных вне распределения. Интуиция подсказывает, что эти возможности отражают человеческие концепции или важные принципы, которые люди определили как важные для общей проблемы; следовательно, эти возможности могут обобщаться лучше, чем любые другие правила, которые алгоритм машинного обучения может вывести во время обучения. Это оправдывает курирование тестовых данных, которые не соответствуют распределению обучения, а вместо этого относятся к конкретным возможностям, которые, как мы ожидаем, будут важны для прогнозов за пределами текущей целевой группы.

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

Автоматизированное (случайное) тестирование и инварианты

Генерация случайных входных данных для тестирования программы проста, и существует много исследований в области разработки программного обеспечения по фазз-тестированию и другим методам создания тестовых сценариев, которые имели большой успех в обнаружении определенных видов ошибок во многих программах. программы. Например, CSmith обнаружил сотни ошибок компилятора, загрузив компиляторы случайными программами. Ключевой проблемой при создании всех тестовых примеров является определение того, когда сгенерированный ввод действительно идентифицировал ошибочное поведение.

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

@Test
void testNextDate() {
  nextDate(488867101, 1448338253, -997372169)
  nextDate(2105943235, 1952752454, 302127018)
  nextDate(1710531330, -127789508, 1325394033)
  nextDate(-1512900479, -439066240, 889256112)
  nextDate(1853057333, 1794684858, 1709074700)
  nextDate(-1421091610, 151976321, 1490975862)
  nextDate(-2002947810, 680830113, -1482415172)
  nextDate(-1907427993, 1003016151, -2120265967)
}

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

@Test
void testNextDate() {
  nextDate(2010, 8, 20)
  nextDate(2024, 7, 15)
  nextDate(2011, 10, 27)
  nextDate(2024, 5, 4)
  nextDate(2013, 8, 27)
  nextDate(2010, 2, 30)
}

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

@Test
void testCancerPrediction() {
  cancerModel.predict(generateRandomImage())
  cancerModel.predict(generateRandomImage())
  cancerModel.predict(generateRandomImage())
}

Сложным шагом в этом подходе является не задача создания входных данных, а знание того, что ожидать от заданных тестовых входных данных. Является ли вычисление nextDate правильным для сгенерированных входных данных? В случае машинного обучения проблема заключается в том, чтобы знать, каким должен быть результат прогноза, то есть метка для сгенерированных изображений. Это известно как проблема оракула. Не зная, чего ожидать, мы не будем знать, будет ли тестовый пример неудачным или успешным, или как измерить точность модели. Проблема оракула затрагивает как традиционное программное обеспечение, так и модели машинного обучения.

Проблема с оракулом

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

Есть несколько распространенных стратегий решения проблемы оракула при случайном тестировании:

  • Вручную указать результат. Люди часто могут предоставить ожидаемый результат, основываясь на своем понимании или на основе спецификации проблемы, но это, очевидно, не масштабируется при создании тысяч случайных входных данных и не может быть автоматизировано. Хотя это утомительно, люди потенциально могут обеспечить ожидаемый результат для задач nextDate и обнаружения рака со случайными входными данными. Но даже при краудсорсинге задачи маркировки в условиях машинного обучения для многих задач не всегда ясно, смогут ли люди давать метки для «случайных» входных данных — особенно тех, которые не похожи на обычные производственные данные. В условиях машинного обучения мы снова страдаем от отсутствия спецификации, которую можно было бы использовать для определения ожидаемого результата.
@Test
void testNextDate() {
  assert nextDate(2010, 8, 20) == (2010, 8, 21);
  assert nextDate(2024, 7, 15) == (2024, 7, 16);
  assert nextDate(2011, 10, 27) == (2011, 10, 28);
  assert nextDate(2024, 5, 4) == (2024, 5, 5);
  assert nextDate(2013, 8, 27) == (2013, 8, 28);
  assert nextDate(2010, 2, 30) throws InvalidInputException;
}
float evaluateCancerPredictionAccuracy() {
  // random inputs
  xs = [loadImage("random1.jpg"), loadImage("random2.jpg"), loadImage("random3.jpg")];
  // manually provided labels
  ys = [true, true, false]; 
  return accuracy(cancerModel, xs, ys)
}
  • Сравнение с золотым стандартом. Если у нас есть альтернативная реализация (обычно более медленная, но известная как правильная реализация, которую мы хотим улучшить) или некоторая форма исполняемой спецификации, мы можем использовать их для простого вычисления ожидаемый результат. Например, у нас может быть эталонная реализация nextDate в библиотеке, с которой мы можем сравнить нашу собственную реализацию. Даже если мы не совсем уверены в правильности альтернативной реализации, мы можем использовать ее для выявления и исследования расхождений или даже голосования, когда существует несколько реализаций. Такие формы дифференциального тестирования оказались чрезвычайно успешными, например, при поиске ошибок компилятора с помощью CSmith. К сожалению, мы обычно используем машинное обучение именно тогда, когда у нас нет спецификации и нет существующего эталонного решения; например, маловероятно, что у нас будет золотой стандарт реализации алгоритма обнаружения рака.
@Test
void testNextDate() {
  assert nextDate(2010, 8, 20)==referenceLib.nextDate(2010, 8, 20);
  assert nextDate(2024, 7, 15)==referenceLib.nextDate(2024, 7, 15);
  assert nextDate(2011, 1, 27)==referenceLib.nextDate(2011, 1, 27);
  assert nextDate(2024, 5, 4) ==referenceLib.nextDate(2024, 5, 4);
  assert nextDate(2013, 8, 27)==referenceLib.nextDate(2013, 8, 27);
  assert nextDate(2010, 2, 30)==referenceLib.nextDate(2010, 2, 30)
}
float evaluateCancerPredictionAccuracy() {
  imgs = ["random1.jpg", "random2.jpg", "random3.jpg"];
  correct = 0
  for (img <- imgs)
    if (cancerModel.predict(loadImage(img)) == 
                        otherModel.predict(loadImage(img)))
      correct += 1
  return correct / img.length
}
  • Проверка частичных спецификаций. Даже если у нас нет полной спецификации проблемы (например, ожидаемого результата для каждого входа), иногда у нас есть частичные спецификации или инварианты. Частичная спецификация описывает некоторые аспекты поведения, которые мы хотим гарантировать, даже если мы не знаем ожидаемого результата вычислений; например, мы можем знать, что принимаем только положительные входные данные или что все выходные данные являются непустыми списками. Некоторые частичные спецификации определяют глобальные инварианты внутренних компонентов программы, например, программа никогда не должна давать сбой, программа не должна обращаться к неинициализированной памяти, все дескрипторы открытых файлов должны быть закрыты до завершения программы или целые числа никогда не должны переполняться. Большинство подходов к нечеткому тестированию ищут ошибки, приводящие к сбоям, или нарушения других глобальных инвариантов, таких как небезопасный доступ к памяти. То есть вместо проверки того, что для данного входа результат соответствует некоторому ожидаемому результату, мы только проверяем, что вычисление не приводит к сбою или не нарушает заданную частичную спецификацию. Разработчики также могут вручную задавать частичные спецификации с помощью утверждений, которые обычно указываются как часть пред- и пост-условий функции или инварианта цикла (хотя разработчики часто неохотно пишут даже такие). Инструкции Assert преобразуют нарушения во время выполнения этих частичных спецификаций в сбои или исключения. Обратите внимание, что частичные спецификации сосредоточены только на определенном аспекте правильности, который должен соблюдаться для всех выполнений, и могут ничего не говорить о том, действительно ли программа производит желаемый результат.
    В условиях машинного обучения нас обычно это не интересует. в ошибках, которые приводят к сбою моделей или выдают исключения, так как это редкое явление. Вместо этого нас в основном беспокоят модели, которые возвращают неправильный результат для заданных входных данных. Как упоминалось ранее, у большинства задач машинного обучения нет четкой спецификации. Однако есть некоторые частичные спецификации, которые мы можем определить для моделей, которые, возможно, стоит протестировать, в том числе частичные спецификации для возможностей, справедливости и надежности, где автоматическое тестирование может быть полезным, как мы обсудим ниже.
@Test
void testNextDate_NoException() {
  // tests that no exception is thrown for any input
  nextDate(2010, 8, 20)
  nextDate(2024, 7, 15)
  nextDate(2011, 10, 27)
  nextDate(2024, 5, 4)
  nextDate(2013, 8, 27)
}
@Test
void testCancerPrediction_NoException() {
  // we don't really worry about crashing bugs
  cancerModel.predict(generateRandomImage())
  cancerModel.predict(generateRandomImage())
  cancerModel.predict(generateRandomImage())
}
  • Моделирование и обратные вычисления — в некоторых сценариях можно смоделировать мир для получения пар вход-выход или для получения соответствующих входных данных для случайно выбранных выходных данных. Например, при выполнении простой факторизации легко выбрать набор простых чисел (выход) и вычислить ввод путем их умножения. В настройках машинного зрения можно создать сцену в трассировщике лучей (с известным расположением объектов), а затем визуализировать изображение, чтобы создать входные данные для алгоритма зрения для обнаружения этих изображений. Случаи, когда получить входные данные из выходных проще, чем наоборот, кажутся не очень распространенными, но это может быть очень мощной стратегией, если она работает, потому что мы можем автоматически генерировать пары вход-выход.
@Test
void testFactorization_3_4_7_7_52673() {
  randomNumbers = [2, 3, 7, 7, 52673];
  assert factorPrime(multiply(randomNumbers))) == randomNumbers;
}
@Test
void testScene931() {
  scene = compose(street, 
                  (car, car_coordinates), 
                  (pedestrian, ped_coordinates));
  assert pedestriantDetector.predict(render(scene)) == true;
}

Инварианты и метаморфическое тестирование

Для оценки моделей с машинным обучением кажется неясным, сможем ли мы когда-либо автоматически генерировать пары ввода-вывода вне некоторых настроек моделирования (обсуждаемых ниже). Однако стоит подумать о частичных спецификациях поведения модели. Однако в отличие от инвариантов, которые определяют ограничения на поведение отдельного выполнения, инварианты, используемые в настройках машинного обучения, обычно описывают отношения между предсказаниями разных или связанных входных данных. Вот несколько примеров инвариантов для модели f:

  • Модель кредитного рейтинга f не должна зависеть от пола: для всех входных данных x и y, которые отличаются только полом f(x)=f (у). Это довольно упрощенное свойство справедливости (иногда называемое антиклассификацией; см. главу о справедливости), которое не учитывает корреляции, но его легко сформулировать как инвариант.
  • На анализ тональности f не должны влиять синонимы: Для всех входных данных x: f(x) = f(x.replace(“isn not”, “isn 'т"))
  • Отрицание должно поменять тональность предложения: для всех входных данных x в форме «X есть Y»: f(x) = 1-f(x.replace(«is», «is не "))
  • Небольшие изменения в обучающих данных не должны влиять на результат: для всех x в нашем обучающем наборе f(x) = f(mutate(x, δ)). Это известно как свойство устойчивости в литературе (подробности см. в главе о безопасности).
  • Низкий кредитный рейтинг никогда не должен давать кредит: для всех претендентов на получение кредита x: (x.score‹645) ⇒ ¬f(x). Здесь мы указываем достаточноеусловие для классификации в качестве инварианта, известное как якорь в объяснимом машинном обучении (см. лекцию об интерпретируемости).

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

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

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

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

∀x. f(g(x)) = h(f(x))

где g — функция, связывающая два входа, а h — функция, связывающая два выхода модели f.

Например, приведенный выше инвариант справедливости можно сформулировать как функцию g, которая меняет пол в данных входных данных, а h — это просто функция идентичности, утверждающая, что ожидаемый прогноз — это то же самое для каждой пары связанных входных данных (не зная, каков ожидаемый прогноз). Точно так же инвариант отрицания имеет функцию g(x)=x.replace("есть", "не является") для отрицания значения предложения и h(x)=1- x, чтобы указать, что ожидаемая тональность между двумя предложениями должна быть противоположной (не зная конкретного значения ни того, ни другого).

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

Например, в той же статье ACL, о которой говорилось выше, Ribeiro et al. протестируйте следующие возможности с инвариантами в инструменте определения тональности:

  • Замена нейтральных слов другими нейтральными словами не должна влиять на тональность текста, например, «кошмар продолжается…» vs «наш кошмар продолжается…»
  • Добавление URL-адресов не должно влиять на настроение текста.
  • Опечатки от перестановки двух соседних символов не должны влиять на тональность текста.
  • Изменение названий локаций не должно влиять на тональность текста.
  • Изменение имен людей не должно влиять на тональность текста.
  • Добавление в текст позитивных фраз не должно повышать негативную тональность более чем на 0,1; добавление в текст негативных фраз не должно повышать положительную тональность более чем на 0,1, т.е. «Отличная поездка на 2672 вчера…» vs «Отличная поездка на 2672 вчера… Вы необыкновенны»
  • Вставка отрицания в предложение с нейтральной тональностью не должна менять тональность, например, «Этот самолет является частным» вместо «Этот самолет не является частным».

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

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

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

Другая стратегия определения инвариантов заключается в поиске инвариантов, которые модель уже изучила, их просмотре и сохранении полезных в качестве регрессионных тестов. Эти инварианты уже встречаются по определению (иначе поиск их бы не нашел), но они все еще могут быть полезны для понимания и регрессионного тестирования. Для поиска существующих инвариантов в традиционных исследованиях в области разработки программного обеспечения было предложено несколько методов анализа спецификаций, причем Daikon, вероятно, является наиболее известным инструментом. В контексте машинного обучения работа над якорями, вероятно, наиболее близка: якоря — это инварианты, которые описывают входные условия, достаточные для получения заданного результата; чтобы найти якоря, система ищет шаблоны, которые являются общими для многих входных данных, которые дают один и тот же прогноз. В большинстве случаев они описывают инварианты отношений ввода-вывода, а не метаморфические отношения. Первоначально якоря были предложены для объяснения решений модели и отладки проблем (см. главу об интерпретируемости).

Генерация входных данных. По сравнению с определением инвариантов создание входных данных обычно намного проще.

Ранние подходы фаззинга просто генерировали случайные входные данные, например, случайные последовательности битов, но, поскольку немногие из этих входных данных представляют собой общие или действительные входные данные, многие из них уже отбрасываются на ранних стадиях программы (например, nextDate(488867101, 1448338253, -997372169)). поэтому тесты редко достигают более глубокой логики, чтобы проверить более интересное поведение. Было разработано множество более разумных стратегий для создания более качественных тестов. Например, разработчики могут указать тип генерируемых входных данных, чтобы ограничить генерацию допустимыми входными данными, например, предоставив грамматику или распределения для всех входных данных. В то же время многие методы, такие как динамическое символьное выполнение и фаззинг на основе покрытия, автоматически анализируют реализацию, чтобы идентифицировать входные данные, которые выполняют больше кода в реализации, или специально направляют входные данные к тем, которые обнаруживают аварийное поведение.

Для создания входных данных для тестирования инвариантов машинного обучения у нас также существует множество различных стратегий:

  • Равномерно случайная выборка: создание чисто случайных входных данных; то есть единая выборка из домена каждой функции. Этот подход относительно прост, но, как правило, не дает много входных данных, похожих на типичные входные данные в целевом распределении. Например, сгенерированные изображения будут выглядеть как белый шум и редко будут похожи на снимки рака. Подобно ранней работе с фаззингом, эта стратегия, вероятно, не очень эффективна для многих задач.
  • Моделирование входных распределений: если мы можем описать целевое распределение, мы можем сделать выборку из этого распределения. В самых простых случаях мы могли бы указать распределения для каждой функции отдельно; например, мы можем опираться на реалистичное распределение возраста, пола и веса для больных раком, но хотя каждая характеристика может быть реалистичной сама по себе, их комбинация может быть не такой, как у годовалого ребенка весом 80 кг. Мы также можем моделировать вероятностные отношения между признаками, чтобы использовать более реалистичные распределения, например, используя вероятностное программирование.
  • Изучение входных распределений. Вместо того, чтобы моделировать распределения вручную, используя знания предметной области, мы также можем изучать их на основе выборочных данных целевой совокупности. Опять же, мы можем изучить распределения отдельных признаков или определить корреляции между признаками. Мы также можем использовать такие методы, как обобщенные состязательные сети, чтобы изучить генератор, который имитирует обучающие данные, хорошо известный созданием глубоких поддельных изображений.
  • Изменение существующих входных данных. Многие инварианты описываются с точки зрения сходств и различий между двумя входными данными. Здесь часто бывает просто взять входные данные из существующего набора тестов и изменить их, чтобы создать один или несколько дополнительных входных данных, следуя одному из многих шаблонов.
  • Состязательное обучение. Многие методы состязательного обучения специализируются на поиске входного пространства, обычно с использованием градиентного спуска, для входных данных, которые максимизируют цель, где нарушение спецификации часто может быть закодировано как цель. Например, классические методы состязательного обучения пытаются найти входные данные, которые нарушают свойство устойчивости, которое утверждает (выражаемое как метаморфическое отношение), что модель должна делать одинаковые прогнозы, когда два входных данных очень похожи. Это концептуально похоже на стратегии генерации тестовых случаев, основанные на динамическом символьном выполнении или фаззинге, управляемом покрытием в традиционном тестировании программного обеспечения.
  • Формальная проверка. Для некоторых свойств и моделей можно формально доказать определенные инварианты. Для некоторых типов моделей определенные виды доказательств на самом деле довольно просты (например, доказательство того, что ни один кандидат с кредитным рейтингом ниже 645 не будет одобрен для кредита в модели дерева решений или что ни одно решение в модели решений не зависит от пола кандидата). кандидат). Для других, таких как свойства надежности в глубоких нейронных сетях, методы автоматической формальной проверки являются областью активных исследований. Если свойство не может быть доказано, некоторые методы формальной проверки предоставляют контрпримеры, которые можно проверить или использовать в качестве тестов.

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

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

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

Тестирование на основе моделирования

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

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

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

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

Критерии адекватности

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

Отчет о покрытии линий и ответвлений при тестировании ПО

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

  • Охват спецификации анализирует, были ли протестированы все условия спецификации (граничные условия и т. д.). Учитывая, что у нас нет спецификаций для моделей машинного обучения, лучшее, что мы можем сделать, — это подумать о репрезентативности проверочных данных, о подгруппах, о возможностях и о вариантах использования при курировании нескольких проверочных наборов.
  • Покрытие белого ящика, такое как покрытие строк и покрытие ветвей, дает нам представление о том, какие части программы были выполнены. Были попытки определить аналогичные метрики покрытия для глубоких нейронных сетей (например, покрытие нейронов), но неясно, что на самом деле представляет собой эта мера. Например, являются ли входные данные, генерируемые для охвата всех активаций нейронов, репрезентативными для чего-либо значимого?
    Показатели покрытия белого ящика иногда используются для управления поиском входных данных, нарушающих инварианты, мало чем отличаясь от их использования в минимизации набора тестов или на основе охвата. фаззинг, но методы состязательного обучения, по-видимому, обеспечивают более прямые методы поиска в моделях, чем методы, основанные на покрытии.
  • Оценка мутаций показывает, насколько хорошо набор тестов обнаруживает внедренные в программу ошибки (мутанты). Например, мы можем случайным образом заменить операцию «+» на операцию «-» в программе и посмотреть, достаточно ли хорош набор тестов, чтобы обнаружить эту введенную ошибку, не пройдя некоторые ранее пройденные тесты. Лучший тестовый набор обнаружит больше введенных ошибок. Однако, опять же, сопоставление с моделями с машинным обучением неясно. Будут ли более тщательно отобранные проверочные наборы обнаруживать больше мутаций параметров модели машинного обучения (или мутаций гиперпараметров или мутаций в некоторых обучающих данных), и будет ли это полезно на практике для оценки качества проверочных наборов и т.п.? Когда мы будем считать обнаруженной введенную ошибку, если у нас нет спецификации и измерения точности по всему набору тестовых данных?

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

Резюме

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

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

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

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

Чтения и ссылки

Как и все главы, этот текст выпущен под лицензией Creative Commons 4.0 BY-SA.