Skip to main content

Command Palette

Search for a command to run...

How Matrix Multiplication Powers Face Recognition, ChatGPT & Self-Driving Cars

Updated
•24 min read•View as Markdown
How Matrix Multiplication Powers Face Recognition, ChatGPT & Self-Driving Cars

Try this for a second. Close your eyes, and have someone toss a small ball gently towards you. Try to catch it.

Somehow, without doing any conscious "calculation," your brain combined information from your eyes (where is the ball, how fast is it moving), your inner ear (which way is up, are you balanced), and your memory of every ball you've ever caught before — and blended all of that into one single decision: move your hand exactly here, exactly now.

One important thing happened here. Your brain did not treat every piece of information the same. For example, if the lighting was poor, your brain trusted what your eyes saw a little less. At the same time, it relied more on what it already knew from past experience, like how balls usually fall. Instead of simply adding all the information together, your brain gave more importance to the signals it trusted the most in that moment. Then it combined those signals to make one final decision.

That exact idea — take several pieces of information, give each one an importance ("weight"), and combine them into one new answer — is the single most important mathematical operation in all of Machine Learning. It's called matrix multiplication, and once you genuinely understand it, you'll start seeing it everywhere: in how your phone recognizes your face, in how Google Translate decides which words matter most in a sentence, and in literally every layer of every neural network ever built, including the one powering ChatGPT.

In the last blog, we learned addition, subtraction, and a "spotlight-style" multiplication that only ever compares matching positions, one at a time, never letting numbers from different rows or columns mix together. Today, we're breaking that limit completely. Get ready — this is the operation everything else in Machine Learning is quietly built on top of.

By the end of this blog, you will understand:

  • What a dot product is, explained with tiny numbers, before we touch a matrix at all

  • What matrix multiplication actually does, step by step, by hand

  • Exactly how it's different from the "spotlight" element-wise multiplication from last time — and why mixing the two up breaks real projects

  • What transpose is, and why you'll type .T constantly to make matrix multiplication even possible

  • What cross product is, and where it quietly makes AR filters and 3D graphics look realistic

  • Real, specific, low-level examples from face recognition, translation apps, and camera filters

Take your time with this one. Everything from here on in the entire Machine Learning world is built on this idea.


Part 1: Understanding "Dot Product" First (Before Matrices, With Tiny Numbers)

Let's not jump straight into matrices. Let's understand the tiny building block first, using an example you can genuinely picture.

Imagine you're a school teacher grading a student's final score for the term. There were three tests, and each one counts for a different amount towards the final grade:

Test Student's score (out of 100) How much this test counts (its "weight")
Test 1 80 0.2 (worth 20% of the final grade)
Test 2 90 0.3 (worth 30% of the final grade)
Test 3 70 0.5 (worth 50% of the final grade)

To find the final grade, you don't just average the three scores equally. You multiply each score by its own weight, and then add up all three results:

final_grade = (80 × 0.2) + (90 × 0.3) + (70 × 0.5)
final_grade = 16 + 27 + 35
final_grade = 78

That's it. That entire process — multiply matching pairs of numbers, then add up all the results into one single number — is called a dot product. It's the single most repeated tiny calculation in the whole of Machine Learning, and you just did it by hand, using nothing more complicated than a school report card.

Here's the important realization: matrix multiplication is nothing but doing this exact dot-product calculation, over and over, for every row of one matrix against every column of another. If you understood the report card example above, you already understand matrix multiplication. You just haven't seen it dressed up in matrix notation yet. Let's fix that now.


Part 2: Matrix Multiplication — Weighing and Combining, at Scale

Setting Up the Idea

Let's slightly extend the report card example. Imagine now you're not grading one student — you're grading three students at once, and there are two different "final grade formulas" you want to apply to all of them (say, one formula for an overall grade, and one formula for a "college readiness" score, each weighing the three tests differently).

Instead of writing out the same calculation nine separate times by hand (3 students × essentially each getting graded against 2 formulas is actually going to give us 3×2 = 6 answers, but let's build it properly), we organize this into two grids:

Students' scores (3 students, 3 tests each):

           Test1   Test2   Test3
Student1     80      90      70
Student2     60      75      95
Student3     85      65      80


Weight formulas (3 tests, 2 formulas):

           Formula1(Overall)   Formula2(College-Readiness)
Test1              0.2                    0.4
Test2              0.3                    0.1
Test3              0.5                    0.5

Notice something already: the "scores" grid has 3 columns (one per test), and the "weights" grid has 3 rows (also one per test). They match up — 3 and 3. This is not a coincidence, and remembering this exact detail is the single most important rule of matrix multiplication.

To multiply matrix A by matrix B, the number of columns in A must equal the number of rows in B.

A: (3 students  x  3 tests)      B: (3 tests  x  2 formulas)
                       └────┬────┘
                these must match

Result shape: (3 students  x  2 formulas)

If they don't match — say, if your scores grid had 3 tests but your weights grid only had data for 2 tests — the multiplication is not just "wrong." It's genuinely undefined. There's no meaningful way to do it, because there'd be a test with no weight to pair up with. NumPy, sensibly, will refuse to run it and give you an error instead of a wrong answer.

Doing It By Hand, Fully, One Cell at a Time

Let's compute Student 1's Overall grade (Formula 1) by hand, using exactly the dot-product idea from Part 1.

Student 1's row: 80, 90, 70 Formula 1's column: 0.2, 0.3, 0.5

(80 × 0.2) + (90 × 0.3) + (70 × 0.5)
= 16 + 27 + 35
= 78

Now Student 1's College-Readiness grade (Formula 2), using the same row, but the other column this time:

Student 1's row: 80, 90, 70 Formula 2's column: 0.4, 0.1, 0.5

(80 × 0.4) + (90 × 0.1) + (70 × 0.5)
= 32 + 9 + 35
= 76

Notice: Student 1's row got reused twice — once against each column. That's exactly how matrix multiplication works. Every row from the first matrix gets multiplied, dot-product style, against every column of the second matrix, one pairing at a time.

If we did this for all 3 students against both formulas, we'd end up with a brand new grid — 3 rows (one per student), 2 columns (one per formula):

Result =    78    76
            ...   ...
            ...   ...

(We've only fully worked out the first row here by hand, purely to keep this section readable — but the process for Student 2 and Student 3 is identical: take their row, pair it against each column, dot-product style.)

The General Rule, Written Simply

result[row][column] = sum over every test of ( scores[row][test] × weights[test][column] )

Or, in the more common notation you'll see in textbooks and code:

result[i][j] = sum over k of  A[i][k] × B[k][j]

Don't be scared by the letters i, j, k — they're just labels. i means "which row we're currently building," j means "which column we're currently building," and k is the counter that walks along the row and down the column at the same time, multiplying matching pairs and adding them up — exactly like our report card dot product.

Now, the Python Code

import numpy as np

x = np.random.randn(3, 6)   # imagine: 3 rows, 6 columns
y = np.random.randn(6, 4)   # imagine: 6 rows, 4 columns — notice 6 matches 6!

result = np.zeros((3, 4))   # the result will be 3 rows, 4 columns

for i in range(len(x)):              # walk through every row of x
    for j in range(len(y[0])):       # walk through every column of y
        for k in range(len(y)):      # walk along the row of x, and down the column of y, together
            result[i, j] += x[i, k] * y[k, j]

print(result)

Notice this code needs three nested loops, not two like addition and subtraction needed. That's a strong, honest signal that this operation is doing meaningfully more work — for every single answer in the result grid, it's now doing an entire dot-product calculation (multiply several pairs, then add them all up), not just one lonely multiplication like element-wise multiplication did.

The line result[i, j] += x[i, k] * y[k, j] is worth reading slowly. The += symbol means "add this new amount to whatever is already in result[i, j], don't overwrite it." So as k counts up (0, then 1, then 2, and so on), we keep multiplying the next pair and adding it onto our running total — exactly the way we manually added 16 + 27 + 35 in our report card example.

The Shortcut Version

print(np.dot(x, y))
print(np.matmul(x, y))

Both give the exact same answer. In most real projects, you'll see either np.matmul(x, y), or simply x @ y — the @ symbol is Python's shorthand specifically for real matrix multiplication, precisely so it never gets confused with the plain * symbol, which (as you learned last blog) means something completely different.

The Comparison You Need Tattooed on Your Brain

This is, genuinely, one of the single most common beginner mistakes in the entire field. Let's make sure it never trips you up.

Element-wise multiplication (A * B) Matrix multiplication (A @ B, np.matmul, np.dot)
Shapes required Both matrices must be the exact same size Columns of A must equal rows of B — sizes can otherwise be totally different
What happens for one answer One number times one number, same position, nothing else involved An entire row multiplied against an entire column, then all those pairs are added up
Size of the result Same size as the original matrices Rows of A by columns of B — often a completely different shape than either original matrix
The "story" behind it "Keep this position, or wipe it out" — like a spotlight or a stencil "Weigh up many pieces of information and combine them into something new" — like a final grade, or a decision
Everyday examples Instagram filters, video call background masks, hiding "future" words during translation Face recognition comparisons, neural network layers, translation model attention, self-driving car sensor fusion

If you remember only one sentence from this entire blog, make it this one:

Element-wise multiplication decides what survives, position by position. Matrix multiplication creates something genuinely new, by weighing and combining lots of numbers into one.


Part 3: Where Matrix Multiplication Actually Shows Up (Real, Concrete Examples)

1. Face recognition — comparing "faceprints" (Computer Vision)

Here's something that will probably surprise you. Modern face recognition systems (the kind used in Face ID, or in airport security gates) don't actually compare photos pixel by pixel. Instead, they first convert your face into something called an embedding — a list of, say, 128 numbers that captures the "essence" of your face (things like the general shape of your jawline, the spacing of your eyes, and hundreds of other subtle patterns no human could easily describe in words).

To check "does this new face match the owner's registered face," the system needs to measure how similar two of these 128-number lists are. It does this using a calculation built directly on the dot product you learned in Part 1 — essentially matrix multiplication between these embedding lists. A high similarity score (a big combined number) means "these are very likely the same face." A low score means "these are likely two different people."

Here's the number that should genuinely surprise you: your phone runs this exact comparison — a dot product across 128 numbers — in a tiny fraction of a second, and it does it every single time you glance at your phone to unlock it. That's matrix multiplication, quietly guarding your phone, dozens of times a day.

2. Self-driving cars combining and reasoning about sensor readings

In the last blog, we saw self-driving cars adding sensor readings together to reinforce weak signals. But real systems go further — they don't trust every sensor equally in every situation. A radar sensor might be far more reliable in heavy rain than a camera, but a camera is far more reliable for reading actual road signs. The car's software learns (again, "learns" — a topic for later blogs, don't worry about it yet) how much to weigh each sensor's input in different conditions, and combines all these weighted readings using matrix multiplication — the exact same "report card" idea from Part 1, just with sensor readings instead of test scores, and "trust levels" instead of grading weights.

3. Google Translate and Transformers — deciding "which words matter to which" (NLP)

This is genuinely one of the most important real-world uses of matrix multiplication in existence today, so let's slow right down.

When a modern translation model (or ChatGPT, or any similar "Transformer" model — we'll dedicate a proper future blog to fully unpacking this name) processes the sentence "The cat sat on the mat because it was tired," it needs to figure out something tricky: does the word "it" refer to "the cat" or "the mat"?

To figure this out, every word in the sentence is converted into two different lists of numbers, called a Query and a Key (again — don't worry about memorizing these names right now, just follow the idea). Roughly speaking, the "Query" for the word "it" gets compared against the "Key" for every other word in the sentence, using — you guessed it — matrix multiplication. Words that are more relevant to "it" (like "cat," because cats get tired, unlike mats) end up with a higher combined number, meaning the model should pay more "attention" to that word when deciding what "it" means.

This process is genuinely called "attention" in the Transformer architecture, and it is, at its mathematical core, exactly the matrix multiplication you learned to do by hand in Part 2 of this blog — just done for every word against every other word, for every sentence, at a staggering scale.

Here's the number that should genuinely shock you. A single, ordinary sentence being translated can involve millions of these tiny multiply-and-add calculations, happening across enormous grids of numbers, and modern translation apps still return your translated sentence to you in under a second. Every single "instant" translation you've ever gotten on your phone secretly involved a scale of arithmetic that would take a human with a calculator, working non-stop, an entire lifetime to complete by hand.


Part 4: Transpose — Flipping the Table on Its Side

The Problem That Forces This Idea to Exist

Here's a very real, very common situation you'll run into the moment you start actually building things.

Remember our attention example above — comparing a word's "Query" against every other word's "Key"? Let's say each word's Query and Key are stored as a list of, say, 4 numbers each. If you have 6 words in your sentence, your Query grid is (6 rows, 4 columns), and your Key grid is also (6 rows, 4 columns).

Now try to apply our golden rule: to multiply Query by Key, the columns of Query (which is 4) must match the rows of Key (which is 6). They don't match — 4 and 6 are different numbers. Multiplication is blocked, even though we desperately need this comparison to happen.

The fix isn't to change your actual data. The fix is to flip one of the grids on its side — turn every row into a column, and every column into a row. A (6, 4) grid, flipped this way, becomes a (4, 6) grid. Now, suddenly, columns of Query (4) match rows of the flipped Key (4). Multiplication becomes possible, and it gives us exactly the "who should pay attention to whom" comparison we needed.

This flipping operation is called transpose.

The Rule

If A has shape (rows, columns), then A transpose (written Aᵀ) has shape (columns, rows)
Aᵀ[column][row] = A[row][column]

In plain English: whatever number used to be at row 2, column 5 is now sitting at row 5, column 2. Every number keeps its exact value — only its position changes.

Doing It By Hand

Matrix A (2 rows, 3 columns) =

    1    2    3
    4    5    6

Transposing it flips rows into columns. The first row (1, 2, 3) becomes the first column. The second row (4, 5, 6) becomes the second column.

Matrix Aᵀ (3 rows, 2 columns) =

    1    4
    2    5
    3    6

Nothing was calculated. Nothing was added or multiplied. We simply re-arranged the same exact numbers into a new orientation.

Python Code

import numpy as np

mat_A = np.random.randn(12, 4)

# transpose — the manual, honest way
mat_A_T = np.zeros((4, 12))
for i in range(mat_A.shape[0]):
    for j in range(mat_A.shape[1]):
        mat_A_T[j, i] = mat_A[i, j]

print(mat_A_T)
# the shortcut
print(mat_A.T)

# proving both give exactly the same result
print((mat_A.T == mat_A_T).all())
# True

Notice the very simple pattern in the manual loop: we're just placing mat_A[i, j] into the opposite position, mat_A_T[j, i]. Row and column literally swap places for every single number.

Where Transpose Actually Shows Up (Real, Concrete Examples)

1. Making the Query and Key comparison in Transformers actually possible (NLP)

Exactly as described above — nearly every "attention" calculation inside translation apps and chatbots involves transposing the Key grid before multiplying it against the Query grid, purely to make the shapes line up correctly. Without transpose, this entire mechanism — arguably the single biggest breakthrough behind modern AI language tools — simply couldn't be computed.

2. Comparing two faces' embeddings the right way round (Computer Vision)

When comparing one face's 128-number embedding against a database of thousands of other registered faces (say, at an airport immigration gate), the incoming face's embedding often needs to be transposed so its shape correctly lines up against the entire stored database grid, letting one single matrix multiplication compare the new face against every stored face at once, instead of one at a time in a slow loop.

3. Rotating and repositioning objects in photo and video editing apps

When an app rotates or repositions a detected object (say, straightening a tilted photo, or repositioning a detected face for a filter), the underlying coordinate grids describing "where is every point of this object" frequently need to be transposed at some stage, purely to keep the maths of the rotation lined up correctly with the multiplication being applied.

Transpose never changes your actual data or its meaning. It only changes the orientation you're looking at it from — but as you can see above, that one small change is very often the exact difference between a calculation that's possible, and one that simply cannot run at all.


Part 5: Cross Product — A Strange, Special Kind of Multiplication, Just for 3D

The Story

Everything we've covered so far takes numbers and combines them into other numbers. Cross product does something genuinely different, and honestly, a little strange the first time you meet it — it takes two arrows (vectors) pointing in 3D space, and produces a brand new arrow, pointing in a completely different direction, one that is perfectly perpendicular (at a right angle) to both of the original two.

Here's a low-level example that should make this click immediately: think about how AR face filters (the kind Snapchat and Instagram use to put digital sunglasses, animal ears, or makeup onto your real face) manage to make the digital object look like it's genuinely sitting on your face, with lighting that matches the real room you're in.

Your face, inside these apps, gets mapped as a mesh made of tiny triangles (imagine covering your whole face with hundreds of tiny flat triangular patches). For the lighting on a digital pair of sunglasses to look convincing — brighter where a window's light hits it, darker in shadowed areas — the app needs to know, for every single tiny triangle, which direction that triangle is "facing." This facing direction is called a surface normal, and it is calculated, for every one of those hundreds of triangles, using cross product — taking two edges of the triangle (each one a simple 3D arrow) and finding the one new arrow that points straight out of the triangle's face.

Get this right for hundreds of tiny triangles, dozens of times a second, and a flat digital object convincingly looks like it's really sitting on your real, three-dimensional face, lit by your real room. Get it wrong, and the filter looks flat, fake, and oddly lit — exactly the "uncanny" look you've probably noticed in a cheap or badly-made filter.

The Rule

For two 3D vectors A and B (each one simply a list of 3 numbers, representing a direction and length in 3D space):

cross_product[0] = A[1]×B[2] − B[1]×A[2]
cross_product[1] = A[2]×B[0] − B[2]×A[0]
cross_product[2] = A[0]×B[1] − B[0]×A[1]

Don't worry about memorizing this formula by heart — almost nobody in industry does it by hand. What matters is understanding what it produces: one new arrow, always perfectly perpendicular to both of the arrows you started with. This only really makes sense in 3D, which is why cross product only applies to 3D vectors — it's a fundamentally geometric idea about physical space, not a general-purpose way to combine any kind of data, unlike everything else in this series so far.

Python Code

import numpy as np

A = np.array([[1], [2], [3]])
B = np.array([[4], [5], [6]])

cross_product = np.zeros((3, 1))

for i in range(A.shape[0]):
    if i == A.shape[0] - 1:
        cross_product[i] = (A[i] * B[0]) - (B[i] * A[0])
    else:
        cross_product[i] = (A[i] * B[i + 1]) - (B[i] * A[i + 1])

print(cross_product)
[[-3.]
 [-3.]
 [ 6.]]

You can double-check this using NumPy's built-in shortcut: np.cross(A.flatten(), B.flatten()) gives you the exact same result.

Where Cross Product Actually Shows Up (Real, Concrete Examples)

Let's be genuinely honest here — this is the one operation in the whole series that's less common in "everyday" Machine Learning (like recommendation systems or basic classification), but it becomes essential the moment your work touches anything physical or visual in three dimensions.

Use case What cross product does there
AR/VR face filters and 3D games Calculates which direction each tiny surface triangle faces, so lighting on digital objects looks realistic
Self-driving cars reading road surfaces (LIDAR processing) Helps determine the tilt and orientation of the road surface from a cloud of distance measurements, so the car understands slopes, bumps, and curves correctly
Robotics (robot arms, drones) Calculates rotation direction and torque — essentially, "which way should this joint twist"
Pose estimation apps (fitness apps that track your form, like a squat-counter app) Helps determine the exact 3D orientation of your limbs and joints from camera data, checking your form against a correct posture

If you're building a chatbot, a spam filter, or a basic recommendation system, you may genuinely never write np.cross yourself. But the instant your work touches a camera capturing the real 3D world, cross product is very likely quietly running underneath, deciding which way things are facing.


Part 6: Everything From This Blog, Side by Side

Operation Input shapes Output shape The one-line idea
Element-wise multiplication Same shape required Same shape Keep or wipe out, position by position
Matrix multiplication Columns of A = rows of B Rows of A by columns of B Weigh and combine many numbers into something new
Transpose Any shape (rows, columns) (columns, rows) Flip orientation, no data lost or changed
Cross product Two 3D vectors (lists of 3 numbers) One new 3D vector Find a fresh direction, perpendicular to both original ones

Part 7: Why This Should Genuinely Impress You

Go back to the ball-catching example from the very start of this blog. Your brain, in real time, combined visual information, balance information, and years of memory, and it weighed each of these differently depending on the situation — trusting your eyes more in good light, trusting muscle memory more in the dark.

We now know, in cold, precise mathematical terms, exactly how a computer can be made to do something structurally similar: multiply each piece of information by how much it should be trusted (its "weight"), and add all those weighted pieces together — a dot product, repeated across an entire grid, which is exactly what matrix multiplication is.

Here is the genuinely humbling part, worth sitting with for a moment. Every time you glance at a friend's face across a room and instantly know who they are, or catch a word someone says despite background noise, or reach out and catch a tossed ball without thinking — your brain is running a process that, mathematically, resembles millions of these dot-product-style weighings, happening through biological neurons instead of numbers in a grid, in a fraction of a second, using less power than a dim lightbulb.

The version we've built out of matrix multiplication — the one running inside your phone's Face ID, inside Google Translate, inside a self-driving car's cameras — needs enormous, purpose-built chips, consuming meaningfully more electricity, just to imitate a small sliver of what your brain does constantly, quietly, without you ever noticing the "calculation" happening at all. Understanding this math doesn't just help you build Machine Learning systems. It genuinely gives you a small window into just how extraordinary your own brain's ordinary, everyday moments really are.


What's Coming Next

You now know how to combine matrices, weigh and merge them through real matrix multiplication, reorient them with transpose, and even find fresh directions in 3D space with cross product. But there's a question we've been quietly avoiding this entire series, and it's finally time to answer it:

When you multiply a vector by a matrix, what actually happens to that vector — geometrically? Does it move? Does it get squashed? Can you always get back to where you started?

It turns out every single matrix multiplication is secretly moving your data — stretching it, rotating it, sometimes even squashing it flat and destroying information permanently. That idea is called a linear transformation, and understanding it is what finally makes concepts like "the model is learning a representation" or "PCA reduces dimensions" click into place, intuitively, instead of just being phrases you nod along to.

To fully understand linear transformation properly, we need two more tools first: the determinant, which tells you whether a transformation destroys information forever, and the matrix inverse, which tells you exactly how to undo a transformation, if it can be undone at all.

That's exactly where the next blog picks up — and I promise, it's going to make the phrase "the model is learning" finally make real sense.

See you there.