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

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

Ассоциативность дополнения

Сложение между действительными числами является ассоциативным, что выражается в свойстве:

Давайте проверим это с помощью Python3.

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

Такое поведение прекрасно объясняется арифметикой с плавающей запятой.

Как работает арифметика с плавающей запятой

В представлении с плавающей запятой базы B и точности p числа представлены как:

где e - показатель степени в фиксированном диапазоне.

Не все действительные числа точно представимы для заданной точности и базы. Например, в то время как 0,1 точно представляется в базе 10 с любой точностью, большей 1, она не может быть представлена ​​в базе 2 для любой конечной точности p, что приводит к ошибке усечения.

Используя представление с плавающей запятой основания 2 и точности 3, давайте рассмотрим два числа: a = 1,01 x 2⁰ и b = 1,11 x 2¹. Чтобы вычислить сумму a + b, мы сначала сдвигаем биты a, чтобы выровнять значения экспоненты, и, поскольку у нас точность равна 2, мы теряем один бит (красный) информации:

Теперь посчитаем сумму, получим:

И снова мы теряем немного информации в результате. Если мы проверим результат, у нас изначально было a = 1,25 и b = 3,5, поэтому a + b = 4,75. Используя наше представление с плавающей запятой, мы получили a + b = 4, что является ошибкой 0,75.

Теперь рассмотрим операции a + (a + b) и (a + a) + b. Для первого получаем:

У нас снова возникает ошибка усечения, которая дает окончательный результат 5, в то время как истинный результат равен 6. Теперь во втором случае a + a не дает ошибки усечения:

И прибавляя к результату значение b получаем:

Это дает окончательный результат без ошибки усечения, что действительно соответствует (a + a) + b = 6.

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

Как ошибки усечения влияют на воспроизводимость

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

  1. Чтение данных из запроса к базе данных.
  2. Перебор неупорядоченных наборов (например, наборов, хэш-карт).
  3. Параллельные вычисления.

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

Подведение итогов

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

Ссылки

Что каждый программист должен знать об арифметике с плавающей запятой

Воспроизводимая агрегация с плавающей запятой в СУБД