머신러닝 & 딥러닝/딥러닝

[AI 기초 다지기] RNN & LSTM 논문 분석 및 코드 구현

Haru_29 2024. 11. 11. 20:26

RNN 기초부터 최신 연구까지 가이드

목차

  1. RNN의 기초와 이론
  2. RNN의 구조와 작동 원리
  3. 문자 수준 언어 모델링
  4. 실제 적용 사례 연구
  5. 학습 과정과 최적화
  6. RNN의 내부 동작 분석
  7. 고급 주제와 최신 연구
  8. 도구와 프레임워크
  9. 문제 해결과 최적화 전략

1. RNN의 기초와 이론

1.1 순환 신경망의 개념

RNN(Recurrent Neural Networks)은 시퀀스 데이터를 처리하기 위해 설계된 특별한 형태의 신경망입니다.

핵심 특징

  • 내부 메모리 상태 유지
  • 가변 길이 입/출력 처리 가능
  • 시간적 의존성 학습 능력

RNN vs 전통적 신경망

  1. 전통적 신경망의 한계
    • 고정된 입력 크기
    • 독립적인 입력 처리
    • 시간적 문맥 고려 불가
  2. RNN의 장점
    • 가변 길이 입력 처리
    • 문맥 정보 보존
    • 시퀀스 패턴 학습

1.2 수학적 기초

기본 수식

h_t = tanh(W_hh * h_(t-1) + W_xh * x_t)
y_t = W_hy * h_t

여기서:

  • h_t: 현재 시점의 은닉 상태
  • x_t: 입력 벡터
  • y_t: 출력 벡터
  • W_hh, W_xh, W_hy: 가중치 행렬

역전파 through time (BPTT)

def bptt(self, x, y, h):
    # 순전파
    h_states = []
    y_preds = []
    loss = 0
    
    # 각 시점에서의 상태 계산
    for t in range(len(x)):
        h = np.tanh(np.dot(W_hh, h) + np.dot(W_xh, x[t]))
        h_states.append(h)
        y_pred = np.dot(W_hy, h)
        y_preds.append(y_pred)
        loss += self.loss_function(y[t], y_pred)
        
    # 역전파
    dW_hh = np.zeros_like(W_hh)
    dW_xh = np.zeros_like(W_xh)
    dW_hy = np.zeros_like(W_hy)
    dh_next = np.zeros_like(h_states[0])
    
    for t in reversed(range(len(x))):
        dy = y_preds[t] - y[t]
        dW_hy += np.dot(dy, h_states[t].T)
        dh = np.dot(W_hy.T, dy) + dh_next
        dh_raw = (1 - h_states[t] * h_states[t]) * dh
        dW_xh += np.dot(dh_raw, x[t].T)
        dW_hh += np.dot(dh_raw, h_states[t-1].T)
        dh_next = np.dot(W_hh.T, dh_raw)
    
    return dW_hh, dW_xh, dW_hy, loss

2. RNN의 구조와 작동 원리

2.1 기본 구조

[입력 층] -> [은닉 층(순환)] -> [출력 층]
     ↑            ↑              ↓
     x_t          h_t            y_t

2.2 다양한 구조

  1. 일대일 (One-to-One)
    • 이미지 분류
    • 벡터 변환
  2. 일대다 (One-to-Many)
    • 이미지 캡셔닝
    • 음악 생성
  3. 다대일 (Many-to-One)
    • 감정 분석
    • 시퀀스 분류
  4. 다대다 (Many-to-Many)
    • 기계 번역
    • 비디오 분류

3. 문자 수준 언어 모델링

3.1 데이터 전처리

def prepare_data(text):
    # 문자 집합 생성
    chars = sorted(list(set(text)))
    char_to_idx = {ch:i for i,ch in enumerate(chars)}
    idx_to_char = {i:ch for i,ch in enumerate(chars)}
    
    # 데이터 인코딩
    x = [char_to_idx[ch] for ch in text[:-1]]
    y = [char_to_idx[ch] for ch in text[1:]]
    
    return x, y, char_to_idx, idx_to_char

3.2 실험 결과

폴 그레이엄 에세이 실험

설정:

  • 데이터: 1MB 텍스트
  • 모델: 2-layer LSTM
  • Hidden Units: 512
  • Dropout: 0.5
  • Learning Rate: 0.002

결과:

The surprised in investors weren't going to raise money. 
I'm not the company with the time there are all interesting quickly, 
don't have to get off the same programmers.

셰익스피어 작품 실험

설정:

  • 데이터: 4.4MB 텍스트
  • 모델: 3-layer LSTM
  • Hidden Units: 512
  • Batch Size: 100

결과:

The surprised in investors weren't going to raise money. 
I'm not the company with the time there are all interesting quickly, 
don't have to get off the same programmers.

4. 실제 적용 사례 연구

4.1 위키피디아 문서 생성

특징적 결과:

== See also ==
* [[List of ethical consent processing]]
* [[Anti-autism]]
* [[French Writings]]
* [[Maria]]
* [[Revelation]]

4.2 리눅스 소스 코드 생성

생성된 코드 예시:

/*
 * Increment the size file of the new incorrect UI_FILTER group information
 * of the size generatively.
 */
static int indicate_policy(void)
{
    int error;
    if (fd == MARN_EPT) {
        /*
         * The kernel blank will coeld it to userspace.
         */
        if (ss->segment < mem_total)
            unblock_graph_and_set_blocked();
        else
            ret = 1;
        goto bail;
    }
    return segtable;
}

5. 학습 과정과 최적화

5.1 단계별 학습 진행

  1. 초기 단계 (100 iterations)
tyntd-iafhatawiaoihrdemot lytdws e ,tfti

    2. 중기 단계 (500 iterations)

"We counter. He stutn co des. His stanted"

    3. 최종 단계 (2000 iterations)

"Why do what that day," replied Natasha, and wishing to himself the fact the
princess, Princess Mary was easier, fed in had oftened him.

5.2 하이퍼파라미터 최적화

  1. Learning Rate 조정
    • 초기값: 0.01
    • Decay: 0.95
    • Minimum: 0.001
  2. Batch Size 실험
    • 작은 배치 (32): 빠른 학습, 높은 변동성
    • 중간 배치 (64): 균형잡힌 성능
    • 큰 배치 (128): 안정적 학습, 느린 수렴
  3. Dropout 적용
    • Input Layer: 0.2
    • Hidden Layers: 0.5
    • Output Layer: 0.2

6. RNN의 내부 동작 분석

6.1 뉴런 활성화 패턴

  1. URL 감지 뉴런
http://www. -> 높은 활성화
다른 텍스트 -> 낮은 활성화

    2. 마크다운 구문 뉴런

[[ 시작 -> 활성화 시작
]] 종료 -> 활성화 종료
 
 

6.2 주요 패턴 분석

  1. 시간적 의존성
  2. 문맥 인식
  3. 패턴 일반화

7. 고급 주제와 최신 연구

7.1 주의 메커니즘 (Attention)

def attention(query, keys, values):
    # 어텐션 스코어 계산
    scores = np.dot(query, keys.T)
    # 소프트맥스 적용
    attention_weights = softmax(scores)
    # 가중치 적용된 컨텍스트 벡터
    context = np.dot(attention_weights, values)
    return context, attention_weights

7.2 메모리 네트워크

  1. Neural Turing Machines
  2. Memory Networks
  3. Differentiable Neural Computers

8. 도구와 프레임워크

8.1 주요 프레임워크

  1. PyTorch
class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(RNN, self).__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, hidden):
        out, hidden = self.rnn(x, hidden)
        out = self.fc(out)
        return out, hidden
 

    2. TensorFlow

model = tf.keras.Sequential([
    tf.keras.layers.SimpleRNN(128, input_shape=(None, input_size)),
    tf.keras.layers.Dense(output_size, activation='softmax')
])

9. 문제 해결과 최적화 전략

9.1 일반적인 문제들

  1. 기울기 소실/폭발
    • 해결: 기울기 클리핑
    • LSTM/GRU 사용
  2. 긴 시퀀스 처리
    • 해결: Attention 메커니즘
    • 계층적 구조 사용
  3. 과적합
    • 해결: Dropout
    • 정규화 기법 적용

9.2 최적화 전략

  1. 학습률 스케줄링
def learning_rate_schedule(epoch):
    initial_rate = 0.001
    decay = 0.95
    return initial_rate * (decay ** epoch)

    2. 배치 정규화

def batch_normalize(x, gamma, beta):
    mean = np.mean(x, axis=0)
    var = np.var(x, axis=0)
    x_norm = (x - mean) / np.sqrt(var + 1e-8)
    return gamma * x_norm + beta

결론

RNN은 시퀀스 데이터 처리에 있어 혁신적인 솔루션을 제공하며, 다음과 같은 특징을 가집니다:

  1. 유연한 구조
    • 다양한 입출력 형태 지원
    • 복잡한 패턴 학습 능력
  2. 광범위한 응용
    • 자연어 처리
    • 음성 인식
    • 시계열 예측
  3. 지속적인 발전
    • 새로운 구조 개발
    • 성능 개선
    • 응용 분야 확장

향후 연구 방향:

  1. 효율적인 학습 알고리즘
  2. 더 강력한 메모리 메커니즘
  3. 복잡한 추론 능력 향상

 

LSTM(Long Short-Term Memory) 네트워크

목차

  1. 순환 신경망(RNN)의 기초
  2. 장기 의존성 문제
  3. LSTM 네트워크 소개
  4. LSTM의 핵심 구조
  5. LSTM의 상세 작동 방식
  6. LSTM의 변형
  7. 결론 및 미래 전망

1. 순환 신경망(RNN)의 기초

1.1 인간의 사고방식과 RNN

인간은 매 순간 처음부터 다시 생각하지 않습니다. 예를 들어, 글을 읽을 때 이전 단어들을 기반으로 현재 단어를 이해합니다. 이러한 '지속성'을 가진 사고 방식이 바로 RNN의 기본 아이디어입니다.

1.2 전통적인 신경망의 한계

기존의 전통적인 신경망은 이전 정보를 활용하지 못한다는 큰 단점이 있습니다. 예를 들어, 영화의 각 장면에서 어떤 사건이 일어나고 있는지 분류하려 할 때, 이전 장면들의 맥락을 활용할 수 없습니다.

1.3 RNN의 구조

RNN은 이러한 문제를 해결하기 위해 루프를 포함한 네트워크 구조를 가집니다:

  • 정보가 지속될 수 있도록 하는 순환 구조
  • 동일한 네트워크의 여러 복사본이 연쇄적으로 연결
  • 시퀀스와 리스트 형태의 데이터 처리에 최적화

2. 장기 의존성 문제

2.1 문제의 정의

RNN의 주요 장점은 이전 정보를 현재 작업에 연결할 수 있다는 것입니다. 하지만 실제로는 정보 간의 거리가 멀어질수록 연결이 어려워지는 "장기 의존성 문제"가 발생합니다.

2.2 실제 예시

  • 단기 의존성 예시: "구름이 하늘에 ___" → "있다"를 예측하기 쉬움
  • 장기 의존성 예시: "나는 프랑스에서 자랐다... 나는 유창한 ___를 구사한다" → "프랑스어"를 예측하기 위해서는 먼 과거의 정보가 필요

3. LSTM 네트워크 소개

3.1 LSTM의 탄생

  • Hochreiter & Schmidhuber(1997)에 의해 소개
  • 장기 의존성 문제를 해결하기 위해 특별히 설계
  • 오랜 기간의 정보 기억이 기본 동작

3.2 기본 구조

  • 체인 형태의 반복 모듈 구조
  • 표준 RNN과 달리 4개의 상호작용 레이어 포함
  • 정보의 추가와 제거를 세밀하게 제어하는 게이트 메커니즘

4. LSTM의 핵심 구조

4.1 셀 상태(Cell State)

  • LSTM의 핵심 아이디어
  • 컨베이어 벨트처럼 체인 전체를 관통
  • 정보가 변경 없이 그대로 흐를 수 있는 구조

4.2 게이트(Gates)

  • 정보의 선택적 전달을 담당
  • 시그모이드 신경망 층과 포인트와이즈 곱셈으로 구성
  • 0(완전 차단)에서 1(완전 통과) 사이의 값 출력

5. LSTM의 상세 작동 방식

5.1 망각 게이트(Forget Gate)

  • 어떤 정보를 버릴지 결정
  • 이전 출력(h_{t-1})과 현재 입력(x_t)을 바탕으로 판단
  • 0과 1 사이의 값을 출력하여 정보의 보존 정도 결정

5.2 입력 게이트(Input Gate)

  • 새로운 정보의 저장을 담당
  • 두 부분으로 구성:
    1. 갱신할 값 결정(시그모이드 층)
    2. 새로운 후보 값 생성(tanh 층)

5.3 셀 상태 갱신

  • 이전 상태를 망각 게이트로 필터링
  • 새로운 후보 값을 입력 게이트로 필터링
  • 두 정보를 결합하여 새로운 셀 상태 생성

5.4 출력 게이트(Output Gate)

  • 필터링된 셀 상태를 기반으로 출력 결정
  • 시그모이드 층으로 출력할 부분 선택
  • tanh를 통해 -1에서 1 사이의 값으로 변환

6. LSTM의 변형

6.1 Peephole 연결

  • Gers & Schmidhuber(2000)가 소개
  • 게이트 층이 셀 상태를 볼 수 있도록 함
  • 모든 게이트 또는 일부 게이트에 적용 가능

6.2 망각과 입력 게이트 결합

  • 망각과 입력을 동시에 결정
  • 새로운 정보를 입력할 때만 이전 정보를 잊음
  • 더 효율적인 정보 관리 가능

6.3 GRU(Gated Recurrent Unit)

  • Cho et al.(2014)이 소개
  • 망각과 입력 게이트를 "업데이트 게이트"로 통합
  • 셀 상태와 숨겨진 상태를 병합
  • 단순화된 구조로 인한 성능 향상

7. 결론 및 미래 전망

7.1 LSTM의 성과

  • 다양한 시퀀스 처리 작업에서 뛰어난 성능
  • 음성 인식, 언어 모델링, 번역, 이미지 캡셔닝 등에서 성공적

7.2 attention 메커니즘

  • LSTM 이후의 주요 발전 방향
  • 각 단계에서 더 큰 정보 집합에서 선택적으로 정보를 활용
  • 이미지 캡셔닝 등에서 성공적으로 적용

7.3 미래 연구 방향

  • Grid LSTM
  • 생성 모델에서의 RNN 활용
  • 새로운 구조와 적용 분야의 지속적 발전

 

RNN 정규화의 모든 것: LSTM을 중심으로

목차

  1. 서론
  2. RNN과 LSTM의 정규화
  3. 드롭아웃을 활용한 LSTM 정규화
  4. 실험 결과 분석
  5. 적용 사례 연구
  6. 구현 가이드
  7. 결론 및 향후 연구 방향

1. 서론

1.1 연구 배경

RNN은 시퀀스 모델링 분야에서 state-of-the-art 성능을 달성하고 있습니다. 주요 적용 분야:

  • 언어 모델링
  • 음성 인식
  • 기계 번역

1.2 문제점

기존 신경망의 가장 강력한 정규화 방법인 드롭아웃이 RNN에서 잘 동작하지 않는 문제가 있었습니다.

  • 오버피팅 문제
  • 모델 크기 제한
  • 성능 저하

2. RNN과 LSTM의 정규화

2.1 LSTM 구조

def lstm_step(self, x, prev_h, prev_c):
    # Gates
    i = sigmoid(Wxi @ x + Whi @ prev_h + bi)  # input gate
    f = sigmoid(Wxf @ x + Whf @ prev_h + bf)  # forget gate
    o = sigmoid(Wxo @ x + Who @ prev_h + bo)  # output gate
    g = tanh(Wxg @ x + Whg @ prev_h + bg)     # cell input
    
    # Update cell and hidden state
    c = f * prev_c + i * g
    h = o * tanh(c)
    
    return h, c

2.2 기존 정규화 방법의 한계

  1. 일반적인 드롭아웃 적용시 문제점
    • 순환 연결의 노이즈 증폭
    • 장기 의존성 학습 저하
    • 불안정한 학습 과정
  2. 기존 해결 시도
    • 작은 모델 사용
    • 간소화된 구조
    • 제한적인 성능 향상

3. 드롭아웃을 활용한 LSTM 정규화

3.1 새로운 접근 방법

핵심 아이디어: 비순환 연결에만 드롭아웃 적용

def regularized_lstm_step(self, x, prev_h, prev_c):
    # Apply dropout only to non-recurrent connections
    x_dropped = dropout(x, p=0.5)
    
    # Gates with dropout
    i = sigmoid(Wxi @ x_dropped + Whi @ prev_h + bi)
    f = sigmoid(Wxf @ x_dropped + Whf @ prev_h + bf)
    o = sigmoid(Wxo @ x_dropped + Who @ prev_h + bo)
    g = tanh(Wxg @ x_dropped + Whg @ prev_h + bg)
    
    c = f * prev_c + i * g
    h = o * tanh(c)
    
    return h, c

3.2 장점

  1. 정보 보존
    • 장기 의존성 유지
    • 안정적인 메모리 셀 상태
  2. 효과적인 정규화
    • 과적합 방지
    • 견고한 특징 학습

4. 실험 결과 분석

4.1 언어 모델링 실험 (Penn Tree Bank)

중형 LSTM 모델

  • 설정
    • 2개 층
    • 층당 650 유닛
    • 드롭아웃 비율: 50%
    • 학습률: 1.0 (6 에폭 후 1.2 비율로 감소)
    • 배치 크기: 20
    • 그래디언트 클리핑: 5.0
  • 결과
    • 검증 세트 퍼플렉서티: 86.2
    • 테스트 세트 퍼플렉서티: 82.7

대형 LSTM 모델

  • 설정
    • 2개 층
    • 층당 1500 유닛
    • 드롭아웃 비율: 65%
    • 학습률: 1.0 (14 에폭 후 1.15 비율로 감소)
    • 그래디언트 클리핑: 10.0
  • 결과
    • 검증 세트 퍼플렉서티: 82.2
    • 테스트 세트 퍼플렉서티: 78.4

4.2 음성 인식 실험

아이슬란드어 음성 데이터셋 결과:

  • 학습 세트 정확도: 69.4%
  • 검증 세트 정확도: 70.5%

4.3 기계 번역 실험

영어-프랑스어 번역 태스크:

  • 테스트 퍼플렉서티: 5.0
  • 테스트 BLEU 점수: 29.03

5. 적용 사례 연구

5.1 이미지 캡션 생성

  • 비정규화 모델: 퍼플렉서티 8.47, BLEU 23.5
  • 정규화 모델: 퍼플렉서티 7.99, BLEU 24.3
  • 앙상블 모델(10개): 퍼플렉서티 7.5, BLEU 24.4

5.2 모델 앙상블 효과

  • 단일 정규화 모델이 앙상블에 근접한 성능
  • 구현 및 유지보수 용이성
  • 계산 비용 절감

6. 구현 가이드

6.1 정규화 LSTM 구현

class RegularizedLSTM(nn.Module):
    def __init__(self, input_size, hidden_size, dropout=0.5):
        super().__init__()
        self.hidden_size = hidden_size
        self.dropout = dropout
        
        # Gates
        self.xi = nn.Linear(input_size, hidden_size)
        self.hi = nn.Linear(hidden_size, hidden_size, bias=False)
        self.xf = nn.Linear(input_size, hidden_size)
        self.hf = nn.Linear(hidden_size, hidden_size, bias=False)
        self.xo = nn.Linear(input_size, hidden_size)
        self.ho = nn.Linear(hidden_size, hidden_size, bias=False)
        self.xg = nn.Linear(input_size, hidden_size)
        self.hg = nn.Linear(hidden_size, hidden_size, bias=False)
        
    def forward(self, x, h, c):
        # Apply dropout only to input connections
        if self.training:
            x = F.dropout(x, p=self.dropout)
            
        # Gate computations
        i = torch.sigmoid(self.xi(x) + self.hi(h))
        f = torch.sigmoid(self.xf(x) + self.hf(h))
        o = torch.sigmoid(self.xo(x) + self.ho(h))
        g = torch.tanh(self.xg(x) + self.hg(h))
        
        # Update states
        c_next = f * c + i * g
        h_next = o * torch.tanh(c_next)
        
        return h_next, c_next

6.2 학습 팁

  1. 하이퍼파라미터 설정
    • 드롭아웃 비율: 0.3-0.7
    • 학습률: 0.5-2.0
    • 그래디언트 클리핑: 5.0-10.0
  2. 최적화 전략
    • 학습률 스케줄링
    • 배치 크기 조정
    • 모델 크기 선택

7. 결론 및 향후 연구 방향

7.1 주요 성과

  1. 효과적인 RNN 정규화 방법 제시
  2. 다양한 태스크에서 성능 향상
  3. 구현 용이성과 확장성

7.2 향후 연구 방향

  1. 다른 RNN 구조에 적용
  2. 하이브리드 정규화 기법 개발
  3. 자동 하이퍼파라미터 최적화

7.3 실무 적용 제안

  1. 태스크별 최적 설정 실험
  2. 모델 크기와 정규화 강도 조절
  3. 앙상블 방법과의 조합