Tagged: numpy

Mathematik
20
Apr
2021

Matrizen-/Matrixmultiplikation

6 0
Lesezeit:4 min, 40 sec

Im Rahmen der Linearen Algebra ist es heute eigentlich Standard-Wissen aus der gymnasialen Oberstufe. Dennoch erreichen mich immer wieder einmal Anfragen zur Matrizenmultiplikation, die sich mehr oder weniger durch das gesamte Feld des Deep- bzw. Machine-Learnings zieht. Die Bezeichnungen Matrixmultiplikation und Matrizenmultiplikation werden synonym verwendet. Die Tatsache, dass die englische Übersetzung “matrix multiplication” ist, führte zur häufigen Verwendung der eingedeutschten Variante.

In diesem Artikel soll nun kurz erklärt werden, wie die Matrizenmultiplikation funktioniert. Die dargestellten Formeln und Prinzipien sollen dem Verständnis dienen, und nicht dem mathematischen Schöngeist. Wer eine ausführliche und detaillierte Information benötigt, der ist auf den Seiten der Wikipedia zu diesem Thema besser beraten.

Die Mathematik

Wir haben zwei Matrizen, die einem ganz bestimmten Format genügen müssen:

\mathbf{A}=\begin{pmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \\ \end{pmatrix},\quad\mathbf{B}=\begin{pmatrix} b_{11} & b_{12} & \cdots & b_{1s} \\ b_{21} & b_{22} & \cdots & b_{2s} \\ \vdots & \vdots & \ddots & \vdots \\ b_{n1} & b_{n2} & \cdots & b_{ns} \\ \end{pmatrix}

Diese Matrizen lassen sich nun miteinander multiplizieren, wenn die Anzahl n der Spalten in Matrix \mathbf{A} gleich der Anzahl der Zeilen in Matrix \mathbf{B} ist.

Dabei ergibt das Produkt aus den beiden Matrizen \mathbf{A}(ij) und \mathbf{B}(jk) eine Matrix \mathbf{C}(ik)

\mathbf{C} = \mathbf{A} \cdot \mathbf{B}

Diese Multiplikation ist nun wie folgt definiert:

c_{ik} = \sum_{j=1}^m a_{ij} \cdot b_{jk}

Um also einen Wert in der Zielmatrix \mathbf{C} an der Position (i,k) zu berechnen müssen jeweils die Einzelwerte der Zeile i aus Matrix \mathbf{A} und die Einzelwerte der Spalte k aus Matrix \mathbf{B} elementweise multipliziert und dann aufsummiert werden.

Matrizen-/Matrixmultiplikation
Schema der Matrizenmultiplikation (Link: Wikimedia)

Umsetzung in Python mit numpy

Die Umsetzung der Matrizenmultiplikation in der Programmiersprache Python ist mit der Bibliothek “numpy” sehr einfach. Wir multiplizieren der Einfachheit halber einmal die beiden folgenden Matrizen:

\mathbf{A}=\begin{pmatrix} 1 & 1 & 1 \\ 2 & 2 & 2 \\ 3 & 3 & 3 \\ 4 & 4 & 4 \\ \end{pmatrix},\quad\mathbf{B}=\begin{pmatrix} 5 & 5 & 5 & 5 & 5 \\ 6 & 6 & 6 & 6 & 6 \\ 7 & 7 & 7 & 7 & 7 \\ \end{pmatrix}

Der Befehl in der Bibliothek “numpy” für die Matrixmultiplikation ist der Befehl numpy.dot(…).

>>> import numpy as np
>>> mat_A = np.array([[1,1,1],[2,2,2],[3,3,3],[4,4,4]])
>>> mat_B = np.array([[5,5,5,5,5],[6,6,6,6,6],[7,7,7,7,7]])
>>> mat_C = mat_A.dot(mat_B)
>>> print(mat_C)
[[18 18 18 18 18]
  [36 36 36 36 36]
  [54 54 54 54 54]
  [72 72 72 72 72]]

Wie man sieht, stimmten die Anzahl der Zeilen der Matrix \mathbf{A} mit der Anzahl der Spalten in Matrix \mathbf{B} überein. Die Ergebnismatrix beinhaltet nun so viele Zeilen wie die Matrix \mathbf{A} und so viele Spalten wie die Matrix \mathbf{B}

Umsetzung in Python für die Harten

Dieser Code dient natürlich nur der Veranschaulichung des Rechenprinzips und kann an vielen Stellen deutlich optimiert werden. Vor allem aber werden keine Prüfungen auf Verletzungen irgendwelcher Bedingungen durchgeführt.

>>> mat_A = [[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
>>> mat_B = [[5,5,5,5,5],[6,6,6,6,6],[7,7,7,7,7]]
>>> m = len(mat_A)
>>> n = len(mat_A[0])
>>> r = len(mat_B[0])
>>> mat_C = [[sum([mat_A[i][j]*mat_B[j][k] for j in range(n)]) for k in range(r)] for i in range(m)]
>>> print(mat_C)
[[18, 18, 18, 18, 18], [36, 36, 36, 36, 36], [54, 54, 54, 54, 54], [72, 72, 72, 72, 72]]

Matrizenmultiplikation mit Vektoren

Die Matrizenmultiplikation mit Vektoren stellt sich als einfachere Variante der Matrizenmultiplikation mit zwei großen Matrizen dar. Die ausführliche Beschreibung dieser vereinfachten Formen findet man auf den Wikipedia-Seiten.

10
Apr
2021

Tensorflow und numpy 1.20.x

6 0
Lesezeit:1 min, 36 sec

In letzter Zeit häufen sich die Meldungen, dass numpy mit der Version 1.20 den Umgang mit “symbolic tensors” massiv verändert hat. Das hat Auswirkungen auf Tensorflow und Keras, die mit der neusten numpy-Version so noch nicht umgehen können. Gute Beispiele sind die Recurrenten Layer von Keras, die sich aktuell noch nicht mit numpy 1.20 verwenden lassen.

Die Lösung

Die aktuell einzige einfache Lösung ist, numpy in der Version 1.19.2 zu installieren (die ist als Minimum für Tensorflow und Keras notwendig).

In einer Anaconda-Umgebung hilft es hier im Terminal folgenden Befehl auszuführen:

conda install numpy=1.19.2

In einer normalen Python-Umgang mit pip:

pip install numpy==1.19.2 --force-reinstall

Beides entfernt das aktuelle Numpy-Paket, und installiert die von Version 1.19.2 – Danach sollte die Fehlermeldung auch verschwunden sein.

Die explizite Lösung

Das Problem mit numpy 1.20 ist ja der Umgang mit symbolischen Tensoren. Das bedeutet, dass die Tensorflow-eigene Datenstrukur des Tensors nicht mehr kompatibel zu den neuen numpy-Tensoren ist. Somit lassen sich die numpy-Operationen nicht mehr auf den sonst kompatiblen Tensorflow-Datenstrukturen ausführen. Ersetzt man nun diese Operationen durch passende aus dem Tensorflow-Paket funktioniert das auch wieder.

Beispiele:

Anstatt np.add ist tf.math.add eine Lösung, oder anstatt np.prod kann man tf.math.reduce_prod nutzen usw. Das funktioniert natürlich nur in eigenem Code, und nicht in mitgelieferten Libraries, wie Keras.