LINUX.ORG.RU

numpy на одинаковых данных даёт немного разный результат

 ,


2

4

Заметил странную особенность numpy - разный результат на одних и тех же данных.

import numpy as np

A = np.random.normal(size=(100, 10000))
B = np.random.normal(size=(10000, 100))

Z1 = np.dot(A, B)
Z2 = np.dot(A, B)

print("A.dtype: %s\nB.dtype: %s" % (A.dtype, B.dtype))
np.testing.assert_almost_equal(Z1, Z2, 13)

output:

A.dtype: float64
B.dtype: float64
..................
AssertionError:
Arrays are not almost equal to 13 decimals

(mismatch 0.02%)
 x: array([[  57.7906116662244,  -23.0575175462736, -199.5869048134938, ...,
         -60.9155744929318,   81.7378975172054,  -29.3638802800916],
       [  90.6673561120846,   75.8409703042503,   81.313634897308 , ...,...
 y: array([[  57.7906116662244,  -23.0575175462736, -199.5869048134938, ...,
         -60.9155744929318,   81.7378975172054,  -29.3638802800916],
       [  90.6673561120846,   75.8409703042503,   81.313634897308 , ...,...

Почему так? Может дело в особенностях параллельного BLAS или Lapack? Неопределенная последовательность суммирования элементов при вычислении матричного произведения?

Такой вариант дает еще больше отличий

Z2 = np.dot(B.T, A.T).T


Хм, проверил на двух интеловых тачках, у меня всё нормально. Какой дистр, какой проц?

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

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Хм, не подумал, что дистр влияет. Заметил это под XP. Под убунту все ок на том же самом компе. Python 2.7, но BLAS/Lapack скорее всего разные.

А вот с транспонированными все равно не совпадает. Но там трудно ждать другого.

Bell ()

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

ptarh ★★★★★ ()
Ответ на: комментарий от ptarh

Спасибо. Сделал так, но он наоборот проапгрейдил кучу других пакетов. Подозреваю, что из-за numpy. Наверно не надо было апгрейдить numpy через pip. Зачем-то я это сделал, но не могу вспомнить, зачем. Я лучше снесу и переставлю Анаконду, так будет проще. Скажи, а с транспонированными результат не совпадает?

Z2 = np.dot(B.T, A.T).T

Bell ()
Ответ на: комментарий от Bell

Сделал так, но он наоборот проапгрейдил кучу других пакетов.

Он апгрейдит всегда до последнего среза, последний срез с numpy 1.9.2 Но увидит ли он numpy, поставленный через pip, действительно не знаю - pip пользоваться явно не стоит. Переставлять не нужно, можно просто в virtualenv залить еще один и переключать. Хотя, переставить его с нуля может быть быстрее, чем возиться с ветками.

Скажи, а с транспонированными результат не совпадает?

Не совпадает.

ptarh ★★★★★ ()
Последнее исправление: ptarh (всего исправлений: 1)
Ответ на: комментарий от Bell

Проверил со свежей Анакондой. Та же фигня. Так что дело, похоже, в XP. Мне это не мешает, просто любопытно, отчего так.

Bell ()

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

В связи с чем, обновлять numpy через pip - достаточно глупая идея. Его «готовить» надо ручками, указывая (как минимум) желаемую версию BLAS.

AlexVR ★★★★★ ()

Посмотри на результат при

export OMP_NUM_THREADS=1

AlexVR ★★★★★ ()
Ответ на: комментарий от AlexVR

В связи с чем, обновлять numpy через pip - достаточно глупая идея. Его «готовить» надо ручками, указывая (как минимум) желаемую версию BLAS.

Как уже выяснилось, дело не в pip - на свежей Анаконде тот же эффект. Однако с OMP_NUM_THREADS=1 у меня полное совпадение. Но это тоже несколько странно - что, у всех отписавшихся здесь однопоточный BLAS? По умолчанию так не должно быть.

Bell ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.