본문 바로가기
AI/Deep-Learning

LSTM(Long Short-Term Memory)

by Wikinist 2023. 9. 18.

LSTM은 "Long Short-Term Memory"의 약어로, 순환 신경망(Recurrent Neural Network, RNN) 아키텍처의 한 종류입니다. LSTM은 시퀀스 데이터를 처리하고 장기적인 의존성을 학습하는 데 사용되며, 주로 자연어 처리 및 시계열 예측과 같은 응용 분야에서 널리 사용됩니다.

LSTM은 RNN의 한계를 극복하기 위해 개발되었는데, RNN은 긴 시퀀스 데이터에 대한 학습에서 그래디언트 소실 혹은 폭발 문제를 가지고 있습니다. 이로 인해 RNN은 긴 시퀀스에 대한 정보를 적절히 유지하지 못하는 경향이 있습니다. LSTM은 이러한 문제를 해결하기 위해 다음과 같은 주요 구성 요소를 도입했습니다.

주요 구성요소

Cell State (셀 상태): LSTM은 고정된 길이의 메모리 셀 상태를 유지합니다. 이 셀 상태는 장기적인 의존성 정보를 저장하고 전달하는 역할을 합니다.

Hidden State (은닉 상태): LSTM은 현재 시점의 입력과 이전 시점의 은닉 상태를 사용하여 현재 시점의 은닉 상태를 계산합니다. 이 은닉 상태는 현재 시점의 출력 및 다음 시점의 입력으로 전달되며, 단기적인 의존성 정보를 저장하고 전달합니다.

게이트 (Gate) 메커니즘: LSTM은 게이트 메커니즘을 사용하여 정보의 흐름을 제어합니다. 주요한 게이트는 다음과 같습니다.

  • Forget Gate (삭제 게이트): 이전 셀 상태로부터 어떤 정보를 삭제할지 결정합니다.
  • Input Gate (입력 게이트): 현재 입력에서 어떤 정보를 셀 상태에 추가할지 결정합니다.
  • Output Gate (출력 게이트): 현재 셀 상태로부터 어떤 정보를 은닉 상태로 출력할지 결정합니다.

이러한 게이트 메커니즘들은 학습 가능한 가중치로 제어되며, 학습 과정에서 최적의 값을 찾아내어 장기 및 단기 의존성을 효과적으로 관리합니다.

LSTM은 긴 시퀀스 데이터에서도 장기적인 의존성을 쉽게 학습할 수 있으며, 이전의 RNN보다 더 효과적으로 다양한 응용 분야에서 사용됩니다. 예를 들어, 기계 번역, 음성 인식, 주식 가격 예측, 텍스트 생성 등 다양한 자연어 처리 및 시계열 데이터 분석 작업에서 LSTM이 활용됩니다.

예제

LSTM을 사용한 예제 중 하나는 텍스트 생성입니다. LSTM을 활용하여 주어진 텍스트 데이터를 학습하고, 새로운 텍스트를 생성할 수 있습니다. 다음은 Python과 TensorFlow/Keras를 사용하여 간단한 텍스트 생성 모델을 구축하는 예제입니다:

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import LSTM, Dense
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 텍스트 데이터 준비
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

# 텍스트를 토큰화
tokenizer = Tokenizer()
tokenizer.fit_on_texts([text])
total_words = len(tokenizer.word_index) + 1

# 입력 시퀀스와 레이블 생성
input_sequences = []
for line in text.split('\n'):
    token_list = tokenizer.texts_to_sequences([line])[0]
    for i in range(1, len(token_list)):
        n_gram_sequence = token_list[:i+1]
        input_sequences.append(n_gram_sequence)

# 패딩을 추가하여 입력 데이터 준비
max_sequence_length = max([len(x) for x in input_sequences])
input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_length, padding='pre')

# 입력 시퀀스와 레이블 분리
X = input_sequences[:,:-1]
y = input_sequences[:,-1]

# 레이블을 원-핫 인코딩
y = tf.keras.utils.to_categorical(y, num_classes=total_words)

# LSTM 모델 구축
model = keras.Sequential()
model.add(Embedding(total_words, 64, input_length=max_sequence_length-1))
model.add(LSTM(100))
model.add(Dense(total_words, activation='softmax'))

# 모델 컴파일
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# 모델 학습
model.fit(X, y, epochs=100, verbose=1)

# 텍스트 생성 함수
def generate_text(seed_text, next_words, model, max_sequence_length):
    for _ in range(next_words):
        token_list = tokenizer.texts_to_sequences([seed_text])[0]
        token_list = pad_sequences([token_list], maxlen=max_sequence_length-1, padding='pre')
        predicted = model.predict_classes(token_list, verbose=0)
        output_word = ""
        for word, index in tokenizer.word_index.items():
            if index == predicted:
                output_word = word
                break
        seed_text += " " + output_word
    return seed_text

# 텍스트 생성 예제
generated_text = generate_text("Lorem ipsum", 10, model, max_sequence_length)
print(generated_text)

이 예제는 주어진 텍스트 데이터를 사용하여 LSTM 모델을 학습하고, "Lorem ipsum"이라는 초기 시드(seed) 텍스트를 주면 모델이 이어지는 텍스트를 생성합니다. 생성된 텍스트는 모델의 학습 데이터에 있는 단어와 문장 구조를 따라갑니다.

이것은 LSTM을 사용한 간단한 텍스트 생성 예제의 일부입니다. LSTM은 다양한 응용 분야에서 사용될 수 있으며, 데이터 유형 및 작업에 따라 다양한 방식으로 활용됩니다.

Bidirectional LSTM 예제

Bidirectional LSTM을 사용하여 단어 예측 모델을 학습하고 결과를 확인할 수 있는 코드를 제공해 드리겠습니다. 이 코드는 Python과 TensorFlow 라이브러리를 기반으로 작성되었습니다. 먼저 TensorFlow를 설치해야 합니다.

pip install tensorflow

그런 다음 다음과 같은 코드를 사용하여 Bidirectional LSTM을 사용한 단어 예측 모델을 생성하고 학습합니다.

import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 예제 데이터 생성
sentences = [
    'I love deep learning',
    'I enjoy natural language processing',
    'Bidirectional LSTM is powerful',
    'This is a simple example'
]
tokenizer = Tokenizer()
tokenizer.fit_on_texts(sentences)
total_words = len(tokenizer.word_index) + 1

# 문장을 시퀀스로 변환
input_sequences = []
for line in sentences:
    token_list = tokenizer.texts_to_sequences([line])[0]
    for i in range(1, len(token_list)):
        n_gram_sequence = token_list[:i+1]
        input_sequences.append(n_gram_sequence)

# 시퀀스를 패딩하여 동일한 길이로 만듦
max_sequence_length = max([len(x) for x in input_sequences])
input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_length, padding='pre')

# 입력 시퀀스와 레이블 생성
X = input_sequences[:, :-1]
y = input_sequences[:, -1]

# 레이블을 one-hot 인코딩
y = tf.keras.utils.to_categorical(y, num_classes=total_words)

# 모델 생성
model = tf.keras.Sequential([
    tf.keras.layers.Embedding(total_words, 64, input_length=max_sequence_length-1),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
    tf.keras.layers.Dense(total_words, activation='softmax')
])

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# 모델 학습
model.fit(X, y, epochs=100, verbose=1)

# 다음 단어 예측 함수 정의
def predict_next_word(seed_text, num_next_words):
    for _ in range(num_next_words):
        token_list = tokenizer.texts_to_sequences([seed_text])[0]
        token_list = pad_sequences([token_list], maxlen=max_sequence_length-1, padding='pre')
        predicted = model.predict_classes(token_list, verbose=0)
        output_word = ""
        for word, index in tokenizer.word_index.items():
            if index == predicted:
                output_word = word
                break
        seed_text += " " + output_word
    return seed_text

# 예측 결과 확인
seed_text = "I love"
predicted_text = predict_next_word(seed_text, num_next_words=5)
print(predicted_text)

Bidirectional LSTM 모델에서는 입력 시퀀스가 양방향으로 처리됩니다. 따라서 "I love deep learning"이라는 문장에 대한 학습 과정은 다음과 같이 진행됩니다:

순방향 학습 (Forward Pass): 모델은 "I", "love", "deep", "learning" 순서로 입력을 받아 처리합니다. 이때 "I"를 입력으로 받고 "love"를 예측하고, "I love"를 입력으로 받고 "deep"을 예측하며, "I love deep"를 입력으로 받고 "learning"을 예측합니다.

역방향 학습 (Backward Pass): 모델은 입력 시퀀스를 역방향으로 처리합니다. 즉, "learning", "deep", "love", "I" 순서로 입력을 받아 처리합니다. 이때 "learning"을 입력으로 받고 "deep"을 예측하고, "learning deep"을 입력으로 받고 "love"를 예측하며, "learning deep love"를 입력으로 받고 "I"를 예측합니다.

양방향 LSTM에서는 순방향과 역방향 결과를 결합하여 최종 예측을 수행합니다. 따라서 "I love deep learning" 문장에서 "learning"을 예측하기 위해서는 모델이 "I love deep" 및 "learning deep love"와 같은 문맥을 함께 고려합니다.

이러한 양방향 처리는 주어진 단어의 문맥을 더 잘 이해하고 예측을 개선하는 데 도움이 될 수 있습니다.

해당 게시글은 ChatGPT의 도움을 받아 작성되었습니다.

'AI > Deep-Learning' 카테고리의 다른 글

[Keras] EarlyStopping  (0) 2023.09.21
[Keras] Sequential 모델과 Dense, Dropout  (0) 2023.09.21
[TensorFlow] Tokenizer  (0) 2023.09.13
순환신경망(Recurrent Neural Network, RNN)  (0) 2023.09.13
풀링 레이어 (Pooling Layer)  (0) 2023.09.13