소개: 시퀀스용 신경망
Le 순환 신경망(RNN) 순차 데이터를 처리하도록 설계되었습니다. 텍스트, 시계열, 오디오, 액션 시퀀스. 처리하는 피드포워드 네트워크와는 달리 독립적인 입력, RNN은 하나를 유지합니다. 숨겨졌어 (숨겨진 상태) 역할을 하는 메모리를 통해 네트워크는 시퀀스에서 이전 정보의 맥락을 고려할 수 있습니다.
그러나 기존 RNN은 다음과 같은 문제를 겪고 있습니다. 사라지는 그래디언트 문제: 동안 훈련을 하면 시간 단계에 따라 기울기가 급격히 감쇠되어 학습이 불가능해집니다. 장기 중독. 그만큼 LSTM (장단기 기억) 및 기중기 (Gated Recurrent Unit)은 정교한 게이팅 메커니즘으로 이 문제를 해결합니다.
무엇을 배울 것인가
- RNN이 시퀀스 전체에서 상태를 유지하는 방법
- Vanishing Gradient 문제와 이것이 RNN을 제한하는 이유
- LSTM: 입력 게이트, 망각 게이트, 출력 게이트 및 셀 상태
- CRANES: LSTM에 대한 더 가벼운 대안
- 양방향 RNN 및 시퀀스-시퀀스 모델
- 실제 구현: 텍스트 생성 및 감정 분석
RNN: 아키텍처와 숨겨진 상태
RNN은 한 번에 한 요소씩 시퀀스를 처리하여 각 단계에서 자체 업데이트를 수행합니다. 숨겨진 상태. 이 상태 벡터는 모든 항목의 압축된 요약을 캡처합니다. 그 시점까지 본 정보. 각 시간 단계의 출력은 두 입력에 따라 달라집니다. 이전 숨겨진 상태보다 현재 상태입니다.
공식적으로 RNN은 각 시간 단계 t에서 다음을 계산합니다.
- h_t = tanh(W_hh * h_(t-1) + W_xh * x_t + b_h): 이전 상태와 현재 입력을 결합한 새로운 숨겨진 상태
- y_t = W_hy * h_t + b_y: 현재 시간 단계에서 출력
import torch
import torch.nn as nn
# RNN semplice in PyTorch
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
self.hidden_size = hidden_size
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
# x shape: (batch, seq_len, input_size)
# h0 shape: (1, batch, hidden_size)
h0 = torch.zeros(1, x.size(0), self.hidden_size).to(x.device)
output, hidden = self.rnn(x, h0)
# Usa l'ultimo hidden state per classificazione
out = self.fc(hidden.squeeze(0))
return out
# Esempio: sequenza di 20 time step con 10 feature ciascuno
model = SimpleRNN(input_size=10, hidden_size=64, output_size=2)
x = torch.randn(8, 20, 10) # batch=8, seq=20, features=10
output = model(x)
print(f"Output: {output.shape}") # [8, 2]
사라지는 그라디언트 문제
Il 사라지는 그라데이션 그리고 고전적인 RNN의 아킬레스 건. 동안 시간을 통한 역전파(BPTT), 기울기에 행렬을 반복적으로 곱합니다. 각 시간 단계의 가중치 W_hh. 이 행렬의 고유값이 1보다 작으면 기울기는 다음과 같습니다. 기하급수적으로 감소합니다. 1보다 크면 폭발합니다.
실제로 이는 기존 RNN이 오버슈팅 종속성을 학습하지 못함을 의미합니다. 나 10-20 시간 단계. 문장의 느낌을 이해하는 핵심 단어가 시작과 끝의 출력에서 그래디언트는 해당 값에 도달하기 전에 거의 0이 됩니다. 단어.
LSTM이 필요한 이유
LSTM은 우아한 직관으로 사라지는 그래디언트를 해결합니다. 반복된 곱셈을 통해 정보에 세포 상태 별도의 정보의 "고속도로" 역할을 합니다. Gates는 추가할 정보를 제어합니다. 셀 상태를 잊어버리거나 읽어서 그래디언트가 수백 동안 변경되지 않고 흐르도록 허용 시간 단계의.
LSTM: 장단기 기억
Le LSTM, 1997년 Hochreiter와 Schmidhuber가 도입한 소멸 문제 해결 네 가지 주요 구성 요소가 포함된 그라데이션:
세 개의 문
- 게이트 포겟(f_t): 셀 상태에서 어떤 정보를 버릴지 결정합니다. 각 차원에 대해 0(모두 무시)과 1(모두 유지) 사이의 시그모이드 값
- 입력 게이트(i_t): 셀 상태에 추가할 새로운 정보를 결정합니다. 시그모이드 게이트(추가할 양)와 tanh 후보 벡터(추가할 내용)를 결합합니다.
- 출력 게이트(o_t): 출력/숨겨진 상태로 사용할 셀 상태의 부분을 결정합니다. tanh 및 sigmoid를 통해 셀 상태 필터링
셀 상태
Il 세포 상태 LSTM의 핵심입니다. 그것은 시간 사슬을 통해 흐른다. 선형 연산(곱셈과 덧셈)만 가능하므로 그래디언트가 전파될 수 있습니다. 쉽게. 게이트는 셀 상태 안팎으로 정보의 흐름을 조절합니다.
import torch
import torch.nn as nn
class LSTMClassifier(nn.Module):
"""LSTM per classificazione di sequenze"""
def __init__(self, vocab_size, embed_dim, hidden_size,
num_layers, num_classes, dropout=0.3):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
self.lstm = nn.LSTM(
input_size=embed_dim,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
dropout=dropout if num_layers > 1 else 0,
bidirectional=True
)
self.dropout = nn.Dropout(dropout)
# Bidirezionale: hidden_size * 2
self.fc = nn.Linear(hidden_size * 2, num_classes)
def forward(self, x):
embedded = self.dropout(self.embedding(x))
lstm_out, (hidden, cell) = self.lstm(embedded)
# Concatena hidden state forward e backward
hidden_cat = torch.cat((hidden[-2], hidden[-1]), dim=1)
output = self.fc(self.dropout(hidden_cat))
return output
# Sentiment analysis: vocab 10000, embedding 128, hidden 256
model = LSTMClassifier(
vocab_size=10000,
embed_dim=128,
hidden_size=256,
num_layers=2,
num_classes=2 # positivo/negativo
)
# Input: batch di 16 frasi, max 50 token
x = torch.randint(0, 10000, (16, 50))
output = model(x)
print(f"Output: {output.shape}") # [16, 2]
크레인: 더 가벼운 대안
Le 기중기 (Gated Recurrent Unit), Cho et al. 2014년에 나는 하나다 LSTM의 단순화된 버전입니다. 망각 게이트와 입력 게이트를 하나로 결합합니다. 업데이트 게이트 셀 상태와 숨겨진 상태를 병합하여 매개변수 수를 줄입니다. 약 25% 정도.
크레인에는 두 개의 게이트가 있습니다.
- 게이트 재설정(r_t): 새 후보를 계산할 때 무시할 이전 숨겨진 상태의 양
- 업데이트 게이트(z_t): 유지할 이전 숨겨진 상태의 양과 사용할 새 후보의 양
실제로 GRU는 많은 작업에서 LSTM과 비슷한 성능을 달성합니다. 열등한 훈련. 선택은 작업에 따라 다릅니다. 매우 긴 시퀀스의 경우 LSTM은 다음과 같은 경향이 있습니다. 더 작은 데이터 세트의 경우 GRU가 더 작은 경우에 바람직할 수 있습니다. 과적합 경향.
양방향 RNN 및 Sequence-to-Sequence
양방향
에이 양방향 RNN 시퀀스를 양쪽 앞으로(왼쪽에서 오른쪽으로) 처리합니다. 거꾸로(오른쪽에서 왼쪽으로) 두 개의 숨겨진 상태를 연결합니다. 이를 통해 각 직위는 과거와 미래의 맥락을 모두 갖고 있어야 하며, 이는 다음과 같은 작업에 기본이 됩니다. 단어의 의미가 전체 맥락에 따라 달라지는 명명된 엔터티 인식.
시퀀스 간(Seq2Seq)
아키텍처 Seq2Seq RNN 인코더를 사용하여 입력 시퀀스를 다음으로 압축합니다. 고정된 컨텍스트 벡터와 출력 시퀀스를 생성하는 RNN 디코더. 이 Transformers가 등장하기 전에는 아키텍처가 기계 번역의 기본이었습니다.
class TextGenerator(nn.Module):
"""Generatore di testo carattere per carattere"""
def __init__(self, vocab_size, embed_dim, hidden_size, num_layers):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden_size, num_layers,
batch_first=True, dropout=0.2)
self.fc = nn.Linear(hidden_size, vocab_size)
def forward(self, x, hidden=None):
embedded = self.embedding(x)
output, hidden = self.lstm(embedded, hidden)
logits = self.fc(output)
return logits, hidden
def generate(self, start_token, max_len=100, temperature=0.8):
"""Genera testo auto-regressivamente"""
self.eval()
current = start_token.unsqueeze(0).unsqueeze(0)
hidden = None
generated = [start_token.item()]
with torch.no_grad():
for _ in range(max_len):
logits, hidden = self(current, hidden)
logits = logits[:, -1, :] / temperature
probs = torch.softmax(logits, dim=-1)
next_token = torch.multinomial(probs, 1)
generated.append(next_token.item())
current = next_token
return generated
관심의 출현
Seq2Seq 모델의 주요 제한 사항은 다음과 같습니다. 병목: 모든 정보 입력 시퀀스의 단일 고정 벡터로 압축됩니다. 긴 시퀀스의 경우 이 벡터가 모든 세부 사항을 캡처하지 못합니다. 메커니즘 주목, Bahdanau 등이 소개했습니다. 2014년에는 디코더를 통해 이 문제를 해결했습니다. 모든 인코더 위치를 직접 "보세요". 이 아이디어는 트랜스포머, 다음 기사에서 살펴보겠습니다.
실제 응용
RNN과 LSTM은 다양한 도메인에 적용됩니다.
- 감성 분석: 리뷰, 트윗, 댓글의 감성을 분류합니다. 양방향 LSTM은 전체 컨텍스트를 캡처합니다.
- 시계열 예측: 주가, 에너지 소비, 시스템 지표를 예측합니다. LSTM은 계절적 패턴을 포착하는 데 탁월합니다.
- 텍스트 생성: 챗봇부터 계산 시까지, 문자별로 또는 단어별로 텍스트 문자를 생성합니다.
- 기계 번역: Seq2Seq + Attention 아키텍처를 사용한 기계 번역(Transformers의 전신)
- 음성 인식: 음향 시퀀스가 음소 및 단어 시퀀스에 매핑되는 오디오-텍스트 변환
시리즈의 다음 단계
- 다음 기사에서는 트랜스포머, 대부분의 NLP 작업에서 RNN을 더 이상 사용하지 않게 만든 아키텍처
- 셀프 어텐션, 멀티 헤드 어텐션, 위치 인코딩을 살펴보겠습니다.
- BERT와 GPT가 자연어 처리에 어떻게 혁명을 일으켰는지 분석해 보겠습니다.







