Aller au contenu principal

Formalisme mathématique - Tenseurs

Un réseau de neurone fait ses opérations sur des tenseurs. (addition, multiplication, tanh, ...) On va donc chercher d'abord à tout bien implémenter pour les tenseurs.

Tenseurs​

On a souvent tendance à ne pas comprendre ce qu'est un tenseur initialement, mais il faut imaginer ces objets comme la généralisation des scalaires/vecteurs/matrices a nn dimensions.

Définition​

Pour la définition d'un tenseur, je renvoie à l'excellent post de "Robot Chinwag" sur le sujet. Cependant, vous pouvez vous arrêter avant la partie "Tensor Calculus" (et tout ce qu'il y a après) car on va utiliser des principes différents, cette partie ne sera donc pas utile pour nous.

D'orénavant, on posera T\mathcal{T} l'espace des tenseurs, et T(N)\mathcal{T}(N) celui des tenseurs d'ordre NN.

Par exemple:

Consideˊrons un tenseur A∈R3×2×2⊂T(3). On peut le voir comme deux matrices empileˊes :\text{Considérons un tenseur } A \in \mathbb{R}^{3 \times 2 \times 2} \subset \mathcal{T}(3). \text{ On peut le voir comme deux matrices empilées :} A=[[a111a112a121a122],[a211a212a221a222],[a311a312a321a322]].A = \begin{bmatrix} \begin{bmatrix} a_{111} & a_{112} \\ a_{121} & a_{122} \end{bmatrix}, \quad \begin{bmatrix} a_{211} & a_{212} \\ a_{221} & a_{222} \end{bmatrix}, \quad \begin{bmatrix} a_{311} & a_{312} \\ a_{321} & a_{322} \end{bmatrix} \end{bmatrix}. Autrement dit, Ak,i,j deˊsigne l’eˊleˊment situeˊ aˋ la position (i,j) dans la k-ieˋme matrice.\text{Autrement dit, } A_{k, i, j} \text{ désigne l’élément situé à la position } (i,j) \text{ dans la $k$-ième matrice.}

On note également dA(i)\mathcal{d}_A(i) la dimension d'ordre ii. Dans ce cas, on a dA(1)=3 et dA(i)=2 pour i∈{2,3}\mathcal{d}_A(1) = 3 \text{ et } \mathcal{d}_A(i) = 2 \text{ pour } i \in \{2, 3\}

Transposée​

Soit A=azij∈T(N),N≥2A = a_{zij} \in \mathcal{T}(N)\text{,} N \geq 2.

Alors

A⊤=azjiA ^{\top} = a_{zji}

Avec i,ji, j les indices des 2 dernières dimensions. L'indice zz représente l'indice de "batch", soit le reste des dimensions précédentes. Si les dimensions d'un tenseur sont i1,...,iNi_1, ..., i_N, alors il faut considérer zz comme i1,...,iN−2i_1, ..., i_{N-2}.

Broadcast​

Un concept important pour les tenseurs est celui du broadcast. Il était déjà expliqué dans le post de "Robot Chinwag", mais je vais mettre des examples afin de rendre la notion plus compréhensible.

Un exemple simple peut être lorsqu'on multiplie un vecteur par un scalaire. Cela peut se voir comme le broadcast du scalaire sur la shape du vecteur puis une multiplication élément par élément. Ex:

[123]∗3=[123]∗[333]=[1∗32∗33∗3]=[369]\begin{bmatrix} 1 & 2 & 3 \end{bmatrix} * 3 = \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} * \begin{bmatrix} 3 & 3 & 3 \end{bmatrix} = \begin{bmatrix} 1*3 & 2*3 & 3*3 \end{bmatrix} = \begin{bmatrix} 3 & 6 & 9 \end{bmatrix} ouˋ ∗ deˊsigne le produit eˊleˊment par eˊleˊment (Hadamard)\text{où } * \text{ désigne le produit élément par élément (Hadamard)}

Voici un exemple plus avancé:

Soient A∈R3×1etB∈R1×4.\text{Soient } A \in \mathbb{R}^{3 \times 1} \quad\text{et}\quad B \in \mathbb{R}^{1 \times 4}. A=[123],B=[10203040].A = \begin{bmatrix} 1 \\[2mm] 2 \\[2mm] 3 \end{bmatrix}, \qquad B = \begin{bmatrix} 10 & 20 & 30 & 40 \end{bmatrix}. Lors d’une opeˊration eˊleˊment-par-eˊleˊment (par ex. C=A+B ), les deux tenseurs sont broadcasteˊs pour obtenir :\text{Lors d'une opération élément-par-élément (par ex. } C = A + B\text{ ), } \text{les deux tenseurs sont \emph{broadcastés} pour obtenir :} A′=[111122223333],B′=[102030401020304010203040].A' = \begin{bmatrix} 1 & 1 & 1 & 1 \\[2mm] 2 & 2 & 2 & 2 \\[2mm] 3 & 3 & 3 & 3 \end{bmatrix}, \qquad B' = \begin{bmatrix} 10 & 20 & 30 & 40 \\[2mm] 10 & 20 & 30 & 40 \\[2mm] 10 & 20 & 30 & 40 \end{bmatrix}. Ainsi, C=A+B=[112131411222324213233343].\text{Ainsi, } C = A + B = \begin{bmatrix} 11 & 21 & 31 & 41 \\[2mm] 12 & 22 & 32 & 42 \\[2mm] 13 & 23 & 33 & 43 \end{bmatrix}.

Vous pourrez trouver le code pour broadcaster dans la section suivante, si cela vous aide à mieux comprendre. On supposera maintenant que pour chaque opération (multiplication, addition, etc etc...) On broadcastera les tenseurs afin que leur shapes correspondent si c'est possible).

Produit scalaire​

Soient A,B∈T(N)×T(M), t.q dA(N−1)=dB(M−1)\text{Soient } A, B \in \mathcal{T}(N) \times \mathcal{T}(M), \text{ t.q } \mathcal{d}_A(N-1) = \mathcal{d}_B(M-1)  On deˊfinit leur produit scalaire par : \text{ On définit leur produit scalaire par : } ⟨A,B⟩=Tr⁡(A⊤B)=azjibzij\langle A, B \rangle = \operatorname{Tr}(A^{\top} B) = a_{zji}b_{zij}

Si vous avez toujours du mal avec cette notation, malgré le post de "Robot Chinwag", je vous conseille de regarder d'autres resources sur la notation d'Einstein et même sur einsum (fonction PyTorch). (En gros ici, on somme sur les indices zz)