diff --git a/.config/custom-dict-words-en.txt b/.config/custom-dict-words-en.txt index 7da622f..3a200e9 100644 --- a/.config/custom-dict-words-en.txt +++ b/.config/custom-dict-words-en.txt @@ -1,4 +1,5 @@ anticommutativity explainability +invertibility regulariser sidelining diff --git a/.config/custom-dict-words-es.txt b/.config/custom-dict-words-es.txt index c968576..c8933d1 100644 --- a/.config/custom-dict-words-es.txt +++ b/.config/custom-dict-words-es.txt @@ -4,6 +4,7 @@ autocompletado bayesianos contrastivo convolucionales +covarianza curvá dejá descripto @@ -14,15 +15,20 @@ explicabilidad extensibilidad geométricamente icónico +imaginate +indexación inicializador interpretabilidad +invertibilidad iteradores mapeos mensurablemente modularidad multinivel +notá ocultamiento operandos +pensalo pensás podés recordá @@ -30,6 +36,7 @@ recursión recursivamente redirecciona renormalizando +retropropagación reusabilidad rotarla semánticamente diff --git a/content/ai/math/algebra/matrices/images/cofactor-sign-pattern.svg b/content/ai/math/algebra/matrices/images/cofactor-sign-pattern.svg new file mode 100644 index 0000000..af9c24a --- /dev/null +++ b/content/ai/math/algebra/matrices/images/cofactor-sign-pattern.svg @@ -0,0 +1,30 @@ + + + + i=1 + i=2 + i=3 + + j=1 + j=2 + j=3 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/ai/math/algebra/matrices/images/invertible.en.svg b/content/ai/math/algebra/matrices/images/invertible.en.svg new file mode 100644 index 0000000..c5124f9 --- /dev/null +++ b/content/ai/math/algebra/matrices/images/invertible.en.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + O + + + + + + + + a₁ = [2.5, 1] + a₂ = [1.25, 0.5] + a₂ = ½ · a₁ → parallel! + 2D plane collapses to a 1D line + + + + det(A) = ad − bc + = (2.5)(0.5) − (1.25)(1) + = 1.25 − 1.25 + = 0 → no inverse + + Parallel columns → zero area → + information lost → not reversible. + diff --git a/content/ai/math/algebra/matrices/images/invertible.es.svg b/content/ai/math/algebra/matrices/images/invertible.es.svg new file mode 100644 index 0000000..5e1ccee --- /dev/null +++ b/content/ai/math/algebra/matrices/images/invertible.es.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + O + + + + + + + a₁ = [2.5, 1] + a₂ = [1.25, 0.5] + a₂ = ½ · a₁ → ¡paralelos! + el plano 2D colapsa a una recta 1D + + + + det(A) = ad − bc + = (2.5)(0.5) − (1.25)(1) + = 1.25 − 1.25 + = 0 → sin inversa + + Columnas paralelas → área cero → + información perdida → no reversible. + diff --git a/content/ai/math/algebra/matrices/images/orientation.en.svg b/content/ai/math/algebra/matrices/images/orientation.en.svg new file mode 100644 index 0000000..e7a276b --- /dev/null +++ b/content/ai/math/algebra/matrices/images/orientation.en.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + det > 0 (anticlockwise) + det < 0 (clockwise) + + + + + + + + + + + + + + + ① a₁ + ② a₂ + area = +3.5 + a₁ then a₂: left turn → positive + + + + + + + + + + + ① a₁ + ② a₂ + area = −3.5 + a₁ then a₂: right turn → negative + diff --git a/content/ai/math/algebra/matrices/images/orientation.es.svg b/content/ai/math/algebra/matrices/images/orientation.es.svg new file mode 100644 index 0000000..47249cd --- /dev/null +++ b/content/ai/math/algebra/matrices/images/orientation.es.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + det > 0 (antihorario) + det < 0 (horario) + + + + + + + + + + + + + + ① a₁ + ② a₂ + área = +3.5 + a₁ luego a₂: giro izq. → positivo + + + + + + + + + + ① a₁ + ② a₂ + área = −3.5 + a₁ luego a₂: giro der. → negativo + diff --git a/content/ai/math/algebra/matrices/images/parallelogram-area.en.svg b/content/ai/math/algebra/matrices/images/parallelogram-area.en.svg new file mode 100644 index 0000000..629c5ff --- /dev/null +++ b/content/ai/math/algebra/matrices/images/parallelogram-area.en.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + O + A(a,c) + B(b,d) + C + + + + ½ac + + bc + + ½bd + + ½bd + + bc + + ½ac + + S + =ad−bc + + + + + + + a + b + + + + + c + d + + + + + + S = bbox − 6 outside pieces + S = (a+b)(c+d) − ac − bd − 2bc + = ac+ad+bc+bd − ac − bd − 2bc + = ad − bc ✓ + + + 6 outside pieces: + + + + ½ac ×2 = ac + + + + bc ×2 = 2bc + + + + ½bd ×2 = bd + + + total outside = ac + 2bc + bd + ∴ S = (a+b)(c+d) − (ac + 2bc + bd) + = ad − bc + diff --git a/content/ai/math/algebra/matrices/images/parallelogram-area.es.svg b/content/ai/math/algebra/matrices/images/parallelogram-area.es.svg new file mode 100644 index 0000000..d68a480 --- /dev/null +++ b/content/ai/math/algebra/matrices/images/parallelogram-area.es.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + O + A(a,c) + B(b,d) + C + + + + ½ac + + bc + + ½bd + + ½bd + + bc + + ½ac + + S + =ad−bc + + + + + + + a + b + + + + + c + d + + + + + + S = bbox − 6 piezas externas + S = (a+b)(c+d) − ac − bd − 2bc + = ac+ad+bc+bd − ac − bd − 2bc + = ad − bc ✓ + + + 6 piezas externas: + + + + ½ac ×2 = ac + + + + bc ×2 = 2bc + + + + ½bd ×2 = bd + + + total externo = ac + 2bc + bd + ∴ S = (a+b)(c+d) − (ac + 2bc + bd) + = ad − bc + diff --git a/content/ai/math/algebra/matrices/images/volume-scale.en.svg b/content/ai/math/algebra/matrices/images/volume-scale.en.svg new file mode 100644 index 0000000..1a3f6a2 --- /dev/null +++ b/content/ai/math/algebra/matrices/images/volume-scale.en.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + x + y + O + + 1 + 2 + 3 + 1 + 2 + 3 + + + area=1 + + + + + + + + + area = 3.5 + + + a₁+a₂ + + a₁ = [2, 1] + a₂ = [0.5, 2] + + + + Columns of A become vectors + + + + + + + + + 2 + 1 + 0.5 + 2 + + a₁ + a₂ + + + + det(A) = ad − bc + = (2)(2) − (0.5)(1) + = 3.5 ✓ + diff --git a/content/ai/math/algebra/matrices/images/volume-scale.es.svg b/content/ai/math/algebra/matrices/images/volume-scale.es.svg new file mode 100644 index 0000000..ee9c18a --- /dev/null +++ b/content/ai/math/algebra/matrices/images/volume-scale.es.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + x + y + O + + 1 + 2 + 3 + 1 + 2 + 3 + + + área=1 + + + + + + + + + área = 3.5 + + + a₁+a₂ + + a₁ = [2, 1] + a₂ = [0.5, 2] + + + + Las columnas de A se convierten en vectores + + + + + + + + + 2 + 1 + 0.5 + 2 + a₁ + a₂ + + + det(A) = ad − bc + = (2)(2) − (0.5)(1) + = 3.5 ✓ + diff --git a/content/ai/math/algebra/matrices/index.en.md b/content/ai/math/algebra/matrices/index.en.md new file mode 100644 index 0000000..e16714a --- /dev/null +++ b/content/ai/math/algebra/matrices/index.en.md @@ -0,0 +1,651 @@ +--- +weight: 2 +title: "Matrices: operations and properties" +authors: + - jnonino +description: > + Master matrix arithmetic, linear transformations, determinants, rank, and inverses from scratch. Step-by-step math derivations, runnable Python code, and research-grade insights for aspiring Machine Learning (ML) scientists. +date: 2026-03-13 +tags: ["AI", "Maths", "Algebra", "Linear Algebra", "Matrices"] +--- + +GPT-3 stores its *"intelligence"* in approximately 1800 weight matrices. Every token you type triggers a cascade of multiplications across those matrices (projections, attention scores, feed-forward expansions) before a single output probability is produced. The entire 175-billion-parameter model is, at its computational core, an intricate composition of matrix operations applied in sequence. + +Matrices are where the abstract idea of a vector space becomes an engine you can actually run. A vector tells you where something is; a matrix tells you how to move it. Weight matrices in neural networks encode learned transformations of feature space. Covariance matrices in statistics encode the shape of a data distribution. The Jacobian matrix of a function encodes how its outputs change with respect to its inputs, it is the object that makes *backpropagation* possible. + +The trouble is that most introductions to matrices treat them as glorified spreadsheets: grids of numbers with arithmetic rules bolted on. That framing makes the operations feel arbitrary. This article takes the opposite approach: we start from the geometry, derive every operation from first principles, and by the end you will see matrices not as tables but as **functions**, with all the richness that implies: composition, invertibility, image, kernel, and rank. + +By the end of this article, you will be able to: + +- Formally define a matrix and a linear transformation, and explain why the axioms matter. +- Execute and derive all fundamental matrix operations: addition, multiplication, transpose, trace, and inversion. +- Compute the determinant geometrically and algebraically, and understand what a zero determinant means. +- Reason about column space, row space, null space, and rank. And state and apply the Rank-Nullity Theorem. +- Implement these operations from scratch in pure Python and NumPy. +- Connect these operations to contemporary research in deep learning. + +Let's start. + +## Prerequisites + +Before reading this article, you should be comfortable with: + +- **Vectors and vector spaces**: formal definitions, dot products, norms, span, and linear combinations. +- **Basic Python and NumPy**: array creation, indexing, shape manipulation. +- **Function notation**: understanding \(f: \mathbb{R}^m \rightarrow \mathbb{R}^n\) style notation. + +If you can define what it means for a set to be *closed* under an operation, you have enough scaffolding. + +## Intuition first + +### The programmer's analogy: matrices as functions + +As a developer, you have used functions your whole career. A function `transform(x)` takes an input and maps it to an output. A matrix \(\mathbf{A}\) is exactly that, a **function** that takes a vector as input and produces a vector as output. The key constraint is that this function must be *linear*, which imposes a specific geometric structure on what transformations are permitted. + +Think of it this way. Imagine a data pipeline where user feature vectors pass through processing stages: + +```python +# Stage 1: expand 3 raw features into 5 derived features +stage1 = transform_3_to_5(user_features) # shape: (5,) + +# Stage 2: compress 5 derived features into 2 latent dimensions +stage2 = transform_5_to_2(stage1) # shape: (2,) + +# Combined: can we do both in one step? +combined = transform_3_to_2(user_features) # Yes — matrix multiplication +``` + +This is exactly what matrix multiplication computes: the **composition** of two linear transformations into one. A \(5 \times 3\) matrix (stage 1) composed with a \(2 \times 5\) matrix (stage 2) produces a single \(2 \times 3\) matrix that does both steps at once. Every layer of a neural network is one stage of this pipeline. + +### Geometric picture: matrices as space transformations + +Picture a 2D coordinate system. The [standard basis](https://en.wikipedia.org/wiki/Standard_basis) vectors are: + +$$ +\hat{e}_1 = [1,0] \qquad \text{(points right along x-axis)} +$$ + +$$ +\hat{e}_2 = [0,1] \qquad \text{(points up along y-axis)} +$$ + +Apply the matrix \(\mathbf{A} = \begin{bmatrix} 2 & 0 \\ 0 & 3 \end{bmatrix}\). After the transformation: \(\hat{e}_1\) maps to \([2,0]\) (stretched right by factor 2) and \(\hat{e}_2\) maps to \([0,3]\) (stretched up by factor 3). The unit square (with area 1), becomes a \(2 \times 3\) rectangle with area 6. The **determinant** of \(\mathbf{A}\), which we will derive shortly, equals exactly 6. This is not a coincidence: the determinant *is* the volume scaling factor. + +Compare this to a rotation matrix: + +$$ +\mathbf{R}(\theta) = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix} +$$ + +This rotates every vector by angle $\theta$ without stretching, so it preserves all areas — and its determinant is always $1$. + +The columns of any matrix tell you exactly where the basis vectors land. Since every vector is a linear combination of the basis vectors, knowing where basis vectors go tells you where *every* vector in the space goes. This insight explains why matrix multiplication is non-commutative (applying transformation A then B is geometrically different from B then A), and why the columns of weight matrices in neural networks carry semantic meaning that researchers actively analyse. + +{{< callout type="important" >}} +The columns of a matrix are not just numbers, they are the *images of the basis vectors* under the transformation. When you look at the weight matrix \(\mathbf{W}\) of a trained neural network layer, each column tells you how that layer responds to one standard input direction. This is the foundation of feature visualization research, where practitioners interpret what each neuron *"detects*" by examining the directions in weight matrices. +{{< /callout >}} + +## Mathematical derivation + +### Formal definition + +An **\(m \times n\) matrix** over \(\mathbb{R}\) is a rectangular array of real numbers arranged in \(m\) rows and \(n\) columns: + +$$ +\mathbf{A} = \begin{bmatrix} 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{bmatrix} \in \mathbb{R}^{m \times n} +$$ + +The entry \(A_{ij}\) denotes the element in **row \(i\), column \(j\)**. We write the set of all \(m \times n\) real matrices as \(\mathbb{R}^{m \times n}\). + +{{< callout type="info" >}} +In plain English: a matrix is a 2D table of numbers. The notation \(\mathbb{R}^{m \times n}\) is the *"type"* of the matrix (how many rows and columns it has). This is exactly the type signature you would attach to a 2D array in a statically typed language: `Array[Float, m, n]`. +{{< /callout >}} + +**Special cases** you will encounter constantly: + +- **Column vector**: a matrix of shape \(n \times 1\), this is just a vector \(mathbf{v} \in \mathbb{R}^n\). +- **Row vector**: a matrix of shape \(1 \times n\). +- **Square matrix**: a matrix where \(m = n\). +- **Identity matrix** \(\mathbf{I}_n\): the \(n \times n\) matrix with \(I_{ij} = 1\) if \(i = j\), else \(0\). +- **Zero matrix** \(\mathbf{0}\): all entries are zero. +- **Diagonal matrix**: a square matrix where \(A_{ij} = 0\) for all \(i \neq j\). + +### Matrices as linear transformations + +The most important property of a matrix is that it defines a **linear transformation** \(T: \mathbb{R}^n \rightarrow \mathbb{R}^m\) via \(T(\mathbf{x}) = \mathbf{A}\mathbf{x}\). + +A function \(T\) is called **linear** if and only if it satisfies two axioms for all vectors \(\mathbf{u}, \mathbf{v} \in \mathbb{R}^n\) and all scalars \(\alpha \in \mathbb{R}\): + +- *Additivity*: \(T(\mathbf{u} + \mathbf{v}) = T(\mathbf{u}) + T(\mathbf{v})\) +- *Homogeneity*: \(T(\alpha \mathbf{u}) = \alpha T(\mathbf{u})\) + +These two axioms are equivalent to the single condition: + +$$ +T(\alpha \mathbf{u} + \beta \mathbf{v}) = \alpha T(\mathbf{u}) + \beta T(\mathbf{v}) +$$ + +{{< callout type="info" >}} +In plain English: a linear transformation preserves the structure of the vector space, it doesn't matter whether you add two vectors first and then transform, or transform each separately and add. This is why stacking multiple linear (un-activated) layers in a neural network collapses to a single matrix product: \(\mathbf{W}_2(\mathbf{W}_1\mathbf{x}) = (\mathbf{W}_2\mathbf{W}_1)\mathbf{x}\). +{{< /callout >}} + +A foundational theorem from linear algebra states that **every** linear transformation between finite-dimensional spaces can be represented as a matrix, and conversely every matrix defines a linear transformation. The matrix and the linear transformation are, for our purposes, the same object. + +### Matrix addition and scalar multiplication + +The set \(\mathbb{R}^{m \times n}\) of all \(m \times n\) real matrices forms a **vector space** under the following operations. + +**Matrix addition**: Given \(\mathbf{A}, \mathbf{B} \in \mathbb{R}^{m \times n}\): + +$$ +(\mathbf{A} + \mathbf{B})_{ij} = A_{ij} + B_{ij} +$$ + +This satisfies: +- *Commutativity*: \(\mathbf{A} + \mathbf{B} = \mathbf{B} + \mathbf{A}\) +- *Associativity*: \((\mathbf{A} + \mathbf{B}) + \mathbf{C} = \mathbf{A} + (\mathbf{B} + \mathbf{C})\) +- *Identity element*: there exists a zero matrix \(\mathbf{0}\) such that \(\mathbf{A} + \mathbf{0} = \mathbf{A}\) +- *Inverse element*: for each \(\mathbf{A}\), there exists \(-\mathbf{A}\) such that \(\mathbf{A} + (-\mathbf{A}) = \mathbf{0}\) + +**Scalar multiplication**: Given \(\alpha \in \mathbb{R}\) and \(\mathbf{A} \in \mathbb{R}^{m \times n}\): + +$$(\alpha \mathbf{A})_{ij} = \alpha \cdot A_{ij}$$ + +This satisfies: +- *Associativity*: \(\alpha(\beta \mathbf{A}) = (\alpha\beta)\mathbf{A}\) +- *Identity element*: \(1 \cdot \mathbf{A} = \mathbf{A}\) +- *Distributivity over matrix addition*: \(\alpha(\mathbf{A} + \mathbf{B}) = \alpha\mathbf{A} + \alpha\mathbf{B}\) +- *Distributivity over scalar addition*: \((\alpha + \beta)\mathbf{A} = \alpha\mathbf{A} + \beta\mathbf{A}\) + +{{< callout >}} +If these axioms look familiar, they should. They are exactly the vector space axioms from our previous lesson about vectors. Matrices *"are"* vectors in a higher-dimensional space. A \(3 \times 4\) matrix is just a vector with \(12\) components arranged in a grid. This means every theorem we prove about vector spaces applies to matrices too. +{{< /callout >}} + +### Matrix multiplication + +Given \(\mathbf{A} \in \mathbb{R}^{m \times k}\) and \(\mathbf{B} \in \mathbb{R}^{k \times n}\), their product \(\mathbf{C} = \mathbf{A}\mathbf{B} \in \mathbb{R}^{m \times n}\) is defined as: + +$$\boxed{C_{ij} = \sum_{l=1}^{k} A_{il} \cdot B_{lj}}$$ + +To compute entry \(C_{ij}\), the element in row \(i\), column \(j\) of the result, take the **dot product of row \(i\) of \(\mathbf{A}\) with column \(j\) of \(\mathbf{B}\)**. The inner dimensions must match: + +$$ +\underbrace{\mathbf{A}}_{m \times k} \cdot \underbrace{\mathbf{B}}_{k \times n} = \underbrace{\mathbf{C}}_{m \times n} +$$ + +{{< callout type="info" >}} +In plain English: matrix multiplication is function composition. Applying transformation \(\mathbf{B}\) first, then \(\mathbf{A}\), gives the same result as the single composed transformation \(\mathbf{AB}\). The inner dimensions must agree because the output dimension of the first transformation must equal the input dimension of the second, exactly like composing functions. +{{< /callout >}} + +Matrix multiplication satisfies: +- *Associativity*: \((\mathbf{AB})\mathbf{C} = \mathbf{A}(\mathbf{BC})\) +- *Left distributivity*: \(\mathbf{A}(\mathbf{B} + \mathbf{C}) = \mathbf{AB} + \mathbf{AC}\) +- *Right distributivity*: \((\mathbf{A} + \mathbf{B})\mathbf{C} = \mathbf{AC} + \mathbf{BC}\) +- *Identity*: \(\mathbf{A}\mathbf{I} = \mathbf{I}\mathbf{A} = \mathbf{A}\) (for compatible \(\mathbf{I}\)) +- **Non-commutativity**: \(\mathbf{AB} \neq \mathbf{BA}\) in general + +{{< callout >}} +The non-commutativity is not a flaw but a fundamental feature of transformations. Rotating a figure then reflecting it is geometrically different from reflecting then rotating. +{{< /callout >}} + +### The transpose + +The **transpose** of \(\mathbf{A} \in \mathbb{R}^{m \times n}\) is the matrix \(\mathbf{A}^\top \in \mathbb{R}^{n \times m}\) defined by: + +$$ +\boxed{(\mathbf{A}^\top)_{ij} = A_{ji}} +$$ + +{{< callout type="info" >}} +In plain English: flip the matrix along its main diagonal, rows become columns and columns become rows. A \(3 \times 5\) matrix becomes a \(5 \times 3\) matrix. Geometrically, the transpose corresponds to the *adjoint* of the transformation, the transformation that "undoes the rotation part" while keeping the scaling. +{{< /callout >}} + +The transpose satisfies the following properties: + +- *Double transpose*: \((\mathbf{A}^\top)^\top = \mathbf{A}\) +- *Linearity*: \((\mathbf{A} + \mathbf{B})^\top = \mathbf{A}^\top + \mathbf{B}^\top\) and \((\alpha\mathbf{A})^\top = \alpha\mathbf{A}^\top\) +- *Product reversal*: \((\mathbf{AB})^\top = \mathbf{B}^\top \mathbf{A}^\top\) + +The product reversal property is **critical** and appears in every backpropagation derivation. Let us prove it completely. We want to show \([(\mathbf{AB})^\top]_{ij} = [\mathbf{B}^\top \mathbf{A}^\top]_{ij}\). + +Starting from the definition of transpose: + +$$ +[(\mathbf{AB})^\top]_{ij} = [\mathbf{AB}]_{ji} +$$ + +Applying the definition of matrix multiplication to \([\mathbf{AB}]_{ji}\): + +$$ +[\mathbf{AB}]_{ji} = \sum_{l} A_{jl} \cdot B_{li} +$$ + +Recognising each factor using the definition of transpose (\(A_{jl} = [\mathbf{A}^\top]_{lj}\) and \(B_{li} = [\mathbf{B}^\top]_{il}\)): + +$$\sum_{l} A_{jl} B_{li} = \sum_{l} [\mathbf{B}^\top]_{il} \cdot [\mathbf{A}^\top]_{lj}$$ + +Recognising the right-hand side as the definition of matrix multiplication \( [\mathbf{B}^\top \mathbf{A}^\top]_{ij} \): + +$$ +\boxed{(\mathbf{AB})^\top = \mathbf{B}^\top \mathbf{A}^\top} +$$ + +**Symmetric and skew-symmetric matrices** are important special cases: + +- \(\mathbf{A}\) is **symmetric** if \(\mathbf{A}^\top = \mathbf{A}\), equivalently \(A_{ij} = A_{ji}\) for all \(i, j\). Covariance matrices and kernel matrices in ML are always symmetric. +- \(\mathbf{A}\) is **skew-symmetric** if \(\mathbf{A}^\top = -\mathbf{A}\), equivalently \(A_{ij} = -A_{ji}\) and all diagonal entries are zero. + +{{< callout >}} +Any square matrix \(\mathbf{A}\) can be uniquely decomposed into a symmetric part and a skew-symmetric part: + +$$ +\mathbf{A} = \underbrace{\frac{\mathbf{A} + \mathbf{A}^\top}{2}}_{\text{symmetric}} + \underbrace{\frac{\mathbf{A} - \mathbf{A}^\top}{2}}_{\text{skew-symmetric}} +$$ + +This decomposition has applications in physics (strain vs. rotation analysis) and in recent research on attention mechanism structure. +{{< /callout >}} + +### The trace + +For a square matrix \(\mathbf{A} \in \mathbb{R}^{n \times n}\), the **trace** is the sum of its diagonal entries: + +$$ +\text{tr}(\mathbf{A}) = \sum_{i=1}^{n} A_{ii} +$$ + +{{< callout type="info" >}} +In plain English: add up the main diagonal. The trace captures how much the transformation *"expands"* space on average. +{{< /callout >}} + +Key properties: +- *Linearity*: \(\text{tr}(\mathbf{A} + \mathbf{B}) = \text{tr}(\mathbf{A}) + \text{tr}(\mathbf{B})\) and \(\text{tr}(\alpha\mathbf{A}) = \alpha\,\text{tr}(\mathbf{A})\) +- *Transpose invariance*: \(\text{tr}(\mathbf{A}^\top) = \text{tr}(\mathbf{A})\) +- **Cyclic property**: \(\text{tr}(\mathbf{ABC}) = \text{tr}(\mathbf{BCA}) = \text{tr}(\mathbf{CAB})\) + +The cyclic property is everywhere in gradient derivations. Let us prove the base case \(\text{tr}(\mathbf{AB}) = \text{tr}(\mathbf{BA})\). + +Starting from the definition of trace: + +$$\text{tr}(\mathbf{AB}) = \sum_{i} [\mathbf{AB}]_{ii} = \sum_{i} \sum_{j} A_{ij} B_{ji}$$ + +Swapping the order of summation (valid since both sums are finite): + +$$\sum_{i} \sum_{j} A_{ij} B_{ji} = \sum_{j} \sum_{i} B_{ji} A_{ij}$$ + +Recognising the right-hand side as the diagonal entry \([\mathbf{BA}]_{jj}\): + +$$ +\sum_{j} \sum_{i} B_{ji} A_{ij} = \sum_{j} [\mathbf{BA}]_{jj} = \text{tr}(\mathbf{BA}) +$$ + +$$ +\boxed{\text{tr}(\mathbf{AB}) = \text{tr}(\mathbf{BA})} +$$ + +{{< callout >}} +Note that this holds even when \(\mathbf{AB}\) and \(\mathbf{BA}\) have different shapes (e.g., \(\mathbf{A} \in \mathbb{R}^{m \times n}\), \(\mathbf{B} \in \mathbb{R}^{n \times m}\)), both traces are scalar and equal. +{{< /callout >}} + +### The determinant + +Before computing a single formula, it is worth asking: why does the determinant exist? What problem does it solve? + +When a matrix encodes a linear transformation, the most fundamental question you can ask about it is: **does it destroy information?** A transformation that squashes a 2D plane into a 1D line has lost all information in the collapsed dimension, it cannot be undone. A transformation that rotates or stretches the plane preserves all information and can be reversed. The determinant is the single number that answers this question, and by how much. + +More precisely, the determinant answers three interconnected questions simultaneously. + +{{< details title="How does the transformation scale volumes?" closed="true" >}} +In two dimensions, the two columns of a matrix are simply two vectors drawn from the origin. Two vectors from the same origin always enclose a parallelogram — that is not a choice, it is a geometric inevitability. The determinant is the *signed area* of that parallelogram. If \(|\det(\mathbf{A})| = 6\), every region in the plane has its area multiplied by 6 after the transformation. In 3D, it becomes the signed volume of the parallelepiped formed by the three column vectors. + +{{< figure + src="images/volume-scale.en.svg" + alt="Escala de volúmenes por el determinante" + caption="The two columns of a \(2\times2\) matrix are vectors that always form a parallelogram. The determinant is its signed area." + >}} +{{< /details >}} + +{{< details title="Does the transformation preserve or reverse orientation?" closed="true" >}} +The word *signed* matters. Two vectors always form a parallelogram, but the *order* in which you traverse them determines the sign of the area. If the rotation from \(\mathbf{a}_1\) to \(\mathbf{a}_2\) is **anticlockwise**, the determinant is positive. If it is **clockwise**, the determinant is negative. The geometric content is identical (same shape, same area) but the sign encodes whether the transformation preserves or flips the handedness of space. + +{{< figure + src="images/orientation.en.svg" + alt="Preservation or inversion of orientation by the determinant" + caption="The order of the columns determines the sign of the determinant: positive if the rotation from the first column to the second is anticlockwise, negative if clockwise." + >}} +{{< /details >}} + +{{< details title="Is the transformation invertible?" closed="true" >}} +\(\det(\mathbf{A}) = 0\) means the two column vectors are parallel, they lie on the same line, spanning zero area. The transformation collapses a 2D plane into a 1D line. Information is irreversibly lost: infinitely many different input vectors produce the same output, so you cannot determine which input you came from. The matrix is **singular** and has no inverse. + +{{< figure + src="images/invertible.en.svg" + alt="Invertibility of the transformation" + caption="A matrix is invertible if and only if its determinant is non-zero." + >}} +{{< /details >}} + +{{< callout type="important" >}} +In ML, checking near-zero determinants is not a mathematical formality, it is a practical debugging step. Covariance matrices that are nearly singular cause numerical instability in [Gaussian processes](https://en.wikipedia.org/wiki/Gaussian_process), linear regression normal equations, and dimensionality reduction. When a model produces `NaN` outputs or wildly large predictions after a matrix inversion, a near-zero determinant is usually the culprit. +{{< /callout >}} + +#### Key properties + +- **Multiplicativity**: \(\det(\mathbf{AB}) = \det(\mathbf{A})\det(\mathbf{B})\), applying a transformation that doubles volume followed by one that triples it produces a six-fold overall expansion. +- **Transpose invariance**: \(\det(\mathbf{A}^\top) = \det(\mathbf{A})\), rows and columns contribute symmetrically to volume. +- **Row scaling**: scaling one row by \(\alpha\) also scales the determinant by \(\alpha\), you are scaling one dimension of the parallelepiped. +- **Row swap**: swapping two rows negates the determinant, you are flipping the orientation. +- **Row addition**: adding a multiple of one row to another leaves the determinant unchanged. This is why Gaussian elimination works: it never changes the determinant. +- **Triangular matrices**: \(\det(\mathbf{A}) = \prod_{i} A_{ii}\), only the diagonal entries matter. +- **Invertibility**: \(\mathbf{A}\) is invertible if and only if \(\det(\mathbf{A}) \neq 0\). + +#### The 2x2 case, derivation from geometry + +Let \(\mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}\). The two column vectors are \(\mathbf{a}_1 = \begin{bmatrix}a \\ c\end{bmatrix}\) and \(\mathbf{a}_2 = \begin{bmatrix}b \\ d\end{bmatrix}\). + +The determinant is the signed area of the parallelogram they span which has four vertices: \(O = (0,0)\), \(A = (a,c)\), \(B = (b,d)\), and \(C = (a+b,\, c+d)\). + +$$ +\boxed{\det\begin{bmatrix} a & b \\ c & d \end{bmatrix} = ad - bc} +$$ + +We derive this in two complementary ways: first geometrically via bounding-box subtraction, then algebraically via the *Shoelace* formula. + +{{< details title="Bounding-box subtraction" closed="true" >}} +Enclose the parallelogram in the smallest axis-aligned rectangle that contains it: a box of width \(a+b\) and height \(c+d\). The area of this bounding rectangle is \((a+b)(c+d)\). + +The region between the rectangle and the parallelogram consists of exactly six pieces: + +- **Two rectangles** with sides \(b\) and \(c\) each (top-left and bottom-right corners). +- **Two triangles** with legs \(a\) and \(c\) each (top and bottom triangles). +- **Two triangles** with legs \(b\) and \(d\) each (left and right triangles). + +{{< figure + src="images/parallelogram-area.en.svg" + alt="Area of the parallelogram" + caption="The area of the parallelogram is the difference between the bounding rectangle and the area of the triangles." + >}} + +Subtracting all of this from the bounding rectangle we'll get the area of the parallelogram: + +$$ +\begin{aligned} + S &= (a+b)(c+d) - 2(bc) - 2\left(\frac{1}{2}ac\right) - 2\left(\frac{1}{2}bd\right) \\ + S &= ac + ad + bc + bd - 2(bc) - 2\left(\frac{1}{2}ac\right) - 2\left(\frac{1}{2}bd\right) \\ + S &= ac + ad + bc + bd - 2(bc) - ac - bd \\ + S &= ad - bc +\end{aligned} +$$ +{{< /details >}} + +{{< details title="Shoelace formula" closed="true" >}} +The **Shoelace formula** gives the signed area of any polygon whose vertices are listed in order. For a polygon with \(n\) vertices \((x_1, y_1), \ldots, (x_n, y_n)\), traversed anticlockwise: + +$$ +\text{área con signo} = \frac{1}{2}\sum_{i=1}^{n}\bigl(x_i y_{i+1} - x_{i+1} y_{i}\bigr) +$$ + +where indices are cyclical, so \(x_{n+1} = x_1\), \(y_{n+1} = y_1\), etc. and \(n\) is the number of vertices. + +The intuition behind each term \(x_i y_{i+1} - x_{i+1} y_i\) is that it measures the signed area of the triangle formed by the origin, vertex \(i\), and vertex \(i+1\). Summing these triangles around the polygon gives the total signed area, positive for anticlockwise traversal, negative for clockwise. + +Apply this to the parallelogram with vertices in anticlockwise order: + +$$ +O = (0,0), \quad A = (a,c), \quad B = (b,d), \quad C = (a+b,\, c+d) +$$ + +Expanding the sum term by term: + +**Term 1** (\(O \to A\)) +$$ +\begin{aligned} + x_{\mathbf{O}}\, y_A - x_A\, y_{\mathbf{O}} &= 0 \cdot c - a \cdot 0 \\ + x_{\mathbf{O}}\, y_A - x_A\, y_{\mathbf{O}} &= 0 +\end{aligned} +$$ + +**Term 2** (\(A \to C\)) +$$ +\begin{aligned} + x_A\, y_C - x_C\, y_A &= a(c+d) - (a+b)c \\ + x_A\, y_C - x_C\, y_A &= ac + ad - ac - bc \\ + x_A\, y_C - x_C\, y_A &= ad - bc +\end{aligned} +$$ + +**Term 3** (\(C \to B\)) +$$ +\begin{aligned} + x_C\, y_B - x_B\, y_C &= (a+b)d - b(c+d) \\ + x_C\, y_B - x_B\, y_C &= ad + bd - bc - bd \\ + x_C\, y_B - x_B\, y_C &= ad - bc +\end{aligned} +$$ + +**Term 4** (\(B \to O\)) +$$ +\begin{aligned} + x_B\, y_O - x_O\, y_B &= b \cdot 0 - 0 \cdot d \\ + x_B\, y_O - x_O\, y_B &= 0 +\end{aligned} +$$ + +Summing and applying the \(\tfrac{1}{2}\) factor: +$$ +\begin{aligned} + \text{signed area} &= \frac{1}{2}\bigl[0 + (ad - bc) + (ad - bc) + 0\bigr] \\ + \text{signed area} &= \frac{1}{2} \cdot 2(ad-bc) \\ + \text{signed area} &= ad - bc +\end{aligned} +$$ + +This derivation makes no assumption about the signs of \(a, b, c, d\), it holds for any real entries. The result is positive when the traversal \(\mathbf{O} \to A \to C \to B\) is anticlockwise (i.e., when \(ad > bc\)), and negative when it is clockwise. This is precisely the sign that encodes orientation. +{{< /details >}} + +#### The 3x3 case, cofactor expansion + +In 3D, the determinant measures the signed volume of the parallelepiped formed by the three column vectors. The computation expands along the first row, each term contributing a projected area weighted by the corresponding entry. Given the matrix \(\mathbf{A} \in \mathbb{R}^{3 \times 3}\): + +$$ +\mathbf{A} = \begin{bmatrix} A_{11} & A_{12} & A_{13} \\ A_{21} & A_{22} & A_{23} \\ A_{31} & A_{32} & A_{33} \end{bmatrix} +$$ + +$$ +\det(\mathbf{A}) = A_{11}\det\begin{bmatrix}A_{22}&A_{23}\\A_{32}&A_{33}\end{bmatrix} - A_{12}\det\begin{bmatrix}A_{21}&A_{23}\\A_{31}&A_{33}\end{bmatrix} + A_{13}\det\begin{bmatrix}A_{21}&A_{22}\\A_{31}&A_{32}\end{bmatrix} +$$ + +{{< details title="The matrix minors" closed="true" >}} +Each \(2 \times 2\) matrix is a **minor** \(M_{1j}\): the submatrix obtained by deleting row 1 and column \(j\). The signed minor \(C_{ij} = (-1)^{i+j} M_{ij}\) is the **cofactor**. The alternating signs follow the checkerboard pattern shown below, which ensures the contributions add up to the correct signed volume rather than cancelling arbitrarily. + +{{< figure + src="images/cofactor-sign-pattern.svg" + alt="Sign pattern of the cofactor" + caption="The sign pattern of the cofactor follows a checkerboard pattern." + >}} + +{{< callout type="info" >}} +Pick any row from the matrix. For each entry, cover its row and column to reveal a \(2 \times 2\) block, compute its determinant, multiply by the entry and by the sign from the checkerboard above, then sum the three results. This is recursive: a \(4 \times 4\) determinant expands into four \(3 \times 3\) determinants, and so on. +{{< /callout >}} +{{< /details >}} + +#### The Leibniz general formula + +For an \(n \times n\) matrix, the determinant sums over all ways to pick one entry from each row and each column simultaneously, i.e., over all permutations: + +$$ +\det(\mathbf{A}) = \sum_{\sigma \in S_n} \text{sgn}(\sigma) \prod_{i=1}^{n} A_{i,\sigma(i)} +$$ + +where \(S_n\) is the set of all permutations of \(\{1, \ldots, n\}\) and \(\text{sgn}(\sigma) = \pm 1\) is the parity of the permutation (\(+1\) and \(-1\) for even and odd permutations, respectively). + +{{< callout type="important" >}} +This formula has \(n!\) terms, so it is never computed directly for large matrices. LU decomposition computes the determinant in \(\mathcal{O}(n^3)\) as a by-product of factorisation. But the Leibniz formula is the right tool for proving identities. +{{< /callout >}} + +### Linear independence and column/row spaces + +Understanding a matrix means understanding the *spaces* it creates and destroys. + +A set of vectors \(\{\mathbf{v}_1, \ldots, \mathbf{v}_k\}\) is **linearly independent** if the only solution to: + +$$ +\alpha_1 \mathbf{v}_1 + \alpha_2 \mathbf{v}_2 + \cdots + \alpha_k \mathbf{v}_k = \mathbf{0} +$$ + +is \(\alpha_1 = \alpha_2 = \cdots = \alpha_k = 0\). In other words, no vector in the set can be written as a combination of the others. Linearly dependent columns are the signature of a rank-deficient matrix. + +For \(\mathbf{A} \in \mathbb{R}^{m \times n}\), three fundamental subspaces are defined: + +**Column space** (range), \(\text{col}(\mathbf{A}) \subseteq \mathbb{R}^m\) is the space generated by the columns of \(\mathbf{A}\). Equivalently, is the set of all the possible outputs of the transformation \(\mathbf{A}\). The rank of the matrix is the dimension of the column space. + +$$ +\begin{aligned} + \text{col}(\mathbf{A}) &= \{\mathbf{A}\mathbf{x} : \mathbf{x} \in \mathbb{R}^n\} \\ + \text{col}(\mathbf{A}) &= \left\{ x_1 \begin{bmatrix}a_{11} \\ a_{21} \\ \vdots \\ a_{m1}\end{bmatrix} + x_2 \begin{bmatrix}a_{12} \\ a_{22} \\ \vdots \\ a_{m2}\end{bmatrix} + \cdots + x_n \begin{bmatrix}a_{1n} \\ a_{2n} \\ \vdots \\ a_{mn}\end{bmatrix} \right\} : x_i \in \mathbb{R} +\end{aligned} +$$ + +**Row space**, \(\text{row}(\mathbf{A}) \subseteq \mathbb{R}^n\): the span of the rows of \(\mathbf{A}\). Equivalently, \(\text{row}(\mathbf{A}) = \text{col}(\mathbf{A}^\top)\). + +**Null space** (kernel), \(\text{null}(\mathbf{A}) \subseteq \mathbb{R}^n\): all input vectors that \(\mathbf{A}\) maps to zero: + +$$\text{null}(\mathbf{A}) = \{\mathbf{x} \in \mathbb{R}^n : \mathbf{A}\mathbf{x} = \mathbf{0}\}$$ + +{{< callout type="info" >}} +In plain English: the null space is the "blind spot" of the transformation. Any vector in the null space is invisible to the matrix, it produces zero output signal regardless of how large it is. In a neural network context, directions in the null space of a weight matrix receive no gradient from that layer and will never be updated by that layer's gradients alone. +{{< /callout >}} + +### Rank + +The **rank** of \(\mathbf{A}\) is the dimension of its column space — the number of linearly independent columns: + +$$ +\text{rank}(\mathbf{A}) = \dim(\text{col}(\mathbf{A})) +$$ + +A fundamental result, the **equality of row rank and column rank**, states that the dimension of the row space always equals the dimension of the column space: + +$$ +\text{rank}(\mathbf{A}) = \dim(\text{col}(\mathbf{A})) = \dim(\text{row}(\mathbf{A})) +$$ + +For an \(m \times n\) matrix: \(\text{rank}(\mathbf{A}) \leq \min(m, n)\). + +When \(\text{rank}(\mathbf{A}) = \min(m,n)\), \(\mathbf{A}\) is **full rank**. Otherwise it is **rank-deficient** and maps a nonzero subspace of inputs to zero. + +### The Rank-Nullity theorem + +This theorem elegantly connects the three fundamental subspaces. + +For any matrix \(\mathbf{A} \in \mathbb{R}^{m \times n}\): + +$$ +\boxed{\text{rank}(\mathbf{A}) + \text{nullity}(\mathbf{A}) = n} +$$ + +where \(\text{nullity}(\mathbf{A}) = \dim(\text{null}(\mathbf{A}))\). + +{{< details title="Proof sketch" closed="true" >}} +Let \(r = \text{rank}(\mathbf{A})\) and let \(\{\mathbf{v}_1, \ldots, \mathbf{v}_{n-r}\}\) be a basis for \(\text{null}(\mathbf{A})\). Extend this to a basis for all of \(\mathbb{R}^n\) by adding \(r\) vectors \(\{\mathbf{w}_1, \ldots, \mathbf{w}_r\}\) from the row space of \(\mathbf{A}\) (which is orthogonal to the null space). The images \(\{\mathbf{A}\mathbf{w}_1, \ldots, \mathbf{A}\mathbf{w}_r\}\) are linearly independent (can be shown) and span \(\text{col}(\mathbf{A})\). So \(\dim(\text{col}(\mathbf{A})) = r\). The total basis has \(r + (n - r) = n\) elements, matching \(\dim(\mathbb{R}^n) = n\). + +{{< callout type="info" >}} +In plain English: the \(n\) input dimensions split cleanly into two complementary parts. Some (\(r\) dimensions, the row space) get mapped to nonzero outputs. The rest (\(n - r\) dimensions, the null space) get mapped to zero. These two parts partition the input space completely and without overlap — which is why their dimensions must sum to exactly \(n\). +{{< /callout >}} +{{< /details >}} + +{{< callout >}} +In ML terms: if you have a weight matrix \(\mathbf{W}\) of shape \(\mathbf{W}\) with \(n > m\) (an "over-parameterized" layer), then \(\text{nullity}(\mathbf{W}) \geq n - m > 0\). There is a whole subspace of weight perturbations that produce zero change in the layer's output. This is one reason why over-parameterized models can be aggressively pruned and compressed, many weight directions literally do nothing. +{{< /callout >}} + +### The inverse + +For a **square** matrix \(\mathbf{A} \in \mathbb{R}^{n \times n}\), the **inverse** \(\mathbf{A}^{-1}\) is the unique matrix satisfying: + +$$ +\mathbf{A}\mathbf{A}^{-1} = \mathbf{A}^{-1}\mathbf{A} = \mathbf{I}_n +$$ + +The **invertible matrix theorem** states that the following conditions are all equivalent, *if any one holds, all hold, and the inverse exists*: + +- \(\text{rank}(\mathbf{A}) = n\) (full rank) +- \(\det(\mathbf{A}) \neq 0\) +- \(\text{null}(\mathbf{A}) = \{\mathbf{0}\}\) (trivial null space) +- The columns of \(\mathbf{A}\) are linearly independent +- The rows of \(\mathbf{A}\) are linearly independent +- The equation \(\mathbf{A}\mathbf{x} = \mathbf{b}\) has a unique solution for every \(\mathbf{b} \in \mathbb{R}^n\) + +{{< callout type="important" >}} +All six conditions are equivalent ways of saying the same thing, the transformation is fully reversible. If the matrix collapses any dimension, there is a nonzero null space, the determinant is zero, then you cannot undo the transformation. All roads lead to the same conclusion: invertibility is an all-or-nothing property. +{{< /callout >}} + +Properties of the inverse: +- *Double inverse*: \((\mathbf{A}^{-1})^{-1} = \mathbf{A}\) +- *Product inverse*: \((\mathbf{AB})^{-1} = \mathbf{B}^{-1}\mathbf{A}^{-1}\) (order reverses, just as with the transpose) +- *Transpose-inverse commutativity*: \((\mathbf{A}^\top)^{-1} = (\mathbf{A}^{-1})^\top\) +- *Determinant*: \(\det(\mathbf{A}^{-1}) = \frac{1}{\det(\mathbf{A})}\) + +#### Computing the inverse + +For \(2 \times 2\) matrices, e.g. \(\mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}\) with \(\det(\mathbf{A}) = ad - bc \neq 0\), the inverse has a closed-form formula: + +We seek \(\mathbf{A}^{-1} = \begin{bmatrix} p & q \\ r & s \end{bmatrix}\) such that \(\mathbf{A}\mathbf{A}^{-1} = \mathbf{I}\): + +$$ +\begin{aligned} + \begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix} p & q \\ r & s \end{bmatrix} &= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \\ + \begin{bmatrix} ap+br & aq+bs \\ cp+dr & cq+ds \end{bmatrix} &= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} +\end{aligned} +$$ + +From the first column: \(ap + br = 1\) and \(cp + dr = 0\). Solving: +$$ +\begin{aligned} + p &= \frac{d}{ad-bc} \\ + r &= \frac{-c}{ad-bc} +\end{aligned} +$$ + +From the second column: \(aq + bs = 0\) and \(cq + ds = 1\). Solving: +$$ +\begin{aligned} + q &= \frac{-b}{ad-bc} \\ + s &= \frac{a}{ad-bc} +\end{aligned} +$$ + +Therefore: +$$ +\begin{aligned} + \mathbf{A}^{-1} &= \begin{bmatrix} p & q \\ r & s \end{bmatrix} \\ + \mathbf{A}^{-1} &= \begin{bmatrix} \frac{d}{ad-bc} & \frac{-b}{ad-bc} \\ \frac{-c}{ad-bc} & \frac{a}{ad-bc} \end{bmatrix} \\ + \mathbf{A}^{-1} &= \frac{1}{ad - bc} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix} +\end{aligned} +$$ + +Knowing that \(\det(\mathbf{A}) = ad - bc\), then: + +$$ +\boxed{\mathbf{A}^{-1} = \frac{1}{\det(\mathbf{A})} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix}} +$$ + +{{< callout type="info" >}} +To invert a \(2 \times 2\) matrix, swap the diagonal entries, negate the off-diagonal entries, and divide everything by the determinant. The determinant appears in the denominator, which is exactly why a zero determinant makes the inverse undefined (division by zero). +{{< /callout >}} + +For \(n > 2\), the inverse is computed in practice via [**Gauss-Jordan elimination**](https://en.wikipedia.org/wiki/Gaussian_elimination) on the augmented matrix \([\mathbf{A}\,|\,\mathbf{I}]\). + +## Machine Learning and AI perspective + +Matrix operations are not merely computational primitives, they are the conceptual vocabulary of modern Machine Learning research, for example: + +**Low-rank structure in fine-tuning.** [Hu et al. (2021)](https://arxiv.org/abs/2106.09685), which observes that weight update matrices \(\Delta\mathbf{W}\) during fine-tuning of large language models are empirically low-rank. Rather than storing the full \(\Delta\mathbf{W} \in \mathbb{R}^{d \times d}\), LoRA decomposes it as \(\Delta\mathbf{W} = \mathbf{B}\mathbf{A}\) where \(\mathbf{B} \in \mathbb{R}^{d \times r}\), \(\mathbf{A} \in \mathbb{R}^{r \times d}\), with \(r \ll d\). This is valid precisely because a rank-\(r\) matrix has a natural factorization into two thin matrices, the rank concept we just derived. LoRA reduces trainable parameters by over 10000x on GPT-3 class models, and the entire insight rests on rank intuition. + +## Common pitfalls and debugging + +1. **Confusing shape conventions across frameworks**. NumPy uses `(batch, features)` convention. PyTorch's `nn.Linear(in_features, out_features)` stores its weight matrix as shape `(out_features, in_features)` and computes `x @ W.T + b` internally. So \(\mathbf{W}\) is stored transposed relative to the mathematical convention. If you manually initialize weights, verify with a forward pass on dummy data before trusting gradients. + +2. **Inverting nearly singular matrices**. `np.linalg.inv()` returns a result even for near-singular matrices, the numbers will be astronomically large and numerically meaningless. Always prefer `np.linalg.solve(A, b)` over `np.linalg.inv(A) @ b` for solving linear systems. Check `np.linalg.cond(A)` before inverting; condition numbers above \(10^{12}\) are a red flag. + +3. **Testing `det == 0` for singularity**. In floating point, the determinant of a truly singular matrix is almost never exactly zero, it will be some very small number like `1e-17`. Do not use determinant as a singularity test in code. Use `np.linalg.matrix_rank(A) < n` or `np.linalg.cond(A) > threshold` instead. + +4. **Forgetting that matrix multiplication is non-commutative**. The most common algebraic error when implementing attention from scratch. \(\mathbf{AB} \neq \mathbf{BA}\). Even when both products are well-defined and have the same shape (square matrices), they will produce different results. When in doubt, track shapes explicitly and reason about the semantics of each multiplication. diff --git a/content/ai/math/algebra/matrices/index.es.md b/content/ai/math/algebra/matrices/index.es.md new file mode 100644 index 0000000..481aa6c --- /dev/null +++ b/content/ai/math/algebra/matrices/index.es.md @@ -0,0 +1,660 @@ +--- +weight: 2 +title: "Matrices: operaciones y propiedades" +authors: + - jnonino +description: > + Domina la aritmética matricial, transformaciones lineales, determinantes, rango e inversas desde cero. Derivaciones matemáticas paso a paso, código Python ejecutable e insights de nivel investigación para aspirantes a Científicos de ML. +date: 2026-03-13 +tags: ["IA", "Matemáticas", "Álgebra", "Álgebra Lineal", "Matrices"] +--- + +GPT-3 almacena su *"inteligencia"* en aproximadamente 1800 matrices de pesos. Cada *token* que escribís dispara una cascada de multiplicaciones a través de esas matrices (proyecciones, puntuaciones de atención, expansiones feed-forward) antes de que se produzca una única probabilidad de salida. El modelo completo de 175.000 millones de parámetros es, en su núcleo computacional, una composición intrincada de operaciones matriciales aplicadas en secuencia. + +Las matrices hacen que la idea abstracta de un espacio vectorial se convierta en un motor que podés ejecutar de verdad. Un vector te dice dónde está algo; una matriz te dice cómo moverlo. Las matrices de pesos en las redes neuronales codifican transformaciones aprendidas del espacio de características. Las matrices de covarianza en estadística codifican la forma de una distribución de datos. La matriz Jacobiana de una función codifica cómo cambian sus salidas respecto a sus entradas, es el objeto que hace posible la *retropropagación*. + +El problema es que la mayoría de las introducciones a las matrices las tratan como planillas de cálculo glorificadas: grillas de números con reglas aritméticas pegadas encima. Esa perspectiva hace que las operaciones parezcan arbitrarias. Este artículo toma el enfoque opuesto: arrancamos desde la geometría, derivamos cada operación desde primeros principios, y al final vas a ver las matrices no como tablas sino como **funciones**, con toda la riqueza que eso implica: composición, invertibilidad, imagen, núcleo y rango. + +Al finalizar este artículo, serás capaz de: + +- Definir formalmente una matriz y una transformación lineal, y explicar por qué importan los axiomas. +- Ejecutar y derivar todas las operaciones matriciales fundamentales: suma, multiplicación, transpuesta, traza e inversión. +- Calcular el determinante de manera geométrica y algebraica, y entender qué significa un determinante nulo. +- Razonar sobre el espacio columna, espacio fila, espacio nulo y rango. Enunciar y aplicar el Teorema Rango-Nulidad. +- Implementar estas operaciones desde cero en Python puro y NumPy. +- Conectar estas operaciones con la investigación contemporánea en aprendizaje profundo (*deep learning*). + +Comencemos. + +## Prerrequisitos + +Antes de leer este artículo, deberías dominar: + +- **Vectores y espacios vectoriales**: definiciones formales, productos punto, normas, espacio generado y combinaciones lineales. +- **Python y NumPy básico**: creación de arreglos, indexación, manipulación de formas (*shapes*). +- **Notación de funciones**: entender notación del estilo \(f: \mathbb{R}^m \rightarrow \mathbb{R}^n\). + +Si puedes definir qué significa que un conjunto sea *cerrado* bajo una operación, tienes la base suficiente. + +## Intuición primero + +### La analogía del programador: matrices como funciones + +Como desarrollador, has usado funciones toda tu carrera. Una función `transformar(x)` recibe una entrada y la mapea a una salida. Una matriz \(\mathbf{A}\) es exactamente eso, una **función** que toma un vector como entrada y produce un vector como salida. La restricción clave es que esta función debe ser *lineal*, lo que impone una estructura geométrica específica sobre qué transformaciones están permitidas. + +Pensalo de esta manera. Imaginate un pipeline de datos donde vectores de características de usuarios pasan por etapas de procesamiento: + +```python +# Etapa 1: expandir 3 características crudas a 5 características derivadas +etapa1 = transformar_3_a_5(caracteristicas_usuario) # shape: (5,) + +# Etapa 2: comprimir 5 características derivadas a 2 dimensiones latentes +etapa2 = transformar_5_a_2(etapa1) # shape: (2,) + +# Combinado: ¿podemos hacer ambas en un solo paso? +combinado = transformar_3_a_2(caracteristicas_usuario) # Sí, multiplicación de matrices +``` + +Esto es exactamente lo que calcula la multiplicación de matrices: la **composición** de dos transformaciones lineales en una. Una matriz \(5 \times 3\) (etapa 1) compuesta con una matriz \(2 \times 5\) (etapa 2) produce una única matriz \(2 \times 3\) que hace ambos pasos a la vez. Cada capa de una red neuronal es una etapa de este pipeline. + +### La imagen geométrica: matrices como transformaciones del espacio + +Imagina un sistema de coordenadas 2D. Los vectores de la [base canónica](https://es.wikipedia.org/wiki/Base_can%C3%B3nica) son: + +$$ +\hat{e}_1 = [1,0] \qquad \text{(apunta a la derecha a lo largo del eje x)} +$$ + +$$ +\hat{e}_2 = [0,1] \qquad \text{(apunta hacia arriba a lo largo del eje y)} +$$ + +Aplica la matriz \(\mathbf{A} = \begin{bmatrix} 2 & 0 \\ 0 & 3 \end{bmatrix}\). Tras la transformación: \(\hat{e}_1\) se mapea a \([2, 0]\) (estirado a la derecha por factor 2) y \(\hat{e}_2\) se mapea a \([0, 3]\) (estirado hacia arriba por factor 3). El cuadrado unitario (con área 1), se convierte en un rectángulo de \(2 \times 3\) con área 6. El **determinante** de \(\mathbf{A}\), que derivaremos en breve, es exactamente \(6\). Esto no es una coincidencia: el determinante *es* el factor de escalado del volumen. + +Compara esto con una matriz de rotación: + +$$ +\mathbf{R}(\theta) = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix} +$$ + +Ésta rota cada vector por el ángulo \(\theta\) sin estirarlo, por lo que preserva todas las áreas, y su determinante siempre es 1. + +Las columnas de cualquier matriz te dicen exactamente adónde van los vectores de la base. Dado que todo vector es una combinación lineal de los vectores base, saber adónde van los vectores base te dice adónde va *cada* vector del espacio. Este razonamiento explica por qué la multiplicación de matrices no es conmutativa (aplicar la transformación A y luego B es geométricamente diferente de B y luego A), y por qué las columnas de las matrices de pesos en las redes neuronales tienen un significado semántico que los investigadores analizan activamente. + +{{< callout type="important" >}} +Las columnas de una matriz no son sólo números, son las *imágenes de los vectores de la base* bajo la transformación. Cuando examinas la matriz de pesos \(\mathbf{W}\) de una capa de red neuronal entrenada, cada columna te dice cómo responde esa capa a una dirección de entrada estándar. Éste es el fundamento de la investigación de visualización de características, donde los practicantes interpretan qué *"detecta"* cada neurona examinando las direcciones en las matrices de pesos. +{{< /callout >}} + +## Derivación matemática + +### Definición formal + +Una **matriz \(m \times n\)** sobre \(\mathbb{R}\) es un arreglo rectangular de números reales con \(m\) filas y \(n\) columnas: + +$$ +\mathbf{A} = \begin{bmatrix} 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{bmatrix} \in \mathbb{R}^{m \times n} +$$ + +La entrada \(A_{ij}\) denota el elemento en la **fila \(i\), columna \(j\)**. Escribimos el conjunto de todas las matrices reales \(m \times n\) como \(\mathbb{R}^{m \times n}\). + +{{< callout type="info" >}} +En palabras sencillas: una matriz es una tabla 2D de números. La notación \(\mathbb{R}^{m \times n}\) es el *"tipo"* de la matriz (cuántas filas y columnas tiene). Es exactamente la firma de tipo que adjuntarías a un arreglo 2D en un lenguaje de tipado estático: `Array[Float, m, n]`. +{{< /callout >}} + +**Casos especiales** que encontrarás constantemente: + +- **Vector columna**: una matriz de forma \(n \times 1\), es simplemente un vector \(\mathbf{v} \in \mathbb{R}^n\). +- **Vector fila**: una matriz de forma \(1 \times n\). +- **Matriz cuadrada**: una matriz donde \(m = n\). +- **Matriz identidad** \(\mathbf{I}_n\): la matriz \(n \times n\) con \(I_{ij} = 1\) si \(i = j\), de lo contrario \(0\). +- **Matriz cero** \(\mathbf{0}\): todas las entradas son cero. +- **Matriz diagonal**: una matriz cuadrada donde \(A_{ij} = 0\) para todo \(i \neq j\). + +### Las matrices como transformaciones lineales + +La propiedad más importante de una matriz es que define una **transformación lineal** \(T: \mathbb{R}^n \rightarrow \mathbb{R}^m\) mediante \(T(\mathbf{x}) = \mathbf{A}\mathbf{x}\). + +Una función \(T\) se llama **lineal** si y solo si satisface dos axiomas para todos los vectores \(\mathbf{u}, \mathbf{v} \in \mathbb{R}^n\) y todos los escalares \(\alpha \in \mathbb{R}\): + +- *Aditividad*: \(T(\mathbf{u} + \mathbf{v}) = T(\mathbf{u}) + T(\mathbf{v})\) +- *Homogeneidad*: \(T(\alpha \mathbf{u}) = \alpha T(\mathbf{u})\) + +Estos dos axiomas son equivalentes a la condición única: + +$$ +T(\alpha \mathbf{u} + \beta \mathbf{v}) = \alpha T(\mathbf{u}) + \beta T(\mathbf{v}) +$$ + +{{< callout type="info" >}} +En términos sencillos: una transformación lineal preserva la estructura del espacio vectorial, no importa si sumas dos vectores primero y luego transformas, o si transformas cada uno por separado y luego sumas. Por eso apilar múltiples capas lineales (sin activación) en una red neuronal se colapsa en un único producto matricial: \(\mathbf{W}_2(\mathbf{W}_1\mathbf{x}) = (\mathbf{W}_2\mathbf{W}_1)\mathbf{x}\). +{{< /callout >}} + +Un teorema fundamental del álgebra lineal establece que **toda** transformación lineal entre espacios de dimensión finita puede representarse como una matriz, y a la inversa, toda matriz define una transformación lineal. La matriz y la transformación lineal son, a efectos prácticos, el mismo objeto. + +### Suma de matrices y multiplicación por escalar + +El conjunto \(\mathbb{R}^{m \times n}\) de todas las matrices reales \(m \times n\) forma un **espacio vectorial** bajo las siguientes operaciones. + +**Suma de matrices**: Dadas \(\mathbf{A}, \mathbf{B} \in \mathbb{R}^{m \times n}\): + +$$ +(\mathbf{A} + \mathbf{B})_{ij} = A_{ij} + B_{ij} +$$ + +Esta operación satisface: +- *Conmutatividad*: \(\mathbf{A} + \mathbf{B} = \mathbf{B} + \mathbf{A}\) +- *Asociatividad*: \((\mathbf{A} + \mathbf{B}) + \mathbf{C} = \mathbf{A} + (\mathbf{B} + \mathbf{C})\) +- *Elemento identidad*: existe una matriz cero \(\mathbf{0}\) tal que \(\mathbf{A} + \mathbf{0} = \mathbf{A}\) +- *Elemento inverso*: para cada \(\mathbf{A}\), existe \(-\mathbf{A}\) tal que \(\mathbf{A} + (-\mathbf{A}) = \mathbf{0}\) + +**Multiplicación por escalar**: Dados \(\alpha \in \mathbb{R}\) y \(\mathbf{A} \in \mathbb{R}^{m \times n}\): + +$$ +(\alpha \mathbf{A})_{ij} = \alpha \cdot A_{ij} +$$ + +Esta operación satisface: +- *Asociatividad*: \(\alpha(\beta \mathbf{A}) = (\alpha\beta)\mathbf{A}\) +- *Elemento identidad*: \(1 \cdot \mathbf{A} = \mathbf{A}\) +- *Distributividad respecto a la suma de matrices*: \(\alpha(\mathbf{A} + \mathbf{B}) = \alpha\mathbf{A} + \alpha\mathbf{B}\) +- *Distributividad respecto a la suma de escalares*: \((\alpha + \beta)\mathbf{A} = \alpha\mathbf{A} + \beta\mathbf{A}\) + +{{< callout >}} +Si estos axiomas te resultan familiares, tiene todo el sentido. Son exactamente los axiomas de espacio vectorial que vimos en el artículo sobre vectores. Las matrices *"son"* vectores en un espacio de mayor dimensión. Una matriz \(3 \times 4\) puede ser vista como un vector de \(12\) componentes dispuestos en una cuadrícula. Esto significa que todo teorema que demostremos sobre espacios vectoriales también aplica a matrices. +{{< /callout >}} + +### Multiplicación de matrices + +Dados \(\mathbf{A} \in \mathbb{R}^{m \times k}\) y \(\mathbf{B} \in \mathbb{R}^{k \times n}\), su producto \(\mathbf{C} = \mathbf{A}\mathbf{B} \in \mathbb{R}^{m \times n}\) se define como: + +$$ +\boxed{C_{ij} = \sum_{l=1}^{k} A_{il} \cdot B_{lj}} +$$ + +Para calcular la entrada \(C_{ij}\), el elemento en la fila \(i\), columna \(j\) del resultado, toma el **producto punto de la fila \(i\) de \(\mathbf{A}\) con la columna \(j\) de \(\mathbf{B}\)**. Las dimensiones internas deben coincidir: + +$$\underbrace{\mathbf{A}}_{m \times k} \cdot \underbrace{\mathbf{B}}_{k \times n} = \underbrace{\mathbf{C}}_{m \times n}$$ + +{{< callout type="info" >}} +En otros términos: la multiplicación de matrices es composición de funciones. Aplicar la transformación \(\mathbf{B}\) primero, y luego \(\mathbf{A}\), produce el mismo resultado que la única transformación compuesta \(\mathbf{AB}\). Las dimensiones internas deben coincidir porque la dimensión de salida de la primera transformación debe igualar la dimensión de entrada de la segunda, exactamente como componer funciones. +{{< /callout >}} + +La multiplicación de matrices satisface: +- *Asociatividad*: \((\mathbf{AB})\mathbf{C} = \mathbf{A}(\mathbf{BC})\) +- *Distributividad izquierda*: \(\mathbf{A}(\mathbf{B} + \mathbf{C}) = \mathbf{AB} + \mathbf{AC}\) +- *Distributividad derecha*: \((\mathbf{A} + \mathbf{B})\mathbf{C} = \mathbf{AC} + \mathbf{BC}\) +- *Identidad*: \(\mathbf{A}\mathbf{I} = \mathbf{I}\mathbf{A} = \mathbf{A}\) (para \(\mathbf{I}\) compatible) +- **No conmutatividad**: \(\mathbf{AB} \neq \mathbf{BA}\) en general + +{{< callout >}} +La no conmutatividad no es un defecto sino una característica fundamental de las transformaciones. Rotar una figura y luego reflejarla es geométricamente diferente a reflejarla y luego rotarla. +{{< /callout >}} + +### La transpuesta + +La **transpuesta** de \(\mathbf{A} \in \mathbb{R}^{m \times n}\) es la matriz \(\mathbf{A}^\top \in \mathbb{R}^{n \times m}\) definida por: + +$$ +(\mathbf{A}^\top)_{ij} = A_{ji} +$$ + +{{< callout type="info" >}} +En palabras simples: voltea la matriz a lo largo de su diagonal principal, las filas se convierten en columnas y las columnas en filas. Una matriz \(3 \times 5\) se convierte en una \(5 \times 3\). Geométricamente, la transpuesta corresponde al *adjunto* de la transformación, la transformación que *"deshace la parte de rotación"* mientras conserva el escalado. +{{< /callout >}} + +La transpuesta satisface las siguientes propiedades: + +- *Doble transpuesta*: \((\mathbf{A}^\top)^\top = \mathbf{A}\) +- *Linealidad*: \((\mathbf{A} + \mathbf{B})^\top = \mathbf{A}^\top + \mathbf{B}^\top\) y \((\alpha\mathbf{A})^\top = \alpha\mathbf{A}^\top\) +- *Inversión del orden del producto*: \((\mathbf{AB})^\top = \mathbf{B}^\top \mathbf{A}^\top\) + +La propiedad de inversión del orden es **crítica** y aparece en cada derivación de retropropagación. Vamos a probarla completamente. Queremos demostrar que \([(\mathbf{AB})^\top]_{ij} = [\mathbf{B}^\top \mathbf{A}^\top]_{ij}\). + +Partimos de la definición de transpuesta: + +$$ +[(\mathbf{AB})^\top]_{ij} = [\mathbf{AB}]_{ji} +$$ + +Aplicando la definición de multiplicación de matrices a \([\mathbf{AB}]_{ji}\): + +$$ +[\mathbf{AB}]_{ji} = \sum_{l} A_{jl} \cdot B_{li} +$$ + +Reconociendo cada factor usando la definición de transpuesta (\(A_{jl} = [\mathbf{A}^\top]_{lj}\) y \(B_{li} = [\mathbf{B}^\top]_{il}\)): + +$$ +\sum_{l} A_{jl} B_{li} = \sum_{l} [\mathbf{B}^\top]_{il} \cdot [\mathbf{A}^\top]_{lj} +$$ + +Reconociendo la parte derecha como la definición de multiplicación de matrices \([\mathbf{B}^\top \mathbf{A}^\top]_{ij}\): + +$$ +\boxed{(\mathbf{AB})^\top = \mathbf{B}^\top \mathbf{A}^\top} +$$ + +**Matrices simétricas y antisimétricas** son casos especiales importantes: + +- \(\mathbf{A}\) es **simétrica** si \(\mathbf{A}^\top = \mathbf{A}\), equivalentemente \(A_{ij} = A_{ji}\) para todo \(i, j\). Las matrices de covarianza y las matrices kernel en Machine Learning son siempre simétricas. +- \(\mathbf{A}\) es **antisimétrica** si \(\mathbf{A}^\top = -\mathbf{A}\), equivalentemente \(A_{ij} = -A_{ji}\) y todas las entradas diagonales son cero. + +{{< callout >}} +Cualquier matriz cuadrada \(\mathbf{A}\) puede descomponerse de forma única en una parte simétrica y una parte antisimétrica: + +$$ +\mathbf{A} = \underbrace{\frac{\mathbf{A} + \mathbf{A}^\top}{2}}_{\text{simétrica}} + \underbrace{\frac{\mathbf{A} - \mathbf{A}^\top}{2}}_{\text{antisimétrica}} +$$ + +Esta descomposición tiene aplicaciones en física (análisis de deformación vs. rotación) y en investigación reciente sobre la estructura de los mecanismos de atención. +{{< /callout >}} + +### La traza + +Para una matriz cuadrada \(\mathbf{A} \in \mathbb{R}^{n \times n}\), la **traza** es la suma de las entradas diagonales: + +$$ +\text{tr}(\mathbf{A}) = \sum_{i=1}^{n} A_{ii} +$$ + +{{< callout type="info" >}} +En palabras simples: suma la diagonal principal. La traza captura cuánto la transformación *"expande"* el espacio en promedio. +{{< /callout >}} + +Propiedades clave: +- *Linealidad*: \(\text{tr}(\mathbf{A} + \mathbf{B}) = \text{tr}(\mathbf{A}) + \text{tr}(\mathbf{B})\) y \(\text{tr}(\alpha\mathbf{A}) = \alpha\,\text{tr}(\mathbf{A})\) +- *Invarianza bajo transpuesta*: \(\text{tr}(\mathbf{A}^\top) = \text{tr}(\mathbf{A})\) +- **Propiedad cíclica**: \(\text{tr}(\mathbf{ABC}) = \text{tr}(\mathbf{BCA}) = \text{tr}(\mathbf{CAB})\) + +La propiedad cíclica es omnipresente en las derivaciones de gradientes. Demostremos el caso base \(\text{tr}(\mathbf{AB}) = \text{tr}(\mathbf{BA})\). + +Partiendo de la definición de traza: + +$$ +\text{tr}(\mathbf{AB}) = \sum_{i} [\mathbf{AB}]_{ii} = \sum_{i} \sum_{j} A_{ij} B_{ji} +$$ + +Intercambiando el orden de la suma (válido ya que ambas sumas son finitas): + +$$ +\sum_{i} \sum_{j} A_{ij} B_{ji} = \sum_{j} \sum_{i} B_{ji} A_{ij} +$$ + +Reconociendo la suma de la derecha como la entrada diagonal \([\mathbf{BA}]_{jj}\): + +$$ +\sum_{j} \sum_{i} B_{ji} A_{ij} = \sum_{j} [\mathbf{BA}]_{jj} = \text{tr}(\mathbf{BA}) +$$ + +$$ +\boxed{\text{tr}(\mathbf{AB}) = \text{tr}(\mathbf{BA})} +$$ + +{{< callout >}} +Notá que esto se cumple incluso cuando \(\mathbf{AB}\) y \(\mathbf{BA}\) tienen distintas formas (por ejemplo, \(\mathbf{A} \in \mathbb{R}^{m \times n}\), \(\mathbf{B} \in \mathbb{R}^{n \times m}\)), ambas trazas son escalares e iguales. +{{< /callout >}} + +### El determinante + +Antes de calcular ninguna fórmula, vale la pena hacerse las preguntas de fondo: ¿por qué existe el determinante? ¿Qué problema resuelve? + +Cuando una matriz codifica una transformación lineal, la pregunta más fundamental que podés hacerle es: **¿destruye información?** Una transformación que aplasta un plano 2D en una recta 1D perdió toda la información de la dimensión colapsada, no puede deshacerse. Una transformación que rota o estira el plano preserva toda la información y puede revertirse. El determinante es el único número que responde a esta pregunta, e indica por cuánto. + +Más precisamente, el determinante responde tres preguntas interconectadas de manera simultánea. + +{{< details title="¿Cómo escala la transformación los volúmenes?" closed="true" >}} +En dos dimensiones, las dos columnas de una matriz son simplemente dos vectores dibujados desde el origen. Dos vectores desde el mismo origen siempre encierran un paralelogramo, no es una elección, es geometría. El determinante es el *área con signo* de ese paralelogramo. Si \(|\det(\mathbf{A})| = 6\), toda región del plano tiene su área multiplicada por 6 al aplicar la transformación. En 3D, se convierte en el volumen con signo del paralelepípedo formado por los tres vectores columna. + +{{< figure + src="images/volume-scale.es.svg" + alt="Escala de volúmenes por el determinante" + caption="Las dos columnas de una matriz \(2\times2\) son vectores que siempre forman un paralelogramo. El determinante es su área con signo." + >}} +{{< /details >}} + +{{< details title="¿Preserva o invierte la orientación?" closed="true" >}} +La palabra *con signo* importa. Dos vectores siempre forman un paralelogramo, pero el *orden* en que los recorrés determina el signo del área. Si la rotación de \(\mathbf{a}_1\) hacia \(\mathbf{a}_2\) es **antihoraria**, el determinante es positivo. Si es **horaria**, el determinante es negativo. El contenido geométrico es idéntico (misma figura, misma área) pero el signo codifica si la transformación preserva o invierte la lateralidad del espacio. + +{{< figure + src="images/orientation.es.svg" + alt="Preservación o inversión de la orientación por el determinante" + caption="El orden de los vectores columna determina el signo del área, codificando si la transformación preserva o invierte la orientación." + >}} +{{< /details >}} + +{{< details title="¿Es la transformación invertible?" closed="true" >}} +\(\det(\mathbf{A}) = 0\) significa que los dos vectores columna son paralelos, yacen sobre la misma recta, encerrando área cero. La transformación colapsa un plano 2D en una recta 1D. La información se pierde de manera irreversible: infinitas entradas distintas producen la misma salida, por lo que no podés determinar de cuál viniste. La matriz es **singular** y no tiene inversa. + +{{< figure + src="images/invertible.es.svg" + alt="Transformación invertible" + caption="Una transformación es invertible si y solo si su determinante es distinto de cero." + >}} +{{< /details >}} + +{{< callout type="important" >}} +En ML, verificar el determinante antes de invertir una matriz no es un formalismo matemático, es un paso de depuración práctico. Las matrices de covarianza casi singulares causan inestabilidad numérica en [procesos gaussianos](https://es.wikipedia.org/wiki/Proceso_de_Gauss), en la ecuación normal de la regresión lineal y en la reducción de dimensionalidad. Cuando un modelo produce salidas `NaN` o predicciones desproporcionadamente grandes después de una inversión matricial, un determinante cercano a cero suele ser el culpable. +{{< /callout >}} + +#### Propiedades clave + +- **Multiplicatividad**: \(\det(\mathbf{AB}) = \det(\mathbf{A})\det(\mathbf{B})\), aplicar una transformación que duplica el volumen seguida de una que lo triplica produce una expansión global de seis veces. +- **Invarianza bajo transpuesta**: \(\det(\mathbf{A}^\top) = \det(\mathbf{A})\), filas y columnas contribuyen simétricamente al volumen. +- **Escalado de fila**: escalar una fila por \(\alpha\) también escala el determinante por \(\alpha\), estás escalando una dimensión del paralelepípedo. +- **Intercambio de filas**: intercambiar dos filas niega el determinante, estás invirtiendo la orientación. +- **Adición de filas**: sumar un múltiplo de una fila a otra no cambia el determinante. Por esto la eliminación gaussiana funciona: nunca cambia el determinante. +- **Matrices triangulares**: \(\det(\mathbf{A}) = \prod_{i} A_{ii}\). Solo importan las entradas diagonales. +- **Invertibilidad**: \(\mathbf{A}\) es invertible si y solo si \(\det(\mathbf{A}) \neq 0\). + +#### El caso 2x2, derivación desde la geometría + +Sea \(\mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}\). Los dos vectores columna son \(\mathbf{a}_1 = \begin{bmatrix}a \\ c\end{bmatrix}\) y \(\mathbf{a}_2 = \begin{bmatrix}b \\ d\end{bmatrix}\). + +El determinante es el área con signo del paralelogramo que forman los cuatro vértices: \(O = (0,0)\), \(A = (a,c)\), \(B = (b,d)\) y \(C = (a+b,\, c+d)\). + +$$ +\boxed{\det\begin{bmatrix} a & b \\ c & d \end{bmatrix} = ad - bc} +$$ + +Derivamos esto de dos maneras complementarias: primero geométricamente mediante sustracción del rectángulo delimitador, y luego algebraicamente mediante la fórmula de *Shoelace*. + +{{< details title="Sustracción del rectángulo delimitador" closed="true" >}} +Encerrá el paralelogramo en el rectángulo alineado con los ejes más pequeño que lo contiene: un rectángulo de ancho \(a+b\) y alto \(c+d\). El área de este rectángulo es \((a+b)(c+d)\). + +La región entre el rectángulo y el paralelogramo se compone de exactamente seis piezas: + +- **Dos rectángulos** con lados \(b\) y \(c\) (esquinas superior izquierda e inferior derecha). +- **Dos triángulos** con catetos \(a\) y \(c\) (triángulos superior e inferior). +- **Dos triángulos** con catetos \(b\) y \(d\) (triángulos izquierdo y derecho). + +{{< figure + src="images/parallelogram-area.es.svg" + alt="Área del paralelogramo" + caption="El área del paralelogramo es la diferencia entre el rectángulo delimitador y el área de los triángulos." + >}} + +Expandiendo el área del rectángulo y restando las áreas de las seis piezas tendremos el area del paralelogramo (\(S\)): + +$$ +\begin{aligned} + S &= (a+b)(c+d) - 2(bc) - 2\left(\frac{1}{2}ac\right) - 2\left(\frac{1}{2}bd\right) \\ + S &= ac + ad + bc + bd - 2(bc) - 2\left(\frac{1}{2}ac\right) - 2\left(\frac{1}{2}bd\right) \\ + S &= ac + ad + bc + bd - 2(bc) - ac - bd \\ + S &= ad - bc +\end{aligned} +$$ +{{< /details >}} + +{{< details title="Fórmula de Shoelace" closed="true" >}} +La **fórmula de Shoelace** (o fórmula del cordón de zapato) da el área con signo de cualquier polígono cuyos vértices se listen en orden. Para un polígono con \(n\) vértices \((x_1, y_1), \ldots, (x_n, y_n)\) recorridos en sentido antihorario: + +$$ +\text{área con signo} = \frac{1}{2}\sum_{i=1}^{n}\bigl(x_i y_{i+1} - x_{i+1} y_{i}\bigr) +$$ + +donde los índices son cíclicos, es decir, \(x_{n+1} = x_1\), \(y_{n+1} = y_1\), etcétera y \(n\) es el número de vértices. + +La intuición detrás de cada término \(x_{i} y_{i+1} - x_{i+1} y_{i}\) es que mide el área con signo del triángulo formado por el origen, el vértice \(i\) y el vértice \(i+1\). Sumando estos triángulos alrededor del polígono se obtiene el área total con signo, positiva para recorrido antihorario, negativa para horario. + +Aplicamos esto al paralelogramo con vértices en orden antihorario: + +$$ +\mathbf{O} = (0,0), \quad A = (a,c), \quad C = (a+b,\, c+d), \quad B = (b,d) +$$ + +Expandiendo la suma término a término: + +**Término 1** (\(\mathbf{O} \to A\)) +$$ +\begin{aligned} + x_{\mathbf{O}}\, y_A - x_A\, y_{\mathbf{O}} &= 0 \cdot c - a \cdot 0 \\ + x_{\mathbf{O}}\, y_A - x_A\, y_{\mathbf{O}} &= 0 +\end{aligned} +$$ + +**Término 2** (\(A \to C\)) +$$ +\begin{aligned} + x_A\, y_C - x_C\, y_A &= a(c+d) - (a+b)c \\ + x_A\, y_C - x_C\, y_A &= ac + ad - ac - bc \\ + x_A\, y_C - x_C\, y_A &= ad - bc +\end{aligned} +$$ + +**Término 3** (\(C \to B\)) +$$ +\begin{aligned} + x_C\, y_B - x_B\, y_C &= (a+b)d - b(c+d) \\ + x_C\, y_B - x_B\, y_C &= ad + bd - bc - bd \\ + x_C\, y_B - x_B\, y_C &= ad - bc +\end{aligned} +$$ + +**Término 4** (\(B \to O\)) +$$ +\begin{aligned} + x_B\, y_O - x_O\, y_B &= b \cdot 0 - 0 \cdot d \\ + x_B\, y_O - x_O\, y_B &= 0 +\end{aligned} +$$ + +Sumando y aplicando el factor \(\tfrac{1}{2}\): +$$ +\begin{aligned} + \text{área con signo} &= \frac{1}{2}\bigl[0 + (ad - bc) + (ad - bc) + 0\bigr] \\ + \text{área con signo} &= \frac{1}{2} \cdot 2(ad-bc) \\ + \text{área con signo} &= ad - bc +\end{aligned} +$$ + +Esta derivación no asume ningún signo particular para \(a, b, c, d\) — vale para cualquier entrada real. El resultado es positivo cuando el recorrido \(\mathbf{O} \to A \to C \to B\) es antihorario (es decir, cuando \(ad > bc\)), y negativo cuando es horario. Ése es exactamente el signo que codifica la orientación. +{{< /details >}} + +#### El caso 3x3, expansión por cofactores + +En 3D, el determinante mide el volumen con signo del paralelepípedo formado por los tres vectores columna. El cálculo se expande a lo largo de la primera fila, donde cada término contribuye con un área proyectada ponderada por la entrada correspondiente. Dada la matriz \(\mathbf{A} \in \mathbb{R}^{3 \times 3}\): + +$$ +\mathbf{A} = \begin{bmatrix} A_{11} & A_{12} & A_{13} \\ A_{21} & A_{22} & A_{23} \\ A_{31} & A_{32} & A_{33} \end{bmatrix} +$$ + +$$ +\det(\mathbf{A}) = A_{11}\det\begin{bmatrix}A_{22}&A_{23}\\A_{32}&A_{33}\end{bmatrix} - A_{12}\det\begin{bmatrix}A_{21}&A_{23}\\A_{31}&A_{33}\end{bmatrix} + A_{13}\det\begin{bmatrix}A_{21}&A_{22}\\A_{31}&A_{32}\end{bmatrix} +$$ + +{{< details title="Los menores de la matriz" closed="true" >}} +Cada matriz \(2 \times 2\) es un **menor** \(M_{1j}\): la submatriz obtenida borrando la fila 1 y la columna \(j\). El menor con signo \(C_{ij} = (-1)^{i+j} M_{ij}\) se llama **cofactor**. Los signos alternantes siguen el patrón de tablero de ajedrez que se muestra a continuación, lo que asegura que las contribuciones se combinen correctamente para dar el volumen con signo. + +{{< figure + src="images/cofactor-sign-pattern.svg" + alt="Patrón de signos del cofactor" + caption="El patrón de signos del cofactor sigue un patrón de tablero de ajedrez." + >}} + +{{< callout type="info" >}} +Elegí cualquier fila de la matriz. Para cada entrada, tapá su fila y su columna para revelar un bloque \(2 \times 2\), calculá su determinante, multiplicá por la entrada y por el signo del tablero de arriba, y sumá los tres resultados. Esto es recursivo: un determinante \(4 \times 4\) se expande en cuatro determinantes \(3 \times 3\), etc. +{{< /callout >}} +{{< /details >}} + +#### La fórmula general de Leibniz + +Para una matriz \(n \times n\), el determinante suma sobre todas las formas de elegir una entrada de cada fila y cada columna simultáneamente, es decir, sobre todas las permutaciones: + +$$ +\det(\mathbf{A}) = \sum_{\sigma \in S_n} \text{sgn}(\sigma) \prod_{i=1}^{n} A_{i,\sigma(i)} +$$ + +donde \(S_n\) es el conjunto de todas las permutaciones de \(\{1, \ldots, n\}\) y \(\text{sgn}(\sigma) = \pm 1\) es la paridad de la permutación (\(+1\) si la permutación es par y \(-1\) si es impar). + +{{< callout type="important" >}} +Esta fórmula tiene \(n!\) términos, por lo que nunca se calcula directamente para matrices grandes. La descomposición LU calcula el determinante en \(\mathcal{O}(n^3)\) como subproducto de la factorización. Pero la fórmula de Leibniz es la herramienta correcta para demostrar identidades. +{{< /callout >}} + +### Independencia lineal y espacios columna, fila y nulo + +Entender una matriz significa entender los *espacios* que crea y destruye. + +Un conjunto de vectores \(\{\mathbf{v}_1, \ldots, \mathbf{v}_k\}\) es **linealmente independiente** si la única solución a: + +$$ +\alpha_1 \mathbf{v}_1 + \alpha_2 \mathbf{v}_2 + \cdots + \alpha_k \mathbf{v}_k = \mathbf{0} +$$ + +es \(\alpha_1 = \alpha_2 = \cdots = \alpha_k = 0\). En otras palabras, ningún vector del conjunto puede escribirse como combinación de los demás. Las columnas linealmente dependientes son la firma de una matriz de rango deficiente. + +Para \(\mathbf{A} \in \mathbb{R}^{m \times n}\), se definen tres subespacios fundamentales: + +- **Espacio columna** (imagen), \(\text{col}(\mathbf{A}) \subseteq \mathbb{R}^m\): es el espacio generado por las columnas de \(\mathbf{A}\). Es el conjunto de todas las salidas posibles de la transformación \(\mathbf{A}\). El rango de \(\mathbf{A}\) es la dimensión de este espacio. + +$$ +\begin{aligned} + \text{col}(\mathbf{A}) &= \{\mathbf{A}\mathbf{x} : \mathbf{x} \in \mathbb{R}^n\} \\ + \text{col}(\mathbf{A}) &= \left\{ x_1 \begin{bmatrix}a_{11} \\ a_{21} \\ \vdots \\ a_{m1}\end{bmatrix} + x_2 \begin{bmatrix}a_{12} \\ a_{22} \\ \vdots \\ a_{m2}\end{bmatrix} + \cdots + x_n \begin{bmatrix}a_{1n} \\ a_{2n} \\ \vdots \\ a_{mn}\end{bmatrix} \right\} : x_i \in \mathbb{R} +\end{aligned} +$$ + +- **Espacio fila**, \(\text{row}(\mathbf{A}) \subseteq \mathbb{R}^n\): el espacio generado por las filas de \(\mathbf{A}\). Equivalentemente, \(\text{row}(\mathbf{A}) = \text{col}(\mathbf{A}^\top)\). + +- **Espacio nulo** (núcleo), \(\text{null}(\mathbf{A}) \subseteq \mathbb{R}^n\): todos los vectores de entrada que \(\mathbf{A}\) mapea a cero: + $$ + \text{null}(\mathbf{A}) = \{\mathbf{x} \in \mathbb{R}^n : \mathbf{A}\mathbf{x} = \mathbf{0}\} + $$ + +{{< callout type="info" >}} +En otras palabras: el espacio nulo es el "punto ciego" de la transformación. Cualquier vector en el espacio nulo es invisible para la matriz, produce cero señal de salida sin importar cuán grande sea. En el contexto de redes neuronales, las direcciones en el espacio nulo de una matriz de pesos no reciben ningún gradiente de esa capa y nunca serán actualizadas por los gradientes de esa capa por sí solos. +{{< /callout >}} + +### Rango + +El **rango** de \(\mathbf{A}\) es la dimensión de su espacio columna, el número de columnas linealmente independientes: + +$$ +\text{rango}(\mathbf{A}) = \dim(\text{col}(\mathbf{A})) +$$ + +Un resultado fundamental, la **igualdad del rango fila y el rango columna**, establece que la dimensión del espacio fila siempre es igual a la dimensión del espacio columna: + +$$ +\text{rango}(\mathbf{A}) = \dim(\text{col}(\mathbf{A})) = \dim(\text{row}(\mathbf{A})) +$$ + +Para una matriz \(m \times n\): \(\text{rango}(\mathbf{A}) \leq \min(m, n)\). + +Cuando \(\text{rango}(\mathbf{A}) = \min(m,n)\), \(\mathbf{A}\) tiene **rango completo**. De lo contrario es **deficiente en rango** y mapea un subespacio no nulo de entradas a cero. + +### El teorema Rango-Nulidad + +Este teorema conecta elegantemente los tres subespacios fundamentales. + +Para cualquier matriz \(\mathbf{A} \in \mathbb{R}^{m \times n}\): + +$$ +\boxed{\text{rango}(\mathbf{A}) + \text{nulidad}(\mathbf{A}) = n} +$$ + +donde \(\text{nulidad}(\mathbf{A}) = \dim(\text{null}(\mathbf{A}))\). + +{{< details title="Esquema de demostración" closed="true" >}} +Sea \(r = \text{rango}(\mathbf{A})\) y sea \(\{\mathbf{v}_1, \ldots, \mathbf{v}_{n-r}\}\) una base para \(\text{null}(\mathbf{A})\). Extiende esto a una base de \(\mathbb{R}^n\) añadiendo \(r\) vectores \(\{\mathbf{w}_1, \ldots, \mathbf{w}_r\}\) del espacio fila de \(\mathbf{A}\) (que es ortogonal al espacio nulo). Las imágenes \(\{\mathbf{A}\mathbf{w}_1, \ldots, \mathbf{A}\mathbf{w}_r\}\) son linealmente independientes y generan \(\text{col}(\mathbf{A})\). Por tanto \(\dim(\text{col}(\mathbf{A})) = r\). La base total tiene \(r + (n - r) = n\) elementos, coincidiendo con \(\dim(\mathbb{R}^n) = n\). + +{{< callout type="info" >}} +En otras palabras: las \(n\) dimensiones de entrada se dividen limpiamente en dos partes complementarias. Algunas (\(r\) dimensiones, el espacio fila) se mapean a salidas no nulas. Las demás (\(n - r\) dimensiones, el espacio nulo) se mapean a cero. Estas dos partes particionan el espacio de entrada completamente y sin solapamiento, por eso sus dimensiones deben sumar exactamente \(n\). +{{< /callout >}} +{{< /details >}} + +{{< callout >}} +En términos de ML, si tienes una matriz de pesos \(\mathbf{W}\) de forma \(m \times n\) con \(n > m\) (una capa "sobreparametrizada"), entonces \(\text{nulidad}(\mathbf{W}) \geq n - m > 0\). Existe todo un subespacio de perturbaciones de pesos que produce cambio cero en la salida de la capa. Ésta es una razón por la que los modelos sobreparametrizados pueden podarse y comprimirse agresivamente, muchas direcciones de peso literalmente no hacen nada. +{{< /callout >}} + +### La inversa + +Para una matriz **cuadrada** \(\mathbf{A} \in \mathbb{R}^{n \times n}\), la **inversa** \(\mathbf{A}^{-1}\) es la única matriz que satisface: + +$$ +\mathbf{A}\mathbf{A}^{-1} = \mathbf{A}^{-1}\mathbf{A} = \mathbf{I}_n +$$ + +El **teorema de la matriz invertible** establece que las siguientes condiciones son todas equivalentes, *si cualquiera se cumple, todas se cumplen, y la inversa existe*: + +- \(\text{rango}(\mathbf{A}) = n\) (rango completo) +- \(\det(\mathbf{A}) \neq 0\) +- \(\text{null}(\mathbf{A}) = \{\mathbf{0}\}\) (espacio nulo trivial) +- Las columnas de \(\mathbf{A}\) son linealmente independientes +- Las filas de \(\mathbf{A}\) son linealmente independientes +- La ecuación \(\mathbf{A}\mathbf{x} = \mathbf{b}\) tiene solución única para todo \(\mathbf{b} \in \mathbb{R}^n\) + +{{< callout type="important" >}} +Las seis condiciones son formas equivalentes de decir lo mismo, la transformación es completamente reversible. Si la matriz colapsa alguna dimensión, hay un espacio nulo no trivial, el determinante es cero, ya no puedes deshacer la transformación. Todos los caminos llevan a la misma conclusión: la invertibilidad es una propiedad de todo o nada. +{{< /callout >}} + +Propiedades de la inversa: +- *Doble inversa*: \((\mathbf{A}^{-1})^{-1} = \mathbf{A}\) +- *Inversa del producto*: \((\mathbf{AB})^{-1} = \mathbf{B}^{-1}\mathbf{A}^{-1}\) (el orden se invierte, igual que con la transpuesta) +- *Conmutatividad transpuesta-inversa*: \((\mathbf{A}^\top)^{-1} = (\mathbf{A}^{-1})^\top\) +- *Determinante*: \(\det(\mathbf{A}^{-1}) = \frac{1}{\det(\mathbf{A})}\) + +#### Cálculo de la inversa + +Para matrices \(2 \times 2\), como \(\mathbf{A} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}\) con \(\det(\mathbf{A}) = ad - bc \neq 0\), existe una fórmula explícita que se deriva de la definición de inversa y el cálculo del determinante. + +Buscamos \(\mathbf{A}^{-1} = \begin{bmatrix} p & q \\ r & s \end{bmatrix}\) tal que \(\mathbf{A}\mathbf{A}^{-1} = \mathbf{I}\): + +$$ +\begin{aligned} + \begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix} p & q \\ r & s \end{bmatrix} &= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \\ + \begin{bmatrix} ap+br & aq+bs \\ cp+dr & cq+ds \end{bmatrix} &= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} +\end{aligned} +$$ + +De la primera columna tenemos que: \(ap + br = 1\) y \(cp + dr = 0\). Resolviendo, encontramos que: +$$ +\begin{aligned} + p &= \frac{d}{ad-bc} \\ + r &= \frac{-c}{ad-bc} +\end{aligned} +$$ + +De la segunda columna: \(aq + bs = 0\) y \(cq + ds = 1\). Resolviendo: +$$ +\begin{aligned} + q &= \frac{-b}{ad-bc} \\ + s &= \frac{a}{ad-bc} +\end{aligned} +$$ + +Reemplazando: +$$ +\begin{aligned} + \mathbf{A}^{-1} &= \begin{bmatrix} p & q \\ r & s \end{bmatrix} \\ + \mathbf{A}^{-1} &= \begin{bmatrix} \frac{d}{ad-bc} & \frac{-b}{ad-bc} \\ \frac{-c}{ad-bc} & \frac{a}{ad-bc} \end{bmatrix} \\ + \mathbf{A}^{-1} &= \frac{1}{ad - bc} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix} +\end{aligned} +$$ + +Sabiendo que \(\det(\mathbf{A}) = ad - bc\), entonces: + +$$ +\boxed{\mathbf{A}^{-1} = \frac{1}{\det(\mathbf{A})} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix}} +$$ + +{{< callout type="info" >}} +Para invertir una matriz \(2 \times 2\), intercambia las entradas diagonales, niega las entradas fuera de la diagonal, y divide todo por el determinante. El determinante aparece en el denominador, exactamente por eso un determinante nulo hace indefinida la inversa (división por cero). +{{< /callout >}} + +Para \(n > 2\), la inversa se calcula en la práctica mediante [**eliminación de Gauss-Jordan**](https://es.wikipedia.org/wiki/Eliminaci%C3%B3n_de_Gauss-Jordan) sobre la matriz aumentada \([\mathbf{A}\,|\,\mathbf{I}]\). + +## Perspectiva de Machine Learning e IA + +Las operaciones matriciales no son meros primitivos computacionales, son el vocabulario conceptual de la investigación moderna en Machine Learning, por ejemplo: + +**Estructura de bajo rango en el ajuste fino**. [Hu et al. (2021)](https://arxiv.org/abs/2106.09685) introdujeron *LoRA (Low-Rank Adaptation)*, que observa que las matrices de actualización de pesos \(\Delta\mathbf{W}\) durante el ajuste fino de grandes modelos de lenguaje son empíricamente de bajo rango. En lugar de almacenar la \(\Delta\mathbf{W} \in \mathbb{R}^{d \times d}\) completa, LoRA la descompone como \(\Delta\mathbf{W} = \mathbf{B}\mathbf{A}\) donde \(\mathbf{B} \in \mathbb{R}^{d \times r}\), \(\mathbf{A} \in \mathbb{R}^{r \times d}\), con \(r \ll d\). Esto es válido precisamente porque una matriz de rango \(r\) tiene una factorización natural en dos matrices delgadas, el concepto de rango que acabamos de ver. LoRA reduce los parámetros entrenables más de 10000 veces en modelos de la escala de GPT-3. + +## Errores comunes y depuración + +1. **Confundir las convenciones de forma entre frameworks**. NumPy usa la convención `(batch, características)`. El `nn.Linear(in_features, out_features)` de PyTorch almacena su matriz de pesos con forma `(out_features, in_features)` y calcula `x @ W.T + b` internamente, por lo que \(\mathbf{W}\) se almacena transpuesta respecto a la convención matemática. Si inicializas pesos manualmente, verifica con una pasada hacia adelante sobre datos ficticios antes de confiar en los gradientes. + +2. **Invertir matrices casi singulares**. `np.linalg.inv()` devuelve un resultado incluso para matrices casi singulares, los números serán astronómicamente grandes y numéricamente sin sentido. Prefiere siempre `np.linalg.solve(A, b)` sobre `np.linalg.inv(A) @ b` para resolver sistemas lineales. Revisa `np.linalg.cond(A)` antes de invertir; los números de condición superiores a \(10^{12}\) son una señal de alerta. + +3. **Usar `det == 0` para detectar singularidad**. En punto flotante, el determinante de una matriz verdaderamente singular casi nunca es exactamente cero,será algún número muy pequeño como `1e-17`. No uses el determinante como prueba de singularidad en el código. En su lugar usa `np.linalg.matrix_rank(A) < n` o `np.linalg.cond(A) > umbral`. + +4. **Asumir que la multiplicación de matrices es conmutativa**. El error algebraico más común al implementar atención desde cero. \(\mathbf{AB} \neq \mathbf{BA}\). Incluso cuando ambos productos están bien definidos y tienen la misma forma (matrices cuadradas), producirán resultados diferentes. Ante la duda, rastrea las formas explícitamente y razona sobre la semántica de cada multiplicación. diff --git a/content/ai/math/algebra/vectors/index.en.md b/content/ai/math/algebra/vectors/index.en.md index 31332e0..d1f97e8 100644 --- a/content/ai/math/algebra/vectors/index.en.md +++ b/content/ai/math/algebra/vectors/index.en.md @@ -6,7 +6,7 @@ authors: description: > Master vectors, scalars & vector spaces from scratch. Step-by-step math derivations, runnable Python code, and research-grade insights for aspiring Machine Learning (ML) scientists. date: 2026-03-06 -tags: ["AI", "Maths", "Algebra", "Vectors"] +tags: ["AI", "Maths", "Algebra", "Linear Algebra", "Vectors", "Scalars", "Vector Spaces"] --- In 2017, researchers at Google Brain published [**Attention Is All You Need**](https://arxiv.org/abs/1706.03762), introducing the Transformer architecture that now underlies GPT-4, Gemini, and virtually every state-of-the-art language model. At the heart of that architecture (and of every neural network, recommendation system, and computer vision model) is a deceptively simple object: the **vector**. @@ -20,13 +20,13 @@ This article builds your working foundation for all of that. By the end, you wil - Reason geometrically about high-dimensional data, a non-negotiable skill for Machine Learning research. - Read a research paper that uses vector notation without losing the thread. -No fluff, let's start. +Let's start. ## Prerequisites Before reading this article, you should be comfortable with: -- **High school algebra:** variables, functions, the coordinate plane. +- **High school algebra**: variables, functions, the coordinate plane. - **Python basics**: lists, loops, functions, importing libraries. - **Basic calculus intuition** (helpful but not required): the idea that a derivative points in the direction of steepest increase. diff --git a/content/ai/math/algebra/vectors/index.es.md b/content/ai/math/algebra/vectors/index.es.md index 6fa98f5..fab1afd 100644 --- a/content/ai/math/algebra/vectors/index.es.md +++ b/content/ai/math/algebra/vectors/index.es.md @@ -6,7 +6,7 @@ authors: description: > Domina vectores y espacios vectoriales para machine learning: intuición geométrica, producto punto, similitud coseno, normas, código NumPy y perspectiva de investigación para científicos en Machine Learning (ML). date: 2026-03-06 -tags: ["AI", "Maths", "Algebra", "Vectors"] +tags: ["IA", "Matemáticas", "Álgebra", "Álgebra Lineal", "Vectores", "Escalares", "Espacio Vectorial"] --- En 2017, investigadores de Google Brain publicaron [**Attention Is All You Need**](https://arxiv.org/abs/1706.03762), el artículo que introdujo la arquitectura Transformer sobre la que hoy se construyen GPT-4, Gemini y prácticamente todos los modelos de lenguaje de vanguardia. En el corazón de esa arquitectura (y de toda red neuronal, sistema de recomendación y modelo de visión por computadora—) vive un objeto engañosamente simple: el **vector**.