Как стать автором
Обновить

Алгоритмы и структуры данных для численных вычислений с автоматической оценкой точности

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров1.7K
Всего голосов 7: ↑7 и ↓0+7
Комментарии6

Комментарии 6

Хм, а нельзя ли просто написать те же алгоритмы с целыми числами? Целочисленная арифметика и точнее и быстрее.

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

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

Это очень сильно замедлило бы. Да, есть boost/intervals, но для начала память увеличивается вдвое (а в xnumpy плюс байт на значение с плавающей точкой). И сами алгоритмы от классической теории погрешностей утяжеляют сильно. Здесь вместо этого используется число обусловленности для дифференцируемых функций, overhead получается вообще небольшой вместо минимум удвоения только на памяти и куда более тяжких алгоритмах. А для всяких округлений функции переписываются из glibc, чтобы не проходить два раза те же ветвления. Плюс к тому, особо важные функции типа матричного умножения (из blas/cublas/mkl) очень эффективны, но вроде не реализованы мощно для интервальной арифметики, вручную сделать настолько же эффективно и надёжно огромная проблема, а это нередко самые тяжеловесные операции. А оценки точностей в точных битах сводят всё к тем же матричным операциям с использованием тех же очень сильно оптимизированных библиотек при помощи оценки тропического произведения целочисленных матриц. Подход с точными битами потому и выбран, что иначе либо пользоваться станет невозможно, либо переписывать огромный тяжеловесный код, который десятки лет оптимизировали, это надо использовать, а не отказываться и переделывать с нуля. Матричные умножения с оценкой точных битов могут становиться тяжелее в разы, а если пытаться наивно посчитать точность интервалами, то медленнее станет в тысячи раз, что неприменимо на практике. С тригонометрией интервалы минимум удваивают стоимость вычислений, а в подходе с точными битам через число обусловленность получается overhead в процентах (например, на exp +21%, на log10 +9% по последнему бенчмарку, тогда как для intervals подсчёт для концов интервала и дополнительные проверки дадут сходу >100% overhead). Плюс к тому, для оценки точности мантиссы в битах часто вместо дополнительных операций с плавающей точкой используется целочисленная арифметика и работа с битовыми масками согласно представлению floating point в памяти, что тоже позволяет сделать ряд оптимизаций (как для арифметики, округлений). Но если добавить к увеличению времени ещё требование сокращать батч вдвое, то для нейронок на трансфере данных до gpu и обратно станет тратиться ещё большее время, так что выгоднее пользоваться оценкой точных битов вместо классических погрешностей очень сильно, а насколько именно, сильно зависит от железа и конкретных нейронок.

И библиотеку можно попробовать на каких то известных ML моделях? Ну так, чтобы сравнить величину ошибки модели с numpy и xnumpy... Посоветуйте простую известную модель?

Простейший нетривиальный вариант, как всегда, LeNet на MNIST. Или пусть даже полносвязную нейронку в несколько слоёв на том же датасете (или тогда уж на чём попало), потому что известно, что MLP на MNIST тоже учится, пусть и не очень хорошо.

Можно при выводе массивов смотреть на массив xf64array (неточное будет помечено вопросиками), а также на вывод отдельно значений (поле values массива типа xf64array) и количества точных битов (поле exact_bits). Единственное, что это всё-таки расширение numpy, а не torch, так что исходную модель надо брать, где вычисление градиентов дополнительно реализуется, но такое в открытом доступе найти несложно, особенно, для чего-то простейшего типа MLP. Только надо поменять импорты numpy на xnumpy, и в большинстве случаев этого будет достаточно. И входные данные при конвертации в xf64array неплохо бы снабдить их естественной погрешностью. Например, если значения пикселей целые от 0 до 255, мы делим это на 256 для получения float, то логично предположить, что там вряд ли более 8 точных битов, а то и меньше, потому что это относительная погрешность.

Если выводить только values, то вывод будет, как если бы считалось на numpy, значения могут только чуть-чуть отличаться, если зависимые версии glibc, blas и прочие чуть-чуть поменялись, но это несущественные и крайне редкие изменения. Разница не в величине ошибки numpy и xnumpy, а в том, что в xnumpy величину ошибки мы знаем, а в numpy не имеем инструмента измерения ошибки вычислений, принимаем их как есть. Ошибки и какая-то мера их накопления неизбежны, а так можно эту величину увидеть без больших усилий заменой импорта. Поиграв с реализацией алгоритма, можно посмотреть, какие варианты надёжнее. И хотя выбор всё равно за лучшей целевой метрикой, из вариантов выбора важно исключить те, которым нельзя верить, зная величину их численной ошибки.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий