LSTM-cel: input-, forget- en outputgates
Cursisten brengen de LSTM-cel in kaart, volgen de informatiestroom door elke gate en implementeren een LSTM-tekstclassifier met nn.LSTM.
LSTM-cel: input-, forget- en outputgates is een gratis Machine Learning Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Machine Learning Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Machine Learning Academy bevat in totaal 4 lessen.
Waarom RNN's poortmechanismen nodig hebben
Standaard-RNN's hebben moeite met afhankelijkheden over lange afstanden, omdat gradiënten verdwijnen tijdens backpropagation door de tijd. De verborgen toestand h_t = tanh(W_h * h_{t-1} + W_x * x_t) overschrijft de vorige context bij elke nieuwe invoer, waardoor het netwerk informatie van veel eerdere stappen vergeet.
Long Short-Term Memory (LSTM) werd in 1997 door Hochreiter en Schmidhuber ontworpen om dit probleem op te lossen. Het introduceert een celtoestand — een afzonderlijke transportband voor geheugen — naast poortmechanismen die expliciet bepalen welke informatie wordt toegevoegd, verwijderd of doorgegeven.
Het concept van de LSTM-celtoestand
De LSTM heeft twee interne toestanden: de celtoestand C_t en de verborgen toestand h_t. De celtoestand loopt als een transportband door de volledige sequentie, waarbij poorten kleine lineaire interacties aansturen. Hierdoor kunnen gradiënten gemakkelijker door de tijd stromen.
De verborgen toestand h_t is de uitvoer bij elke tijdstap en wordt berekend vanuit de celtoestand. Zie C_t als langetermijngeheugen en h_t als werkgeheugen dat aan de volgende laag wordt doorgegeven en als uitvoer wordt teruggegeven.
import torch
import torch.nn as nn
# An LSTM processes sequences and returns (output, (h_n, c_n))
lstm = nn.LSTM(input_size=10, hidden_size=32, batch_first=True)
print('LSTM parameters:', sum(p.numel() for p in lstm.parameters()))De vergeetpoort
De vergeetpoort is de eerste poort waar de invoer doorheen gaat. Deze leest de vorige verborgen toestand h_{t-1} en de huidige invoer x_t en produceert voor elk element in de celtoestand een waarde tussen 0 en 1.
Een waarde van 1 betekent 'alles behouden', terwijl 0 betekent 'volledig vergeten'. De formule is: f_t = sigmoid(W_f · [h_{t-1}, x_t] + b_f). Bij het verwerken van een nieuwe zin in een NLP-taak zou de vergeetpoort bijvoorbeeld alle opgeslagen informatie over het onderwerp uit de vorige zin wissen.
import torch
import torch.nn as nn
# Manual forget gate illustration
batch_size, hidden_size, input_size = 1, 4, 3
h_prev = torch.zeros(batch_size, hidden_size)
x_t = torch.randn(batch_size, input_size)
W_f = torch.randn(hidden_size, hidden_size + input_size)
b_f = torch.zeros(hidden_size)
combined = torch.cat([h_prev, x_t], dim=1)
f_t = torch.sigmoid(combined @ W_f.T + b_f)
print('Forget gate output:', f_t) # Values between 0 and 1De invoerpoort en de kandidaat-cel
De invoerpoort bepaalt welke nieuwe waarden in de celtoestand worden opgeslagen. De poort bestaat uit twee samenwerkende onderdelen: de invoerpoort i_t = sigmoid(W_i · [h_{t-1}, x_t] + b_i) bepaalt hoeveel er wordt bijgewerkt, en de kandidaatcel g_t = tanh(W_g · [h_{t-1}, x_t] + b_g) maakt kandidaatwaarden die eventueel kunnen worden toegevoegd.
De sigmoid-functie regelt de poort (0 = gesloten, 1 = open), terwijl tanh waarden in het bereik [-1, 1] maakt. De nieuwe informatie die aan de celtoestand wordt toegevoegd, is i_t * g_t — de door de kandidaatwaarden gefilterde poortwaarde.
# Input gate and candidate values
W_i = torch.randn(hidden_size, hidden_size + input_size)
b_i = torch.zeros(hidden_size)
W_g = torch.randn(hidden_size, hidden_size + input_size)
b_g = torch.zeros(hidden_size)
i_t = torch.sigmoid(combined @ W_i.T + b_i) # Input gate: what to update
g_t = torch.tanh(combined @ W_g.T + b_g) # Candidate values to add
print('Input gate:', i_t.detach())
print('Candidate cell:', g_t.detach())De celtoestand bijwerken
Nu we de vergeetpoort f_t, invoerpoort i_t en kandidaatcel g_t hebben, is het bijwerken van de celtoestand eenvoudig: C_t = f_t * C_{t-1} + i_t * g_t.
De eerste term f_t * C_{t-1} past de vergeetpoort toe — hiermee wordt selectief informatie uit de vorige celtoestand gewist. De tweede term i_t * g_t voegt selectief nieuwe informatie toe. Dankzij deze optelstructuur kunnen gradiënten door veel tijdstappen terugstromen zonder te verdwijnen, omdat de gradiënt rechtstreeks door de optelbewerking stroomt.
# Update cell state
C_prev = torch.zeros(batch_size, hidden_size) # Previous cell state
C_t = f_t * C_prev + i_t * g_t # Element-wise operations
print('Updated cell state C_t:', C_t.detach())
# The additive update is key: gradients flow through + easily
# Compare to vanilla RNN: h_t = tanh(W * h_{t-1} + U * x_t)
# where gradients must flow through the tanh compression each stepDe uitvoerpoort
De uitvoerpoort bepaalt welk deel van de celtoestand als uitvoer van de verborgen toestand h_t zichtbaar wordt. Eerst bepaalt de uitvoerpoort welke delen van de celtoestand worden uitgevoerd: o_t = sigmoid(W_o · [h_{t-1}, x_t] + b_o).
Vervolgens wordt de celtoestand door tanh gehaald (om waarden tussen -1 en 1 te brengen) en vermenigvuldigd met de uitvoerpoort: h_t = o_t * tanh(C_t). De verborgen toestand h_t dient zowel als uitvoer bij deze tijdstap als als invoer voor de volgende LSTM-stap, samen met de nieuwe celtoestand.
# Output gate and hidden state
W_o = torch.randn(hidden_size, hidden_size + input_size)
b_o = torch.zeros(hidden_size)
o_t = torch.sigmoid(combined @ W_o.T + b_o) # Output gate
h_t = o_t * torch.tanh(C_t) # New hidden state
print('Output gate:', o_t.detach())
print('New hidden state h_t:', h_t.detach())Aantal LSTM-parameters en gewichtsmatrices
Een LSTM heeft vier gewichtsmatrices (vergeten, invoer, kandidaat, uitvoer), elk met de afmetingen (hidden_size, hidden_size + input_size), plus biaswaarden. Het totale aantal parameters is 4 * hidden_size * (hidden_size + input_size) + 4 * hidden_size.
De nn.LSTM van PyTorch verpakt alle vier de poorten voor efficiëntie in de gecombineerde gewichtsmatrices weight_ih_l0 en weight_hh_l0. Daarom kan het trainen van een LSTM langzamer zijn dan dat van een GRU (Gated Recurrent Unit), die slechts twee poorten en minder parameters gebruikt.
import torch.nn as nn
hidden = 64
input_s = 32
lstm = nn.LSTM(input_size=input_s, hidden_size=hidden, batch_first=True)
# PyTorch stores weight_ih (input-hidden) and weight_hh (hidden-hidden)
print('weight_ih_l0 shape:', lstm.weight_ih_l0.shape) # (4*hidden, input)
print('weight_hh_l0 shape:', lstm.weight_hh_l0.shape) # (4*hidden, hidden)
print('Total params:', sum(p.numel() for p in lstm.parameters()))nn.LSTM gebruiken in PyTorch
De nn.LSTM van PyTorch accepteert een sequentietensor met de vorm (batch, seq_len, input_size) wanneer batch_first=True is ingesteld, en optioneel een tuple met de beginstatus (h_0, c_0). De methode retourneert de uitvoertensor (alle verborgen toestanden) en een tuple met de eindtoestanden.
Voor sequentieclassificatie heb je meestal alleen de laatste verborgen toestand h_n van de laatste tijdstap nodig. Voor taken met sequentielabels (zoals herkenning van benoemde entiteiten) gebruik je de uitvoer van alle tijdstappen. Initialiseer verborgen toestanden altijd op nul, tenzij je een reden hebt om context tussen batches door te geven.
import torch
import torch.nn as nn
batch_size, seq_len, input_size = 16, 20, 32
hidden_size = 64
lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size, batch_first=True)
x = torch.randn(batch_size, seq_len, input_size)
# Forward pass
output, (h_n, c_n) = lstm(x)
print('Output shape (all timesteps):', output.shape) # (16, 20, 64)
print('h_n shape (final hidden):', h_n.shape) # (1, 16, 64)
print('c_n shape (final cell):', c_n.shape) # (1, 16, 64)LSTM's met meerdere lagen en in beide richtingen
Een gestapelde LSTM gebruikt de uitvoer van de ene LSTM-laag als invoer voor de volgende, zodat het netwerk hiërarchische temporele representaties kan leren. Stel num_layers=2 of hoger in bij nn.LSTM.
Een bidirectionele LSTM laat één LSTM vooruit door de sequentie lopen en een andere achteruit, en voegt hun verborgen toestanden samen. Hierdoor krijgt elke tijdstap context uit zowel het verleden als de toekomst. Stel bidirectional=True in; de uitvoerdimensie wordt dan 2 * hidden_size. Bidirectionele LSTM's zijn zeer effectief voor NLP-taken waarbij zowel de linker- als rechtercontext van belang zijn.
import torch
import torch.nn as nn
# Bidirectional stacked LSTM
lstm = nn.LSTM(
input_size=32,
hidden_size=64,
num_layers=2,
batch_first=True,
bidirectional=True,
dropout=0.3 # Dropout between layers
)
x = torch.randn(16, 20, 32)
output, (h_n, c_n) = lstm(x)
print('Bidirectional output shape:', output.shape) # (16, 20, 128)
print('h_n shape:', h_n.shape) # (4, 16, 64): 2 layers * 2 directionsGRU: een eenvoudiger alternatief voor LSTM
De Gated Recurrent Unit (GRU) vereenvoudigt de LSTM door de vergeet- en invoerpoorten samen te voegen tot één bijwerkpoort en de cel- en verborgen toestanden te combineren. De GRU gebruikt slechts twee poorten: de resetpoort (hoeveel van het verleden moet worden vergeten) en de bijwerkpoort (hoeveel moet worden bijgewerkt).
Een GRU heeft minder parameters en wordt sneller getraind dan een LSTM, terwijl de prestaties vaak vergelijkbaar zijn. Gebruik LSTM wanneer je maximale expressiviteit voor complexe sequenties nodig hebt, en GRU wanneer snelheid en eenvoud belangrijk zijn. In de praktijk bepaalt empirisch testen op je specifieke taak welke keuze beter is.
import torch
import torch.nn as nn
# GRU is simpler: only 3 weight matrices instead of 4
gru = nn.GRU(input_size=32, hidden_size=64, batch_first=True)
lstm = nn.LSTM(input_size=32, hidden_size=64, batch_first=True)
print('GRU params:', sum(p.numel() for p in gru.parameters()))
print('LSTM params:', sum(p.numel() for p in lstm.parameters()))
# GRU has 25% fewer parameters than LSTM for same hidden sizeIntuïtie achter LSTM aan de hand van een taalvoorbeeld
Bekijk de zin: 'De auteur, die vele jaren in Parijs woonde, schreef een roman.' Een LSTM moet 'auteur' (enkelvoud) onthouden wanneer het veel woorden later bij 'schreef' aankomt.
De vergeetpoort houdt 'auteur' gedurende de lange betrekkelijke bijzin in de celtoestand. De invoerpoort voegt nieuwe relevante informatie, zoals 'schreef', toe aan de celtoestand. De uitvoerpoort gebruikt de celtoestand op het juiste moment om de correcte verborgen toestand te produceren voor vervolgtaken, zoals het voorspellen van het volgende woord of het classificeren van de zin.
- Vergeetpoort: Houd het onderwerp vast gedurende de betrekkelijke bijzin
- Invoerpoort: Sla de informatie over het werkwoord op zodra je die tegenkomt
- Uitvoerpoort: Gebruik de opgeslagen informatie tijdens het voorspellen
Korte controle
Test je begrip van de LSTM-poorten uit deze les.
Samenvatting van de les
In deze les heb je geleerd dat de LSTM-celtoestand fungeert als langetermijngeheugen dat met minimale wijzigingen door de sequentie stroomt, dat drie poortmechanismen (vergeten, invoer, uitvoer) de informatiestroom regelen met vermenigvuldiging die door een sigmoid wordt aangestuurd, en dat de optellende update van de celtoestand C_t = f_t * C_{t-1} + i_t * g_t ervoor zorgt dat gradiënten kunnen doorstromen zonder te verdwijnen. Hierna passen we LSTM's toe op een echte taak voor sentimentanalyse en bouwen we een tekstclassificatiemodel van begin tot eind.
Leer Python met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 30
- Lessen
- 120
Veelgestelde vragen
Is de les “LSTM-cel: input-, forget- en outputgates” gratis?
Ja — de volledige tekst van “LSTM-cel: input-, forget- en outputgates” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Machine Learning Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Machine Learning Academy bevat in totaal 4 lessen.
Wat leer ik in “LSTM-cel: input-, forget- en outputgates”?
Cursisten brengen de LSTM-cel in kaart, volgen de informatiestroom door elke gate en implementeren een LSTM-tekstclassifier met nn.LSTM. Je oefent met Machine Learning Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Machine Learning Academy te beginnen?
Ervaring vooraf is niet nodig. Machine Learning Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.
Hoe lang duurt de les “LSTM-cel: input-, forget- en outputgates”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Machine Learning Academy?
Ja. Elke les over Machine Learning Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Vanilla RNN's: hidden state en sequentie-uitvouwing
- Het verdwijnende-gradiëntprobleem bij diepe tijdstappen
- LSTM-cel: input-, forget- en outputgates
- Sequence-to-one: sentimentanalyse met een LSTM