
📓Google Colab에서 실습하기
이 레슨은 PyTorch/GPU가 필요합니다. 노트북을 다운로드 후 Google Colab에서 열어주세요.
학습 내용
시퀀스 데이터란 무엇인가?
학습 목표
이 레슨을 완료하면:
- •시퀀스 데이터가 무엇인지 자신만의 말로 설명할 수 있다
- •시계열, 텍스트, 음성 데이터의 공통점을 파악할 수 있다
- •왜 일반 신경망(MLP, CNN)으로는 시퀀스를 다루기 어려운지 이해한다
- •시퀀스 전용 모델(RNN)이 왜 필요한지 직관적으로 납득한다
핵심 메시지
"순서가 바뀌면 의미가 달라진다 -- 그것이 시퀀스 데이터의 본질이다." 이미지는 픽셀을 뒤섞어도 색 분포는 비슷하지만, 문장의 단어 순서를 바꾸면 뜻 자체가 달라집니다. 이번 레슨에서는 "순서"가 왜 그렇게 중요한지, 그리고 그 순서를 어떻게 학습할 수 있는지를 알아봅니다.
비유로 시작하기: 문장을 한 단어씩 읽는 과정
비유: 여러분이 소설책을 읽고 있다고 상상해 보세요. 첫 페이지에서 주인공 이름을 알게 되고, 두 번째 페이지에서 배경이 나오고, 세 번째 페이지에서 사건이 벌어집니다. 만약 페이지를 무작위로 섞어서 읽으면 어떻게 될까요? 이야기를 전혀 이해할 수 없을 것입니다.
시퀀스 데이터도 마찬가지입니다. 데이터가 나열된 "순서" 자체가 정보의 핵심입니다.
간단한 예를 들어 보겠습니다.
| 문장 | 의미 |
|---|---|
| "안녕하세요" | ✅ 의미가 통하는 인사말 |
| "하녕안세요" | ❌ 같은 글자들이지만 의미 없음 |
⚠️ 순서가 바뀌면 정보가 파괴됩니다!
시퀀스 데이터의 세 가지 대표 유형
| 유형 | 예시 | 순서의 의미 |
|---|---|---|
| 시계열(Time Series) | 주가, 기온, 심박수, 센서 데이터 | 시간이 흐르는 방향으로 나열 |
| 텍스트(Text) | 문장, 대화, 뉴스 기사 | 단어/글자가 앞에서 뒤로 나열 |
| 음성(Audio) | 목소리, 음악, 환경 소리 | 소리 파형이 시간 축을 따라 변화 |
세 가지 유형 모두 "앞의 것을 보아야 뒤의 것을 이해할 수 있다" 는 공통점을 가집니다.
시계열 데이터 자세히 보기
시계열이란?
시계열 데이터는 일정한 시간 간격으로 기록된 숫자들의 나열입니다.
| 요일 | 가격 | 변화 |
|---|---|---|
| 월요일 | 100원 | - |
| 화요일 | 105원 | +5 📈 |
| 수요일 | 103원 | -2 📉 |
| 목요일 | 108원 | +5 📈 |
| 금요일 | ??? | 내일은 얼마일까? |
💡 핵심: "어제까지의 흐름"을 알아야 "내일"을 예측할 수 있습니다. 순서를 무시하고 평균(104원)만 안다면 추세를 알 수 없습니다.
실행해보기: 시계열 데이터 시각화
아래 코드는 간단한 주가 시뮬레이션을 만들고 시각화합니다. 순서대로 보았을 때 "추세"가 보이지만, 순서를 섞으면 패턴이 사라지는 것을 확인해 보세요.
pythonimport numpy as np import matplotlib.pyplot as plt # 1) 간단한 주가 시뮬레이션 np.random.seed(42) days = 60 prices = [100.0] for i in range(days - 1): change = 0.3 + np.random.normal(0, 2) prices.append(prices[-1] + change) prices = np.array(prices) # 2) 순서를 섞은 버전 shuffled = prices.copy() np.random.shuffle(shuffled) # 3) 시각화: 원본 vs 셔플 fig, axes = plt.subplots(1, 2, figsize=(12, 4)) axes[0].plot(prices, color="steelblue", linewidth=1.5) axes[0].set_title("Original (order preserved)") axes[0].set_xlabel("Day") axes[0].set_ylabel("Price") axes[1].plot(shuffled, color="coral", linewidth=1.5) axes[1].set_title("Shuffled (order destroyed)") axes[1].set_xlabel("Day") axes[1].set_ylabel("Price") plt.tight_layout() plt.savefig("sequence_order.png", dpi=100) plt.show() print("Original -- trend is visible.") print("Shuffled -- no pattern at all!")
왼쪽 그래프에서는 "서서히 올라가는 추세"가 보이지만, 오른쪽은 같은 숫자들이 뒤섞여서 아무 패턴도 보이지 않습니다. 순서가 정보의 핵심이라는 사실을 한눈에 확인할 수 있습니다.
텍스트 데이터 자세히 보기
단어 순서가 의미를 결정한다
| 문장 | 가해자 |
|---|---|
| "개가 사람을 물었다" | 🐕 개 |
| "사람이 개를 물었다" | 👤 사람 (!!) |
💡 같은 단어 4개가 순서만 바뀌었을 뿐인데, 뜻이 완전히 달라집니다.
문맥(Context)이 단어의 뜻을 결정한다
| 문장 | "사과"의 의미 |
|---|---|
| "빨간 사과가 맛있다" | 🍎 과일 |
| "진심으로 사과드립니다" | 🙏 용서를 구하는 행위 |
💡 같은 단어라도 앞뒤 단어(문맥)를 보아야 정확한 의미를 알 수 있습니다. AI가 텍스트를 이해하려면 "이전에 어떤 단어가 나왔는지"를 기억해야 합니다.
텍스트 시퀀스가 쓰이는 곳
| 응용 분야 | 하는 일 | 왜 순서가 중요한가 |
|---|---|---|
| 챗봇 / 대화 AI | 사용자 질문에 답변 | 대화 흐름을 기억해야 적절한 답 가능 |
| 기계 번역 | 한국어 -> 영어 | 문장 구조가 언어마다 다름 |
| 감성 분석 | 리뷰 긍정/부정 판단 | "나쁘지 않다"는 긍정 -- 순서가 의미 결정 |
| 자동 완성 | 다음 단어 예측 | 이전 단어를 보고 다음을 추론 |
음성 데이터 자세히 보기
🔊 소리는 공기의 진동이 시간에 따라 변하는 **파형(waveform)**입니다.
| 시점 | 소리 |
|---|---|
| 0.0초 | "아~" 소리의 파형 |
| 0.1초 | "ㄴ" 소리로 전환 |
| 0.2초 | "녕" 소리의 파형 |
⚠️ 이 순서가 바뀌면 "녕안" 같은 이상한 소리가 됩니다. 음성 인식 AI도 소리를 "시간 순서대로" 분석해야 합니다.
실행해보기: 간단한 파형 시각화
pythonimport numpy as np import matplotlib.pyplot as plt sr = 1000 t1 = np.linspace(0, 0.3, int(sr * 0.3), endpoint=False) t2 = np.linspace(0.3, 0.6, int(sr * 0.3), endpoint=False) wave1 = np.sin(2 * np.pi * 200 * t1) # 200 Hz wave2 = np.sin(2 * np.pi * 600 * t2) # 600 Hz signal = np.concatenate([wave1, wave2]) time_axis = np.concatenate([t1, t2]) plt.figure(figsize=(10, 3)) plt.plot(time_axis, signal, color="mediumpurple", linewidth=0.8) plt.axvline(x=0.3, color="red", linestyle="--", label="Frequency change") plt.title("Simple waveform: low freq -> high freq") plt.xlabel("Time (s)") plt.ylabel("Amplitude") plt.legend() plt.tight_layout() plt.savefig("waveform.png", dpi=100) plt.show() print("0~0.3s: 200Hz (low), 0.3~0.6s: 600Hz (high)") print("The ORDER of frequencies carries meaning!")
왜 일반 신경망(MLP, CNN)으로는 부족한가?
지금까지 배운 일반 신경망(완전연결층, MLP)이나 합성곱 신경망(CNN)은 각 입력을 독립적으로 처리합니다.
문제 1: 순서 무시
| 모델 | 입력 [100, 105, 103, 108] 처리 방식 |
|---|---|
| MLP | ❌ 4개의 숫자를 "동시에" 독립적으로 처리 → 순서 정보 손실 |
| 시퀀스 모델 | ✅ 100을 보고 → 그 기억으로 105를 보고 → "오르다가 내렸다가 다시 올랐다" 흐름 학습 |
문제 2: 고정된 입력 크기
| 모델 | 입력 크기 | 문제점 |
|---|---|---|
| MLP | 고정 | 10단어용 ≠ 100단어용 → 길이마다 별도 모델 필요? ❌ |
| RNN | 가변 | 5단어든 500단어든 같은 모델로 처리 가능 ✅ |
문제 3: 기억 능력 없음
"The cat sat on the ___"
다음 단어를 예측하려면 앞에 나온 "cat"을 기억해야 합니다. MLP는 입력을 한꺼번에 받아서 처리하므로 **"어떤 단어가 먼저 나왔는지"**를 구분하지 못합니다.
실행해보기: 순서를 무시하면 예측이 불가능함을 체험
pythonimport numpy as np data = np.arange(1, 21) X, y = [], [] for i in range(len(data) - 4): X.append(data[i:i+4]) y.append(data[i+4]) X = np.array(X) y = np.array(y) print("=== Original (order preserved) ===") for i in range(5): print(f" Input: {X[i]} -> Target: {y[i]}") X_shuffled = X.copy() for i in range(len(X_shuffled)): np.random.shuffle(X_shuffled[i]) print() print("=== Shuffled (order destroyed) ===") for i in range(5): print(f" Input: {X_shuffled[i]} -> Target: {y[i]}") print() print("Shuffled input [3,1,4,2] -- next number 5? or 3?") print("Impossible to tell! Order is ESSENTIAL.")
그래서 등장한 것이 RNN
비유: RNN은 "메모장을 들고 책을 읽는 사람"과 같습니다. 한 문장을 읽을 때마다 메모장에 핵심 내용을 적어 두고, 다음 문장을 읽을 때 메모장을 참고합니다. 이 메모장이 바로 Hidden State(은닉 상태) 입니다.
RNN의 기본 아이디어:
[입력1] -----> 처리 -----> h1 (메모 저장)
[입력2] + h1 --> 처리 --> h2 (메모 업데이트)
[입력3] + h2 --> 처리 --> h3 (메모 업데이트)
...
각 단계에서:
현재 입력 + 이전 메모 --> 새로운 메모
이렇게 하면 순서 정보가 자연스럽게 유지됩니다.
RNN이 해결하는 세 가지 문제
| MLP/CNN의 한계 | RNN의 해결 방식 |
|---|---|
| 순서를 무시함 | 하나씩 순서대로 읽으며 Hidden State로 순서 기억 |
| 고정 크기 입력 | 가변 길이 시퀀스를 동일 모델로 처리 |
| 기억 없음 | Hidden State가 과거 정보를 축적 |
실행해보기: 간단한 시계열 패턴 예측 (numpy)
아래는 "sin 곡선의 다음 값을 맞추기" 라는 아주 단순한 시퀀스 예측입니다. 과거 5개 값을 보고 다음 1개 값을 예측하는데, "이동 평균"이라는 간단한 방법으로도 순서 정보를 활용하면 제법 괜찮은 예측이 가능합니다.
pythonimport numpy as np import matplotlib.pyplot as plt t = np.linspace(0, 4 * np.pi, 200) signal = np.sin(t) + np.random.normal(0, 0.1, len(t)) window_size = 5 predictions = [] actuals = [] for i in range(window_size, len(signal)): past = signal[i - window_size:i] pred = np.mean(past) predictions.append(pred) actuals.append(signal[i]) predictions = np.array(predictions) actuals = np.array(actuals) plt.figure(figsize=(12, 4)) plt.plot(actuals, label="Actual", color="steelblue", alpha=0.8) plt.plot(predictions, label="Prediction (moving avg)", color="coral", linestyle="--") plt.title("Simple sequence prediction using past values") plt.xlabel("Time step") plt.ylabel("Value") plt.legend() plt.tight_layout() plt.savefig("seq_prediction.png", dpi=100) plt.show() mse = np.mean((predictions - actuals) ** 2) print(f"Mean Squared Error: {mse:.4f}") print("Even a simple moving average works because it uses ORDER information!") print("RNN does something similar but LEARNS the best way to combine past values.")
이 예제에서 이동 평균은 "과거 5개 값"이라는 순서 정보를 활용합니다. RNN은 이와 비슷하지만, 어떻게 과거 값을 조합할지를 자동으로 학습합니다.
시퀀스 데이터 vs 정적 데이터 비교
| 특성 | 정적 데이터 (이미지, 표) | 시퀀스 데이터 (텍스트, 음성, 시계열) |
|---|---|---|
| 순서 | 무관하거나 공간적 | 시간적/순차적 -- 매우 중요 |
| 대표 모델 | MLP, CNN | RNN, LSTM, GRU, Transformer |
| 입력 크기 | 보통 고정 | 가변 길이가 자연스러움 |
| 핵심 패턴 | 공간적 특징 (엣지, 형태) | 시간적 의존성 (추세, 문맥) |
| 예시 과제 | 고양이/개 분류 | 다음 단어 예측, 주가 예측 |
핵심 요약
| 개념 | 설명 | 비유 |
|---|---|---|
| 시퀀스 데이터 | 순서가 중요한 데이터 | 소설책의 페이지 순서 |
| 시계열 | 시간에 따라 기록된 숫자 | 매일 적는 일기장 |
| 텍스트 | 단어/글자가 순서대로 나열 | 한 글자씩 읽는 문장 |
| 음성 | 시간 축을 따르는 파형 | 노래 가사가 순서대로 흘러가는 것 |
| MLP/CNN 한계 | 순서 무시, 기억 없음 | 페이지를 섞어 놓은 책 |
| RNN | Hidden State로 순서 기억 | 메모장을 들고 책 읽는 사람 |
학습 체크리스트
- • 시퀀스 데이터가 무엇인지 한 문장으로 설명할 수 있다
- • 시계열, 텍스트, 음성 세 유형의 공통점을 말할 수 있다
- • 순서를 섞으면 왜 정보가 파괴되는지 예를 들어 설명할 수 있다
- • MLP/CNN이 시퀀스를 잘 못 다루는 이유 세 가지를 알고 있다
- • RNN의 Hidden State가 어떤 역할을 하는지 비유로 설명할 수 있다
다음 레슨 예고
다음 시간에는 RNN이 구체적으로 어떻게 동작하는지 -- 순환 구조, 은닉 상태 계산, 파라미터 공유 등을 numpy 코드로 직접 구현하며 배워봅니다.
레슨 정보
- 레벨
- Level 6: 시퀀스 모델 (RNN/LSTM)
- 예상 소요 시간
- 30분
- 참고 영상
- YouTube 링크
💡실습 환경 안내
이 레벨은 PyTorch/GPU가 필요하여 Google Colab 사용을 권장합니다.
Colab은 무료 GPU를 제공하여 PyTorch, CNN, Transformer 등을 실행할 수 있습니다.