LSTM-cellen: Input-, forget- og output gates
De lærende tegner LSTM-cellen, følger informationsstrømmen gennem hver gate og implementerer en LSTM-tekstklassifikator med nn.LSTM.
LSTM-cellen: Input-, forget- og output gates er en gratis Machine Learning Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Machine Learning Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Machine Learning Academy-kurset indeholder 4 lektioner i alt.
Hvorfor RNN'er har brug for gating-mekanismer
Standardmæssige almindelige RNN'er har svært ved afhængigheder over lange afstande, fordi gradienter forsvinder under backpropagering gennem tiden. Den skjulte tilstand h_t = tanh(W_h * h_{t-1} + W_x * x_t) overskriver den tidligere kontekst med hvert nyt input, så netværket glemmer information fra mange trin tilbage.
Long Short-Term Memory (LSTM) blev udviklet i 1997 af Hochreiter og Schmidhuber for at løse dette problem. Det introducerer en celletilstand — et separat hukommelsestransportbånd — sammen med gating-mekanismer, der eksplicit styrer, hvilke oplysninger der tilføjes, fjernes eller sendes videre.
Begrebet LSTM-celletilstanden
LSTM har to interne tilstande: celletilstanden C_t og den skjulte tilstand h_t. Celletilstanden fungerer som et transportbånd gennem hele sekvensen, mens gates styrer mindre lineære interaktioner. Det gør det lettere for gradienter at flyde gennem tiden.
Den skjulte tilstand h_t er outputtet ved hvert tidssteg og beregnes ud fra celletilstanden. Tænk på C_t som langtidshukommelse og h_t som arbejdshukommelse, der sendes videre til det næste lag og returneres som output.
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()))Glemmegaten
Glemmegaten er den første gate, som inputtet passerer gennem. Den læser den tidligere skjulte tilstand h_{t-1} og det aktuelle input x_t og sender en værdi mellem 0 og 1 ud for hvert element i celletilstanden.
Værdien 1 betyder »behold alt«, mens 0 betyder »glem helt«. Formlen er: f_t = sigmoid(W_f · [h_{t-1}, x_t] + b_f). Når der for eksempel behandles en ny sætning i en NLP-opgave, vil glemmegaten nulstille oplysninger om subjektet, der er gemt fra den forrige sætning.
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 1Inputgaten og kandidatcellen
Inputgaten afgør, hvilke nye værdier der skal gemmes i cellestatussen. Den består af to dele, der arbejder sammen: inputgaten i_t = sigmoid(W_i · [h_{t-1}, x_t] + b_i) bestemmer, hvor meget der skal opdateres, og kandidatcellen g_t = tanh(W_g · [h_{t-1}, x_t] + b_g) opretter kandidatværdier, der potentielt kan tilføjes.
Sigmoid-funktionen styrer gaten (0 = lukket, 1 = åben), mens tanh-funktionen opretter værdier i intervallet [-1, 1]. Den nye information, der tilføjes til cellestatussen, er i_t * g_t — gaten filtreret gennem kandidatværdierne.
# 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())Opdatering af cellestatussen
Når vi har glemmeporen f_t, inputgaten i_t og kandidatcellen g_t, er det ligetil at opdatere cellestatussen: C_t = f_t * C_{t-1} + i_t * g_t.
Det første led f_t * C_{t-1} anvender glemmeporen — det sletter selektivt information fra den forrige cellestatus. Det andet led i_t * g_t tilføjer ny information selektivt. Denne additive struktur gør det muligt for gradienter at flyde tilbage gennem mange tidstrin uden at forsvinde, fordi gradienten flyder direkte gennem additionsoperationen.
# 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 stepOutputgaten
Outputgaten styrer, hvilken del af cellestatussen der eksponeres som outputtet fra den skjulte tilstand h_t. Først afgør outputgaten, hvilke dele af cellestatussen der skal sendes ud: o_t = sigmoid(W_o · [h_{t-1}, x_t] + b_o).
Derefter sendes cellestatussen gennem tanh-funktionen (for at begrænse værdierne til mellem -1 og 1) og multipliceres med outputgaten: h_t = o_t * tanh(C_t). Den skjulte tilstand h_t fungerer både som outputtet ved dette tidstrin og som inputtet til det næste LSTM-trin sammen med den nye cellestatus.
# 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())Antal LSTM-parametre og vægtmatricer
En LSTM har fire vægtmatricer (glemme-, input-, kandidat- og outputgaten), som hver har størrelsen (hidden_size, hidden_size + input_size), samt bias. Det samlede antal parametre er 4 * hidden_size * (hidden_size + input_size) + 4 * hidden_size.
PyTorch's nn.LSTM samler alle fire gates i de kombinerede vægtmatricer weight_ih_l0 og weight_hh_l0 for at opnå bedre effektivitet. Derfor kan træning af en LSTM være langsommere end træning af en GRU (Gated Recurrent Unit), som kun bruger to gates og færre parametre.
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()))Brug af nn.LSTM i PyTorch
PyTorch's nn.LSTM accepterer en sekvenstensor med formen (batch, seq_len, input_size), når batch_first=True, samt valgfrit en tupel med den oprindelige tilstand (h_0, c_0). Den returnerer outputtensoren (alle skjulte tilstande) og en tupel med de endelige tilstande.
Til sekvensklassifikation har du typisk kun brug for den sidste skjulte tilstand h_n fra det sidste tidstrin. Til sekvensmærkningsopgaver (som genkendelse af navngivne entiteter) bruger du outputtene fra alle tidstrin. Initialisér altid de skjulte tilstande til nul, medmindre du har en grund til at føre kontekst videre mellem batches.
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'er med flere lag og i begge retninger
En stablet LSTM sender outputtet fra ét LSTM-lag som input til det næste, så netværket kan lære hierarkiske tidsmæssige repræsentationer. Angiv num_layers=2 eller mere i nn.LSTM.
En tovejs-LSTM kører én LSTM fremad gennem sekvensen og en anden baglæns og sammenkæder deres skjulte tilstande. Det giver hvert tidstrin kontekst fra både fortiden og fremtiden. Angiv bidirectional=True; outputdimensionen bliver 2 * hidden_size. Tovejs-LSTM'er er meget effektive til NLP-opgaver, hvor både venstre- og højrekontekst er vigtig.
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: Et enklere alternativ til LSTM
Gated Recurrent Unit (GRU) forenkler LSTM ved at slå glemme- og inputgaten sammen til én opdateringsgate og kombinere celle- og skjulte tilstande. Den bruger kun to gates: nulstillingsgaten (hvor meget af fortiden der skal glemmes) og opdateringsgaten (hvor meget der skal opdateres).
En GRU har færre parametre og trænes hurtigere end en LSTM, samtidig med at den ofte opnår sammenlignelige resultater. Brug LSTM, når du har brug for maksimal udtrykskraft på komplekse sekvenser, og GRU, når hastighed og enkelhed er vigtig. I praksis afgør empiriske tests på din konkrete opgave, hvilket valg der er bedst.
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 sizeIntuition bag LSTM gennem et sprogeksempel
Se på sætningen: 'The author, who lived in Paris for many years, wrote a novel.' En LSTM skal huske 'author' (ental), når den mange ord senere når frem til 'wrote'.
Glemmeporen bevarer 'author' i cellestatussen gennem hele den lange relativsætning. Inputgaten tilføjer ny relevant information som 'wrote' til cellestatussen. Outputgaten bruger cellestatussen på det rigtige tidspunkt til at danne den korrekte skjulte tilstand til efterfølgende opgaver som forudsigelse af det næste ord eller klassifikation af sætningen.
- Glemmepor: Bevar subjektet gennem relativsætningen
- Inputgate: Gem information om verbet, når det mødes
- Outputgate: Brug den gemte information på forudsigelsestidspunktet
Hurtigt tjek
Test din forståelse af LSTM-gates fra denne lektion.
Opsummering af lektionen
I denne lektion lærte du, at LSTM-cellestatussen fungerer som langtidshukommelse, der flyder gennem sekvensen med minimale ændringer, at tre gatingmekanismer (glemme-, input- og outputgaten) styrer informationsstrømmen ved hjælp af sigmoidstyret multiplikation, og at den additive opdatering af cellestatussen C_t = f_t * C_{t-1} + i_t * g_t lader gradienter flyde uden at forsvinde. Næste trin er at anvende LSTM'er på en reel opgave inden for sentimentanalyse, hvor vi bygger en tekstklassifikator fra ende til anden.
Lær Python med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “LSTM-cellen: Input-, forget- og output gates” gratis?
Ja — hele teksten til “LSTM-cellen: Input-, forget- og output gates” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Machine Learning Academy-kurset, skal du opgradere til CoddyKit PRO. Machine Learning Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “LSTM-cellen: Input-, forget- og output gates”?
De lærende tegner LSTM-cellen, følger informationsstrømmen gennem hver gate og implementerer en LSTM-tekstklassifikator med nn.LSTM. Du øver dig i Machine Learning Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Machine Learning Academy?
Der kræves ingen tidligere erfaring. Machine Learning Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “LSTM-cellen: Input-, forget- og output gates”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Machine Learning Academy-lektion?
Ja. Alle Machine Learning Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Vanilla-RNN'er: Hidden state og sekvensudrulning
- Problemet med forsvindende gradienter over dybe tidstrin
- LSTM-cellen: Input-, forget- og output gates
- Sekvens-til-én: Sentimentanalyse med en LSTM