2015-12-29 10 views
5

Używam Theano/NumPy do robienia głębokich rzeczy do nauki. Znalazłem bardzo irytujący problem. Mam matrycę wagi A (przypuszczalnie 50 * 2048) i wektor właściwości b (2048 dim).Precyzja NumPy, gdy robimy produkt z kropką

A jest inicjalizowane za pomocą

self.alpha = np.random.random((50, 2048)).astype(np.float32) * 2 - 1.0 

B wynosi 2048 słabe numpy.ndarrary z Theano.

Problemem jest

X = numpy.dot(A, b) 
Y = [numpy.dot(A[i], b) for i in xrange(50)] 

niektóre rzędy X i Y nie są równe. Porównałem je i stwierdziłem, że różnica wynosi od 1e-6 do 1e-7.

Obecnie wolę używać drugiego do obliczenia produktu kropki, ponieważ wydaje się, że może nauczyć się lepszych wag. Ale pierwszy jest znacznie szybszy. Zastanawiam się, dlaczego istnieje tak wielka różnica. Czy przyczyną są różne implementacje kropek (matryca, wektor) i kropka (wektor, wektor)? Wielkie dzięki!

--edit Jak wspomniano, jest to kod, który można odtworzyć.

import numpy as np 

test_time = 1000 
vector_size = 100 
matrix_size = (100, 100) 

for i in xrange(test_time): 
    a = np.random.random(matrix_size).astype(np.float32) * 2 - 1.0 
    b = np.random.random(vector_size).astype(np.float32) 
    x = np.dot(a, b) 
    y = [np.dot(a[i], b) for i in xrange(a.shape[0])] 
    for k in xrange(len(y)): 
     epsilon = x[k] - y[k] 
     if abs(epsilon) > 1e-7: 
      print('Diff: {0}\t{1}\t{2}'.format(x[k], y[k], epsilon)) 
+0

Czy możesz zduplikować problem za pomocą mniejszej liczby cyfr, które możesz uwzględnić w pytaniu? Zobacz [Jak utworzyć przykład minimalny, kompletny i sprawdzalny] (http://stackoverflow.com/help/mcve). Czasami, izolując to zjawisko, możesz znaleźć problem w tym procesie. – uhoh

+0

Mogę replikować problem z dowolnym rozmiarem tablicy ... – Julien

+0

Dlaczego jest różnica, nie wiem. Dlaczego jest tak duży, ponieważ używasz float32. Zostaw to float64 (wiem, że nie jest to zgodne z używaniem theano GPU), a różnica spada do e-14/-15. – Julien

Odpowiedz

2

Cóż, zwykle istnieje kompromis między wydajnością i precyzją. Być może będziesz musiał zrekompensować jedno lub drugie. Chociaż osobiście nie wierzę, że różnica 0.0000001 jest duża w większości zastosowań. Jeśli szukasz wyższej precyzji, lepiej pójdź z float64, ale zauważ, że operacje float64 są bardzo powolne w procesorach graficznych, zwłaszcza w procesorach graficznych z serii NVIDIA 9xx.

Mogę zauważyć, że wspomniany problem wydaje się zależeć od ustawień sprzętowych, ponieważ nie napotkam takiego problemu na moim komputerze.

Możesz także użyć np.allclose(x, y), aby zobaczyć, czy różnica jest namacalna.

Powiązane problemy