# Self-attention wiskundig ontleed: dot-product tot softmax

[Naar de inhoud](#lm-inhoud)Netwerk/NL[EN](/en/)[Hubhub.llmnet.nlModellen vergelijken op taak, taal, kosten en licentie.](https://hub.llmnet.nl/)[Communitycommunity.llmnet.nlPrompttechnieken, patronen en systeemprompts.](https://community.llmnet.nl/)[APIapi.llmnet.nlLLM's robuust in software: rate limits, routing, structured output.](https://api.llmnet.nl/)[Consultancyconsultancy.llmnet.nlAI invoeren in een organisatie, van pilot tot productie.](https://consultancy.llmnet.nl/)[Nieuwsnieuws.llmnet.nlOntwikkelingen in AI, geduid voor Nederland.](https://nieuws.llmnet.nl/)[Benchmarkbenchmark.llmnet.nlZelf meten wat AI-kwaliteit is, voor jouw taken.](https://benchmark.llmnet.nl/)[Vacaturesvacatures.llmnet.nlAI-rollen, salarissen en carrièrepaden in Nederland.](https://vacatures.llmnet.nl/)[Lerenleren.llmnet.nlAI-concepten in gewoon Nederlands, van beginner tot bouwer.](https://leren.llmnet.nl/)[Gidsgids.llmnet.nlAI privé draaien op eigen Mac, pc, NAS of thuisserver.](https://gids.llmnet.nl/)[Directorydirectory.llmnet.nlHet AI-ecosysteem in kaart: tools, modellen, bedrijven.](https://directory.llmnet.nl/)[Radarradar.llmnet.nlSignalen uit X, onderzoek en communities voor indie developers.](https://radar.llmnet.nl/)[Appsapps.llmnet.nlReviews van AI-apps en open-source repo's, met tips voor wie zelf bouwt.](https://apps.llmnet.nl/)[llmnet.nl — hoofdsite](https://llmnet.nl/)[](https://x.com/intent/post?url=https%3A%2F%2Fleren.llmnet.nl%2Fself-attention-wiskundig-ontleed-van-dot-product-naar-softmax&text=Self-attention%20wiskundig%20ontleed%3A%20dot-product%20tot%20softmax)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fleren.llmnet.nl%2Fself-attention-wiskundig-ontleed-van-dot-product-naar-softmax)[](https://www.reddit.com/submit?url=https%3A%2F%2Fleren.llmnet.nl%2Fself-attention-wiskundig-ontleed-van-dot-product-naar-softmax&title=Self-attention%20wiskundig%20ontleed%3A%20dot-product%20tot%20softmax)[](#)[](https://x.com/intent/post?url=https%3A%2F%2Fleren.llmnet.nl%2Fself-attention-wiskundig-ontleed-van-dot-product-naar-softmax&text=Self-attention%20wiskundig%20ontleed%3A%20dot-product%20tot%20softmax)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fleren.llmnet.nl%2Fself-attention-wiskundig-ontleed-van-dot-product-naar-softmax)[](https://www.reddit.com/submit?url=https%3A%2F%2Fleren.llmnet.nl%2Fself-attention-wiskundig-ontleed-van-dot-product-naar-softmax&title=Self-attention%20wiskundig%20ontleed%3A%20dot-product%20tot%20softmax)[](#)

 
# Self-attention wiskundig ontleed: van dot-product naar softmax

 Door Ivo Donker — samengesteld met AI-ondersteuning (Claude & Gemini) · 22 augustus 2026

 Dit is module 5, onder de motorkap. Waar conceptuele artikelen self-attention vaak omschrijven als een zoekmachine waarin tokens naar elkaar kijken, ontleden we in dit artikel de exacte lineaire algebra en matrixbewerkingen achter het mechanisme. We volgen een invoervector van de initiële projecties tot de gewogen sommatie na de softmax-laag.

 
 
### Wat je hiervoor moet weten

 
 
- Lees voor een intuïtieve introductie eerst [hoe het attention-mechanisme conceptueel werkt](https://leren.llmnet.nl/attention-uitgelegd).
 
- Begrijp hoe volgorde-informatie aan vectoren wordt gekoppeld via [de werking van positional encodings](https://leren.llmnet.nl/positional-encoding-uitgelegd).
 
- Basiskennis van matrixvermenigvuldiging, transponeren en vectorruimten is vereist om de afleidingen te volgen.
 
 

 
## 1. De wiskundige basisvergelijking

 De kern van de moderne transformer-architectuur steunt op één compacte matrixformule die in 2017 werd geïntroduceerd: Scaled Dot-Product Attention. In zuivere wiskundige notatie ziet de bewerking er als volgt uit:

 Attention(Q, K, V) = softmax( (Q * K^T) / sqrt(d_k) ) * V

 In deze vergelijking representeren Q (Queries), K (Keys) en V (Values) tweedimensionale matrices die zijn afgeleid van de invoertokens. De scalar d_k staat voor de dimensie van de key-vectoren. Om te begrijpen waarom deze specifieke reeks bewerkingen zorgt voor contextbewuste representaties, moeten we elke term ontbinden in zijn afzonderlijke dimensies en meetkundige betekenis.

 Laten we aannemen dat we een invoersequentie hebben van N tokens. Elk token is gerepresenteerd door een dichte vector met dimensie d_model (bijvoorbeeld 4096 in Llama 3 8B). De complete invoermatrix X heeft dus de dimensie (N, d_model). Voordat er enige interactie tussen tokens plaatsvindt, transformeert het netwerk deze invoer via drie afzonderlijke gewichtsmatrices.

 
## 2. Projectie naar Query-, Key- en Value-ruimten

 Een transformer berekent de onderlinge relaties niet direct op de ruwe invoervectoren X. In plaats daarvan leert het model drie lineaire transformaties om afzonderlijke representaties te construeren voor drie specifieke rollen:

 
 
- Query (Q): Wat zoekt het huidige token in de rest van de zin?
 
- Key (K): Welke eigenschappen biedt dit token aan andere tokens die op zoek zijn naar informatie?
 
- Value (V): Welke feitelijke inhoudelijke informatie draagt dit token over als er een match is?
 

 De transformaties worden uitgevoerd door matrixvermenigvuldigingen met geleerde gewichtsmatrices W_Q, W_K en W_V:

 Q = X * W_Q waarbij W_Q de vorm (d_model, d_k) heeft
K = X * W_K waarbij W_K de vorm (d_model, d_k) heeft
V = X * W_V waarbij W_V de vorm (d_model, d_v) heeft

 In standaard multi-head architecturen geldt vrijwel altijd dat d_k = d_v = d_model / h, waarbij h staat voor het aantal attention heads. Als d_model = 4096 en h = 32, dan is d_k = 128. De resulterende matrices Q, K en V hebben daardoor elk de dimensie (N, d_k).

 
 
 
 
 Matrix | 
 Wiskundige dimensie | 
 Voorbeeld (N=4, d_model=4096, d_k=128) | 
 Functie in het netwerk | 
 

 
 
 
 X | 
 (N, d_model) | 
 (4, 4096) | 
 Ingebedde tokens inclusief positie-informatie | 
 

 
 W_Q, W_K | 
 (d_model, d_k) | 
 (4096, 128) | 
 Projectiegewichten voor zoekvragen en sleutels | 
 

 
 W_V | 
 (d_model, d_v) | 
 (4096, 128) | 
 Projectiegewichten voor de inhoudelijke waarden | 
 

 
 Q, K, V | 
 (N, d_k) | 
 (4, 128) | 
 Geprojecteerde representaties per token | 
 

 
 
 

 
## 3. Het inwendig product (Dot-Product) als affiniteitsmaat

 De volgende stap is het bepalen van de paarsgewijze affiniteit tussen elk token. Dit gebeurt door de query-matrix Q te vermenigvuldigen met de getransponeerde key-matrix K^T:

 S = Q * K^T

 Omdat Q de vorm (N, d_k) heeft en K^T de vorm (d_k, N), is het resultaat een vierkante matrix S met dimensie (N, N). Elk element S_{i,j} in deze matrix representeert het inwendig product (dot-product) tussen de query-vector van token i en de key-vector van token j:

 S_{i,j} = q_i · k_j = som(q_{i,m} * k_{j,m}) voor m = 1 tot d_k

 Meetkundig gezien meet dit inwendig product de richtingsafstemming tussen de twee vectoren in de d_k-dimensionale ruimte. Wijzen twee vectoren in dezelfde richting, dan resulteert dit in een hoge positieve score. Staan ze loodrecht op elkaar, dan is de score exact nul. Wijzen ze in tegengestelde richting, dan ontstaat een negatieve score.

 Laten we een concreet Nederlands voorbeeld bekijken met drie tokens: ["De", "bank", "kraakte"]. Als het token "kraakte" fungeert als query, zoekt zijn vector q_3 naar een onderwerp dat fysiek kan breken. De key-vector k_2 van het polyseme woord "bank" (zitmeubel vs. financiële instelling) heeft in de context van meubilair een hoge overeenkomst met q_3. Het dot-product q_3 · k_2 levert daardoor een aanzienlijk hogere waarde op dan q_3 · k_1 ("De").

 
## 4. Waarom schalen met sqrt(d_k)? De variantie-afleiding

 Een cruciaal onderdeel van de formule is de deling door sqrt(d_k). Zonder deze schaalfactor spreekt men van Dot-Product Attention; met deze factor heet het Scaled Dot-Product Attention. Waarom is deze specifieke wortel noodzakelijk?

 Beschouwen we twee willekeurige vectoren q en k met lengte d_k, waarbij we aannemen dat de individuele componenten onafhankelijke stochastische variabelen zijn met een gemiddelde (verwachtingswaarde) van 0 en een variantie van 1:

 E[q_m] = 0, Var(q_m) = 1
E[k_m] = 0, Var(k_m) = 1

 Het inwendig product is de som van d_k van dergelijke producten: Z = som_{m=1}^{d_k} (q_m * k_m). De verwachtingswaarde van elk product q_m * k_m is 0. Omdat de termen onafhankelijk zijn, mogen we de varianties bij elkaar optellen:

 Var(q_m * k_m) = Var(q_m) * Var(k_m) = 1 * 1 = 1
Var(Z) = Var( som_{m=1}^{d_k} (q_m * k_m) ) = som_{m=1}^{d_k} Var(q_m * k_m) = d_k

 De standaardafwijking van het dot-product Z groeit dus evenredig met sqrt(d_k). Bij een moderne dimensie van d_k = 128 heeft het ongekende dot-product een variantie van 128 en een standaarddeviatie van ongeveer 11,31. Dit betekent dat ruwe scores regelmatig waarden aannemen boven de +25 of onder de -25.

 Wanneer we zulke extreme getallen door een softmax-functie sturen, treedt exponentiële verzadiging op. De grootste waarde krijgt een waarschijnlijkheid van nagenoeg 1,0, terwijl alle andere posities convergeren naar 0,0. In dit verzadigde gebied is de gradiënt (de afgeleide) van de softmax-functie nagenoeg nul (het vanishing gradient probleem). Hierdoor stagneert het trainingsproces via backpropagation volledig. Door te delen door sqrt(d_k) normaliseren we de variantie van de invoer van de softmax terug naar exact 1:

 Var( Z / sqrt(d_k) ) = (1 / d_k) * Var(Z) = (1 / d_k) * d_k = 1

 
## 5. Softmax-normalisatie en numerieke stabiliteit

 De geschaalde affiniteitsscores worden per rij genormaliseerd met behulp van de softmax-functie. Voor elke rij i in de affiniteitsmatrix S' = (Q * K^T) / sqrt(d_k) berekenen we de attention weights A_{i,j}:

 A_{i,j} = exp(S'_{i,j}) / som_{l=1}^N exp(S'_{i,l})

 De matrix A heeft opnieuw de dimensie (N, N). Softmax garandeert twee essentiële wiskundige eigenschappen:

 
 
- Elk gewicht A_{i,j} ligt strikt tussen 0 en 1: 0 <= A_{i,j} <= 1.
 
- De som van alle gewichten in een rij is exact 1: som_{j=1}^N A_{i,j} = 1.
 

 In praktische software-implementaties (zoals PyTorch, CUDA-kernels of C++) kan een directe berekening van exp(x) leiden tot numerieke overflow als x groot is. Daarom gebruikt men universeel de safe softmax truc, waarbij de maximale waarde van de rij eerst van alle elementen wordt afgetrokken voordat de e-macht wordt berekend:

 m_i = max_j (S'_{i,j})
A_{i,j} = exp(S'_{i,j} - m_i) / som_{l=1}^N exp(S'_{i,l} - m_i)

 Omdat exp(a - c) / exp(b - c) = exp(a) / exp(b) verandert deze aftrekking de wiskundige uitkomst niet, maar het voorkomt dat tussenresultaten in floating-point representatie (zoals FP16 of BF16) veranderen in +Infinity of NaN.

 
## 6. Gewogen sommatie van de Value-vectoren

 Nadat de gewichtenmatrix A met dimensie (N, N) is berekend, volgt de laatste vermenigvuldiging met de Value-matrix V met dimensie (N, d_v):

 Output = A * V

 Het resultaat is een matrix van vorm (N, d_v). Voor elk afzonderlijk token i is de uiteindelijke representatie een gewogen lineaire combinatie van alle value-vectoren in de sequentie:

 Output_i = som_{j=1}^N (A_{i,j} * v_j)

 Hier zien we de mechanische synthese van context: als token 1 ("kraakte") een hoge attention score A_{1,2} = 0.85 toekent aan token 2 ("bank"), dan bestaat 85% van de resulterende vector voor token 1 uit de eigenschappen die zijn opgeslagen in de value-vector v_2. Het token heeft zijn eigen representatie verrijkt met informatie van zijn contextuele buren.

 
## 7. Causale maskering bij autoregressieve decoders

 In decoder-only architecturen zoals GPT-4, Llama of Claude mag een token tijdens het genereren niet vooruitkijken naar toekomstige tokens. Een model dat het vierde woord voorspelt, mag alleen aandacht schenken aan posities 1, 2 en 3.

 Wiskundig wordt dit opgelost door vóór de softmax-stap een maskeringsmatrix M toe te voegen aan de affiniteitsmatrix S':

 S'_{masked} = S' + M

 Waarbij het masker M als volgt is gedefinieerd:

 M_{i,j} = 0 voor j <= i (huidige en eerdere tokens)
M_{i,j} = -inf voor j > i (toekomstige tokens)

 Omdat exp(-inf) = 0, resulteert de softmax-bewerking voor alle toekomstige posities j > i in een attention weight van exact 0. De gradienten vloeien tijdens de backpropagation eveneens niet terug via gemaskeerde posities. In systemen die inference uitvoeren, stelt dit mechanisme ons in staat om eerdere sleutels en waarden te cachen; zie hiervoor [hoe de opbouw van KV-caching in transformer-architecturen](https://leren.llmnet.nl/kv-caching-opbouw) voorkomt dat eerdere tokens telkens opnieuw berekend moeten worden.

 
## 8. Een compleet numeriek stap-voor-stap voorbeeld

 Om alle stappen samen te zien, werken we een minimalistisch voorbeeld door met N = 2 tokens en een dimensie d_k = 2.

 Stel dat de geprojecteerde matrices Q, K en V na transformatie de volgende waarden bevatten:

 Q = [ [1.0, 0.0], K = [ [1.0, 1.0], V = [ [2.0, 0.0],
 [0.0, 2.0] ] [0.0, 1.0] ] [1.0, 3.0] ]

 Stap 1: Matrixvermenigvuldiging Q * K^T

 K^T = [ [1.0, 0.0],
 [1.0, 1.0] ]

Q * K^T = [ [1.0*1.0 + 0.0*1.0, 1.0*0.0 + 0.0*1.0],
 [0.0*1.0 + 2.0*1.0, 0.0*0.0 + 2.0*1.0] ]
 = [ [1.0, 0.0],
 [2.0, 2.0] ]

 Stap 2: Schalen met sqrt(d_k) = sqrt(2) ≈ 1.4142

 S' = (Q * K^T) / 1.4142
 = [ [0.7071, 0.0000],
 [1.4142, 1.4142] ]

 Stap 3: Softmax per rij

 Voor rij 1: exp(0.7071) ≈ 2.0281, exp(0.0) = 1.0000. Som = 3.0281.

 A_{1,1} = 2.0281 / 3.0281 ≈ 0.670
A_{1,2} = 1.0000 / 3.0281 ≈ 0.330

 Voor rij 2: exp(1.4142) ≈ 4.1132, exp(1.4142) ≈ 4.1132. Som = 8.2264.

 A_{2,1} = 4.1132 / 8.2264 = 0.500
A_{2,2} = 4.1132 / 8.2264 = 0.500

A = [ [0.670, 0.330],
 [0.500, 0.500] ]

 Stap 4: Vermenigvuldiging met V

 Output = A * V
Output_1 = 0.670 * [2.0, 0.0] + 0.330 * [1.0, 3.0] = [1.340 + 0.330, 0.000 + 0.990] = [1.670, 0.990]
Output_2 = 0.500 * [2.0, 0.0] + 0.500 * [1.0, 3.0] = [1.000 + 0.500, 0.000 + 1.500] = [1.500, 1.500]

Output = [ [1.670, 0.990],
 [1.500, 1.500] ]

 
## 9. Multi-Head Attention: parallellisatie en projectie

 In plaats van één grote attention-berekening uit te voeren met dimensie d_model, splitst Multi-Head Attention (MHA) de representatie over h onafhankelijke koppen. Elke kop berekent zijn eigen aandachtsverdeling in een lagere dimensie d_k = d_model / h:

 head_i = Attention(Q * W_Q^i, K * W_K^i, V * W_V^i)
MultiHead(Q, K, V) = Concat(head_1, head_2, ..., head_h) * W_O

 De concatenatie plakt de h matrices van vorm (N, d_v) naast elkaar tot één matrix van vorm (N, h * d_v) = (N, d_model). Vervolgens zorgt de output-projectiematrix W_O (met dimensie (d_model, d_model)) voor een lineaire menging van alle koppen.

 Waarom is dit wiskundig superieur aan één enkele kop? Met één kop kan een token zijn aandacht slechts richten volgens één distributie. Met 32 of 64 koppen kan kop 1 zich richten op grammaticale afhankelijkheden (werkwoord-onderwerp relaties), kop 2 op anaforen ("hij" verwijst naar "de minister"), en kop 3 op semantische clustering.

 
## 10. Computationele complexiteit en geheugenknelpunten

 De computationele en geheugencomplexiteit van standaard self-attention vormt het grootste infrastructurele knelpunt van grote taalmodellen. Laten we de complexiteit analyseren in termen van FLOPs en geheugengebruik:

 
 
- Matrixvermenigvuldiging Q * K^T: Vereist 2 * N^2 * d_k bewerkingen.
 
- Softmax en opslag van affiniteiten: Heeft een tijd- en geheugencomplexiteit van O(N^2).
 
- Matrixvermenigvuldiging A * V: Vereist 2 * N^2 * d_v bewerkingen.
 

 Voor een contextlengte van N = 2.048 tokens bevat de A matrix circa 4,19 miljoen elementen per kop per laag. Bij een context van N = 128.000 tokens explodeert dit naar 16,38 miljard elementen per laag. Zonder optimalisaties leidt dit tot geheugentekorten op GPU's (OOM).

 Om deze kwadratische bottleneck in de praktijk te doorbreken, maakt moderne hardware gebruik van gespecialiseerde algoritmen; zie hoe [FlashAttention berekeningen versnelt via slim GPU-geheugenbeheer](https://leren.llmnet.nl/flashattention-ontleed-snellere-berekening-via-gpu-geheugen) door middel van online softmax en tiling. Daarnaast worden technieken op inferentieniveau ingezet om de algehele latentie te drukken; bekijk bijvoorbeeld de ontwikkelingen rondom [versnelling van inferentie via speculatieve decoding](https://nieuws.llmnet.nl/speculative-decoding-versnelling-van-llm-inferentie).

 
 
### Hierna verder met

 
 
- Verdiep je in geheugenoptimalisatie op architectuurniveau via [grouped-query attention en geheugenbesparing](https://leren.llmnet.nl/grouped-query-attention-uitgelegd).
 
- Ontdek hoe hardware-implementaties de computationele bottleneck aanpakken in [de diepgaande analyse van FlashAttention](https://leren.llmnet.nl/flashattention-ontleed-snellere-berekening-via-gpu-geheugen).
