2017-07-11 1 views
1

Gegeben zwei Matrizen A und B (der Dimensionen N x K) und eine Liste der Indizes iA = (a1, a2 ... aM) für A und iB = (b1, b2 ... bM) für B, brauche ich Folgendes zu tun:Indizieren von Matrizen effizienter (Vermeidung von Gattern)?

lp = 0 
for a in iA: 
    for b in iB: 
     lp += np.sum(A[a,] * B[b,]) 

in Tensorflow. Die Liste der Indizes hat Wiederholungen, daher zeichnen wir dieselbe Zeile mehrmals.

Meine aktuelle Implementierung sieht wie folgt aus:

lp = tf.reduce_sum(tf.multiply(tf.gather(A, iA), tf.gather(B, iB)), 1) 

Allerdings sind die Steigungen ziemlich langsam zu berechnen (vermutlich, weil ich tf.gather bin mit). Man kann annehmen, dass iA in aufsteigender Reihenfolge sortiert ist (so kann eine bestimmte Zeile A [a,] wiederverwendet werden, bis sich 'a' ändert). Gibt es einen besseren Weg, dies zu tun? Jede Hilfe wird geschätzt.

Bearbeiten: A und B sind tf.Variables hier und ändern für jede Iteration. Precomputing ist keine Option. iA und iB sind jedoch Konstanten und ändern sich nicht.

Bearbeiten: M >> N. Größe von K ist nicht wirklich ein Problem.

+0

Als Kommentar zu meiner Antwort. Kannst du uns etwas über deine Größe erzählen? I.e. Wie groß ist N, K, M? –

+0

M >> N. Die Größe von K ist nicht wirklich ein Problem. – mandate

Antwort

0

Je nachdem, wie dicht Ihre Indizes sind, kann es sinnvoll sein, ein Array von Zählwerten einfach vorab zu berechnen. In numpy würde das

counts = np.zeros_like(A) 
np.add.at(counts, iA, 1) 
np.add.at(counts, iB, 1) 

Sie werden dann durch diese durch einfache Multiplikation und Addition der indizierten Summe berechnen könnte:

lp = np.sum(counts * A * B) 

Wenn jedoch iA und iB sind beide sehr spärlich, das gibt ganz etwas Leistungs Overhead. Gleiches gilt, wenn iA oder iB nicht festgelegt sind, sondern sich für jede Iteration ändern.

+0

Meine Lösung funktioniert immer noch, solange 'counts' vorberechnet werden kann. Ist das eine Option? –

+0

Hallo. Danke für die Antwort, aber ich denke, die Frage war ein wenig mehrdeutig. A und B sind Tensorflow's tf.Variables und werden bei jedem Durchlauf aktualisiert, so dass der lp nicht vorberechnet werden kann. iA und IB sind Indizes, also dürfte der zweite Teil der Antwort nicht wirklich helfen. Vorberechnung zählt nicht wirklich eine Option. Danke für Ihre Zeit! Sehr geschätzt. – mandate

+0

Auch sind iA und iB nicht spärlich. Sie sind jedoch festgelegt und ändern sich nicht bei jeder Iteration. :) – mandate