2013-07-05 4 views
11

Ich implementierte ein Gewichtungssystem namens TF-IDF auf einer Menge von 42000 Bildern, die jeweils aus 784 Pixeln bestanden. Dies ist im Grunde eine 42000 mal 784 Matrix. Die erste Methode, die ich versuchte, verwendete explizite Schleifen und nahm mehr als 2 Stunden.Erläutern Sie den Geschwindigkeitsunterschied zwischen der vektorisierten Funktionsanwendung von numpy VS pythons for-Schleife

def tfidf(color,img_pix,img_total): 
    if img_pix==0: 
     return 0 
    else: 
     return color * np.log(img_total/img_pix) 

... 

result = np.array([]) 
for img_vec in data_matrix: 
    double_vec = zip(img_vec,img_pix_vec) 
    result_row = np.array([tfidf(x[0],x[1],img_total) for x in double_vec]) 
    try: 
     result = np.vstack((result,result_row)) 
    # first row will throw a ValueError since vstack accepts rows of same len 
    except ValueError: 
     result = result_row 

Die zweite Methode, die ich verwendet numpy Matrizen versucht und dauerte weniger als 5 Minuten. Beachten Sie, dass data_matrix, img_pix_mat beide 42000 mal 784 Matrizen sind, während img_total ein Skalar ist.

result = data_matrix * np.log(np.divide(img_total,img_pix_mat)) 

Ich hatte gehofft, jemand könnte den immensen Unterschied in der Geschwindigkeit erklären.

Die Autoren der folgenden Arbeit mit dem Titel "The NumPy Array: eine Struktur für effiziente numerische Berechnung" (http://arxiv.org/pdf/1102.1523.pdf), auf der Oberseite der Seite 4, dass sie eine 500-fache Geschwindigkeitserhöhung aufgrund der vektorisierten Berechnung beobachten. Ich nehme an, dass ein Großteil der Geschwindigkeitszunahme, die ich sehe, darauf zurückzuführen ist. Ich möchte jedoch noch einen Schritt weiter gehen und fragen, warum numpy vektorisierte Berechnungen so viel schneller sind als Standard-Python-Schleifen?

Vielleicht kennen Sie vielleicht auch andere Gründe, warum die erste Methode langsam ist. Haben Versuch/Ausnahme Strukturen einen hohen Aufwand? Oder dauert die Bildung eines neuen np.array für jede Schleife eine lange Zeit?

Danke.

+0

Dies verdeutlicht die Gründe, warum numpy Verwendung von C ist viel schneller: http: // stackoverflow.com/q usesions/8385602/warum-sind-numpy-arrays-so-schnell. –

Antwort

6

Aufgrund der internen Abläufe numpy, (soweit ich weiß, arbeitet numpy mit C intern, so alles, was Sie numpy nach unten drücken, ist tatsächlich viel schneller, weil sie in einer anderen Sprache ist)

bearbeiten: die Zip herausnehmen, und es mit einem vstack ersetzen sollte auch schneller gehen, (zip neigt dazu, langsam zu werden, wenn die Argumente sehr groß sind, und als vstack ist schneller), (aber das ist auch etwas, das es in numpy setzt in C), während zip ist python)

und ja, wenn ich richtig verstehe - nicht sicher über das-, machst du 42k mal einen Versuch/außer Block, das sollte definitiv schlecht für die Geschwindigkeit sein,

Test:

T=numpy.ndarray((5,10)) 
for t in T: 
print t.shape 

Ergebnisse in (10,)

Das bedeutet, dass ja, wenn Ihre Matrizen 42kx784 Matrizen sind, können Sie 42k mal ein try-except Block versuchen, ich gehe davon aus, dass sollte einen Effekt in den Berechnungszeiten, sowie jedes Mal eine Zip jedes Mal, aber nicht sicher, wenn das die Hauptursache wäre,

(so dass jeder Ihrer 42k Zeiten Sie Ihre Sachen laufen, nimmt 0,17 sec, ich bin ziemlich sicher, dass ein Versuch/außer Block nicht dauert 0,17 Sekunden, aber vielleicht die ov Er verursacht es oder so, trägt dazu bei?

versucht das zu ändern folgenden:

double_vec = zip(img_vec,img_pix_vec) 
result_row = np.array([tfidf(x[0],x[1],img_total) for x in double_vec]) 

zu

result_row=np.array([tfidf(img_vec[i],img_pix_vec[i],img_total) for i in xrange(len(img_vec))]) 

, dass zumindest wird die Zip-Anweisung los zu werden, aber nicht sicher, ob die Zip-Anweisung Ihrer Zeit um eine Minute dauert nach unten, oder um fast zwei Stunden (ich weiß, Zip ist langsam, im Vergleich zu numpy vstack, aber keine Ahnung, ob das Ihnen zwei Stunden Zeitgewinn geben würde)

+0

Beantwortet das die Frage? oder möchtest du eine technische Antwort? (Im Allgemeinen wird Python nicht schnell ausgeführt, andere Sprachen existieren dafür, aber numpy existiert für diejenigen, die Python verwenden wollen, aber dennoch Geschwindigkeiten erhalten, die mindestens mit den Geschwindigkeiten vergleichbar sind, die Sie in C oder FORTRAN erhalten würden gemacht für Numbercrunching-Anwendungen) – usethedeathstar

+0

Ist es der Reißverschluss, der es verursacht ??? (nur für den zukünftigen Gebrauch wissen, wenn es 42k mal den Zip nennt, der es verursacht?), da es schön wäre zu wissen, ob das einen 2 Stunden Unterschied gibt, oder ob das nur 30min oder so verbessern würde, – usethedeathstar

4

numpy ist in C geschrieben. Der Unterschied, den Sie sehen, ist nicht auf etwas Fantastisches wie SSE-Vektorisierung zurückzuführen; Es ist nur so, dass die C-Implementierung nicht durch die Unmengen an Laufzeit-Methoden-Dispatch- und Exception-Überprüfungen und so weiter gehen muss, die eine Python-Implementierung durchläuft.

Verwandte Themen