Forum: PC-Programmierung Python: Matrixprodukt mit Tensorkomponenten, wie?


von Schmidt (Gast)


Lesenswert?

Hallo liebe Gemeinschaft,


ich bin relativ neu im Bereich Python unterwegs und habe eine Frage an 
euch.

Ausgangssituation
Python 3.5
NumPy 1.16


Meine Problem ist folgendes:

Ich habe einen Tensor, welcher Bildinformationen enthält. Nehmen wir an, 
er habe die Dimensionen T^30x300x300. Jeder der 300x300 "Pixel"-Vektoren 
beinhaltet somit 30 Elemente.

Ich möchte nun eine Matrizenmultiplikation auf diese 30 Elemente eines 
jeden Pixelvektors durchführen, und das möglichst zeiteffektiv.

Somit wäre in Pseudo-Python-Code:

V[:] = T[:][j][i] der Vektor, welcher die Elemente des Pixels i, j 
beinhaltet. Leider funktioniert bereits dieser Übertrag nicht.

Nun soll eine Matrix M^30x30 auf V mit MV = V' angewendet werden und 
anschließend der neue Vektor V' als V'= T'[:][j][i] als neuer Tensor T' 
abgelegt werden.

---

1. Dieses Problem kann als for-Schleife und der Einsteinsumme gelöst 
werden, was jedoch ewig dauert.

2. Es gibt die Funktion np.matmul (Matrix, Vektor), welche bei mir 
jedoch stets Dimensionsfehler ausgibt.

---

Gibt es da einen offiziellen und effektiven Weg? Vielleicht habt ihr ein 
Schlagwort für mich, dass ich nachlesen kann?


Ich freue mich auf gute Ideen von euch

Schmidt

von Christopher J. (christopher_j23)


Lesenswert?

Die Syntax
1
a = T[i][j][k]

funktioniert als Verkettung des [] operators, d.h. intern läuft so etwas 
ab wie
1
a1 = T[i]
2
a2 = a1[j]
3
a = a2[k]

Da T[:]==T kommst du nicht zum gewünschten Ergebnis
1
T[:][j][k]

schreibst du das einfach als
1
T[:,j,k]

kurzes Beispiel:
1
>>> T = np.arange(2*4*4).reshape(2,4,4)
2
>>> T
3
array([[[ 0,  1,  2,  3],
4
        [ 4,  5,  6,  7],
5
        [ 8,  9, 10, 11],
6
        [12, 13, 14, 15]],
7
8
       [[16, 17, 18, 19],
9
        [20, 21, 22, 23],
10
        [24, 25, 26, 27],
11
        [28, 29, 30, 31]]])
12
# das wäre ein Beispiel mit 4x4 Pixeln mit jeweils zwei Werten, d.h. zwei 4x4 Matrizen als Stapel
13
14
>>> T[:,1,1]
15
array([ 5, 21])
16
# so funktioniert es aber immer daran denken, dass Python 0-based indexing hat ;)
17
18
>>> M = np.array([[2,0],[0,2]])
19
>>> M
20
array([[2, 0],
21
       [0, 2]])
22
# als Beispiel verdoppeln wir einfach die Werte
23
24
>>> np.matmul(T[:,0,0],M)
25
array([ 0, 32])
26
# das wären die Werte für den ersten Pixel. Das könnte man jetzt in eine Schleife packen und drüber iterieren aber einfacher ist es das Array zu transformieren
27
28
>>> T.reshape(2,16)
29
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
30
       [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]])
31
# jetzt haben wir eine 2x16 Matrix, so dass matmul() damit arbeiten kann
32
# d.h. (2x2)*(2x16)->(2x16)
33
34
>>> np.matmul(M,T.reshape(2,16))
35
array([[ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30],
36
       [32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62]])
37
# das ganze dann wieder zurücktransformieren:
38
39
>>> T1 = np.matmul(M,T.reshape(2,16)).reshape(2,4,4)
40
>>> T1
41
array([[[ 0,  2,  4,  6],
42
        [ 8, 10, 12, 14],
43
        [16, 18, 20, 22],
44
        [24, 26, 28, 30]],
45
46
       [[32, 34, 36, 38],
47
        [40, 42, 44, 46],
48
        [48, 50, 52, 54],
49
        [56, 58, 60, 62]]])
50
51
# wie man sehen kann wurden alle Werte verdoppelt

Die reshape-Operationen dürften sehr günstig sein, da meines Wissens 
nach nur die äußere Repräsentation der Daten geändert wird aber sie nach 
wie vor linear im Speicher liegen und damit keine Rechenzeit in 
irgendwelchen Schleifen verbummelt wird.

von Sven B. (scummos)


Lesenswert?

Um mir genau zu überlegen wie ist es zu warm, aber das lässt sich doch 
bestimmt mit "np.einsum" in einem Aufruf lösen.

von Programmierer (Gast)


Lesenswert?

Schmidt schrieb:
> Ich habe einen Tensor, welcher Bildinformationen enthält. Nehmen wir an,
> er habe die Dimensionen T^30x300x300.

Hmm, warum hast Du den Tensor?

Doch bestimmt weil du mit Machine Learning rum machst, oder?

Warum dann nicht einfach eines der bekannten Frameworks dafür nehmen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.