콘텐츠로 이동

5차시: 다층 신경망 - TensorFlow Playground로 XOR 정복하기

⏰ 80분 · 은닉층 · 비선형 분류 · TensorFlow Playground · Keras · 난이도 ●●●○○

학습목표: 은닉층이 비선형 문제를 해결하는 원리를 설명하고, TensorFlow Playground와 Keras로 XOR 문제를 직접 해결합니다.

오늘의 질문: “한 개의 자로는 그릴 수 없는 경계를, 두 개의 자를 합치면 그릴 수 있을까요?”


뉴런을 여러 층으로 쌓으면 왜 곡선 경계가 만들어지는지 이해합니다

TensorFlow Playground에서 층과 뉴런을 바꿔가며 XOR·원형·나선형 데이터를 분류합니다

Dense 두 줄로 XOR을 학습시키는 신경망을 직접 작성합니다

시뮬레이터 조작과 코드 한 줄을 연결해 “무엇이 학습되었는지” 설명합니다


지난 시간 단층 퍼셉트론이 XOR에서 실패한 이유를 5분 복습합니다. 종이에 직선 하나로 XOR 네 점을 분리해 보며 “직선이 부족하다”는 체험을 공유합니다.

TensorFlow Playground에 접속해 XOR 데이터를 불러오고, 은닉층 1개·뉴런 2-4개로 학습을 돌립니다. 결정 경계가 곡선으로 휘는 과정을 관찰하고, 각 뉴런의 작은 그림을 해석합니다.

3단계: 층 수와 뉴런 수 실험 (15분)

섹션 제목: “3단계: 층 수와 뉴런 수 실험 (15분)”

원형·나선형 데이터셋에서 층 수와 뉴런 수를 바꿔가며 언제 학습이 되고 언제 실패하는지 기록합니다. 모둠별 실험 결과를 표로 정리합니다.

Colab에서 Keras Sequential API로 Dense 2층 신경망을 만들어 XOR을 학습시킵니다. v1 단층 실패 → v2 은닉층 추가 → v3 활성화 함수 변경 순으로 진화시킵니다.

오늘의 질문에 스스로 답하고, 형성평가 2문항을 풉니다. 다음 차시(역전파) 예고로 마무리합니다.


개념 1. 왜 직선 하나로는 XOR을 풀 수 없는가

섹션 제목: “개념 1. 왜 직선 하나로는 XOR을 풀 수 없는가”

4차시 끝에서 만났던 XOR 데이터를 다시 떠올려 보겠습니다. 입력이 (0,0)과 (1,1)이면 출력은 0, (0,1)과 (1,0)이면 출력은 1입니다. 이 네 점을 평면에 찍으면 같은 클래스가 대각선 방향으로 놓입니다. 아무리 자를 기울여 봐도 직선 하나로는 0과 1을 가를 수 없습니다.

이 한계는 수학적으로 분명합니다. 단층 퍼셉트론의 결정 경계는 식 (1)과 같이 하나의 직선이기 때문입니다.

$ w_1 x_1 + w_2 x_2 + b = 0 \tag{1} $

여기서 $w_1, w_2$는 가중치, $b$는 편향입니다. 이 식은 평면에서 직선 하나만 그립니다. XOR처럼 선형 분리 불가능(linearly non-separable)한 데이터에는 근본적으로 맞지 않습니다.

해결 방법은 간단합니다. 자를 두 개 쓰면 됩니다. 자 하나로 “x₁이 크면 1”을 긋고, 다른 자로 “x₂가 크면 1”을 그은 다음, 두 결과를 똑똑하게 조합하면 XOR을 풀 수 있습니다. 이 “두 자를 조합하는 방”이 바로 은닉층입니다.


개념 2. 은닉층: 공간을 휘게 만드는 층

섹션 제목: “개념 2. 은닉층: 공간을 휘게 만드는 층”

은닉층은 입력을 받아 새로운 특성(feature)으로 변환합니다. 사진 보정 앱에서 원본 사진에 “밝기 필터”, “대비 필터”를 각각 적용한 뒤, 두 결과를 합쳐 새로운 사진을 만드는 것과 비슷합니다. 은닉층의 각 뉴런은 서로 다른 관점으로 입력을 바라보는 “필터”입니다.

정의를 분명히 하겠습니다. 은닉층은 입력층과 출력층 사이에 위치하며, 입력 벡터 $\mathbf{x}$를 비선형 함수로 변환해 다음 층에 전달하는 층입니다. 2층 신경망의 계산은 식 (2)와 같습니다.

$ \begin{aligned} \mathbf{h} &= \sigma(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) \ \hat{y} &= \sigma(\mathbf{W}_2 \mathbf{h} + \mathbf{b}_2) \end{aligned} \tag{2} $

첫 줄에서 입력 $\mathbf{x}$가 은닉 벡터 $\mathbf{h}$로 변환되고, 둘째 줄에서 $\mathbf{h}$가 최종 예측 $\hat{y}$로 변환됩니다. $\sigma$는 활성화 함수(ReLU나 시그모이드 등)로, 이것이 없으면 아무리 층을 쌓아도 직선 하나와 같습니다.

flowchart LR
    X1([x1]) --> H1[뉴런 1<br/>필터 A]
    X1 --> H2[뉴런 2<br/>필터 B]
    X2([x2]) --> H1
    X2 --> H2
    H1 --> Y[출력<br/>조합]
    H2 --> Y
    Y --> P([예측])

은닉층 뉴런 2개가 서로 다른 직선을 그리고, 출력층이 그 둘을 조합해 곡선 경계를 만드는 구조입니다.


개념 3. 활성화 함수: 비선형성의 원천

섹션 제목: “개념 3. 활성화 함수: 비선형성의 원천”

활성화 함수가 왜 필요한지는 간단한 논리로 알 수 있습니다. 활성화 함수 없이 층을 두 개 쌓으면 $\mathbf{W}_2(\mathbf{W}_1 \mathbf{x}) = (\mathbf{W}_2 \mathbf{W}_1)\mathbf{x}$가 되어, 결국 하나의 직선과 다를 바 없습니다. 층을 아무리 쌓아도 소용이 없습니다. 중간에 구부림을 넣어야 공간이 휘어집니다.

대표적인 활성화 함수 세 가지를 비교하겠습니다.

이름수식특징주 용도
시그모이드$\sigma(z) = \dfrac{1}{1+e^{-z}}$0-1 사이 부드러운 S자이진 분류 출력층
tanh$\tanh(z)$-1과 1 사이 S자은닉층(옛날 방식)
ReLU$\max(0, z)$음수는 0, 양수는 그대로은닉층(현재 표준)

현재 딥러닝에서 은닉층에는 ReLU가 거의 표준입니다. 계산이 빠르고 학습이 잘 되기 때문입니다. 출력층에서 0에서 1 사이 확률이 필요하면 시그모이드를 씁니다.


개념 4. 각 뉴런은 무엇을 배우는가

섹션 제목: “개념 4. 각 뉴런은 무엇을 배우는가”

TensorFlow Playground의 가장 훌륭한 기능은 각 뉴런 옆에 작은 그림을 보여준다는 점입니다. 이 그림은 해당 뉴런이 입력 공간을 어떻게 가르는지 보여줍니다. XOR 데이터에 은닉 뉴런 2개를 썼을 때 보통 다음 현상이 나타납니다.

  • 뉴런 1: “x₁ + x₂ > 0.5” 같은 왼쪽 아래 대각선을 긋습니다
  • 뉴런 2: “x₁ + x₂ > 1.5” 같은 오른쪽 위 대각선을 긋습니다
  • 출력층: 두 결과를 “첫째는 참, 둘째는 거짓일 때만 1” 식으로 조합합니다

이것은 AND와 OR로 XOR을 만드는 고전적인 방법과 정확히 같은 구조입니다. 다층 신경망이 학습하는 것은 문제를 부분 문제로 쪼개는 방법이라고 볼 수 있습니다.


🔧 실습 1. TensorFlow Playground로 XOR 정복

섹션 제목: “🔧 실습 1. TensorFlow Playground로 XOR 정복”

브라우저에서 다음 주소로 접속합니다.

playground.tensorflow.org

초기 화면이 뜨면 다음 순서로 설정합니다.

  1. DATA: 좌측 상단 4개 데이터셋 중 “Exclusive or” (XOR 패턴) 선택
  2. FEATURES: $X_1$과 $X_2$만 체크, 나머지(제곱·곱·사인) 전부 해제
  3. HIDDEN LAYERS: 1개 층, 뉴런 2개로 설정
  4. Activation: 우측 상단에서 “Tanh” 선택
  5. Learning rate: 0.03 (기본값)

좌측 상단 재생(▶) 버튼을 눌러 학습을 시작합니다.

학습이 진행되면서 다음을 기록합니다.

관찰 항목기록란
학습 시작 시 Test loss
1,000 epoch 후 Test loss
최종 결정 경계 모양(직선/곡선)
은닉 뉴런 1의 그림이 보여주는 경계선
은닉 뉴런 2의 그림이 보여주는 경계선

일반적으로 Test loss가 0.01 아래로 내려가면 성공입니다. 우측의 큰 그래프에서 경계선이 S자 또는 곡선 형태로 휘어진 모습을 볼 수 있습니다.

같은 XOR 데이터에 대해 다음 세 가지 설정을 비교합니다.

실험 번호은닉층 수뉴런 수예상 결과
A0 (단층)-실패. Loss가 0.25 근처에서 멈춤
B12성공. 곡선 경계
C14성공. 더 부드러운 경계

🔧 실습 2. 원형·나선형 데이터로 확장

섹션 제목: “🔧 실습 2. 원형·나선형 데이터로 확장”

XOR을 풀었다면 더 어려운 데이터에 도전합니다.

중심에 파란 점, 바깥 링에 주황 점이 있는 데이터입니다.

  • 시도 1: 은닉층 1개, 뉴런 2개 → 대부분 실패 (경계가 직선 조합으로만 가능)
  • 시도 2: 은닉층 1개, 뉴런 4개 → 원형 경계 형성
  • 시도 3: 은닉층 2개, 뉴런 4개+2개 → 매끄러운 원

두 나선이 서로 꼬여 있는 가장 어려운 데이터입니다.

구성결과
은닉 1층, 뉴런 4개거의 실패
은닉 2층, 뉴런 4+4부분 성공, 중심부 오류
은닉 3층, 뉴런 6+4+4성공, 나선을 따라 감김

관찰: 데이터가 복잡해질수록 층과 뉴런이 더 많이 필요합니다. 이것이 “딥”러닝이라고 부르는 이유입니다.


💻 실습 3. Keras로 XOR 직접 학습시키기

섹션 제목: “💻 실습 3. Keras로 XOR 직접 학습시키기”

Google Colab (colab.research.google.com)에서 새 노트북을 엽니다. Python 3.10+, TensorFlow 2.x가 이미 설치되어 있습니다.

v1. 먼저 “실패하는” 단층 퍼셉트론

섹션 제목: “v1. 먼저 “실패하는” 단층 퍼셉트론”

은닉층 없이 입력 → 출력으로 바로 연결하는 신경망입니다. XOR에서 실패하는지 직접 확인합니다.

import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# XOR 진리표 4개 샘플
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
y = np.array([[0], [1], [1], [0]], dtype=np.float32)
# 은닉층 없이 바로 출력층 (단층 퍼셉트론과 동치)
model_v1 = Sequential([
Dense(1, activation='sigmoid', input_shape=(2,)) # <- 여기가 단층 구조
])
model_v1.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
history = model_v1.fit(X, y, epochs=500, verbose=0)
# 결과 확인
print("최종 예측:")
print(model_v1.predict(X, verbose=0).round(2))
print(f"정확도: {history.history['accuracy'][-1]:.2f}")

실행 결과 예시:

최종 예측:
[[0.5 ]
[0.5 ]
[0.5 ]
[0.5 ]]
정확도: 0.50

네 개 모두 0.5로 예측합니다. 정확도 50%는 그냥 찍는 것과 같은 수준입니다. 4차시에서 예고했던 실패가 코드로도 재현되었습니다.

위 코드의 9번째 줄 Dense(1, activation='sigmoid', input_shape=(2,))가 바로 단층 퍼셉트론입니다. 은닉층이 없어서 XOR을 학습할 수 없습니다.


은닉층 하나를 추가합니다. 이것이 오늘 수업의 핵심입니다.

import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
y = np.array([[0], [1], [1], [0]], dtype=np.float32)
model_v2 = Sequential([
Dense(4, activation='tanh', input_shape=(2,)), # <- 여기가 은닉층 (뉴런 4개)
Dense(1, activation='sigmoid') # <- 여기가 출력층
])
model_v2.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
history = model_v2.fit(X, y, epochs=2000, verbose=0)
print("최종 예측:")
print(model_v2.predict(X, verbose=0).round(2))
print(f"정확도: {history.history['accuracy'][-1]:.2f}")

실행 결과 예시:

최종 예측:
[[0.03]
[0.97]
[0.97]
[0.04]]
정확도: 1.00

정확도 100%. (0,0)과 (1,1)은 0에 가깝고, (0,1)과 (1,0)은 1에 가깝게 예측합니다.

v1에서 10번째 줄 Dense(4, activation='tanh', ...) 한 줄만 추가했을 뿐인데 문제가 풀렸습니다. 이 한 줄이 개념 2의 식 (2)에서 $\mathbf{h} = \sigma(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1)$에 해당하는 은닉층입니다.


에러 경험: 활성화 함수를 빼면 어떻게 될까?

섹션 제목: “에러 경험: 활성화 함수를 빼면 어떻게 될까?”

은닉층만 있고 활성화 함수를 빼면 어떻게 되는지 직접 봅시다.

# 활성화 함수를 일부러 'linear'로 (= 활성화 없음)
model_err = Sequential([
Dense(4, activation='linear', input_shape=(2,)), # <- 비선형성 제거
Dense(1, activation='sigmoid')
])
model_err.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model_err.fit(X, y, epochs=2000, verbose=0)
print(model_err.predict(X, verbose=0).round(2))

실행 결과 예시:

[[0.5 ]
[0.5 ]
[0.5 ]
[0.5 ]]

은닉층이 있는데도 v1과 똑같이 실패합니다.

원인: activation='linear'는 $\sigma(z) = z$, 즉 아무 변환도 하지 않음과 같습니다. 그러면 $\mathbf{W}_2 \mathbf{W}_1 \mathbf{x}$가 되어 직선 하나와 수학적으로 동일해집니다. 개념 3에서 설명한 “활성화 함수가 비선형성의 원천”이라는 말이 코드로 증명된 순간입니다.---

v3. ReLU로 바꾸고 학습 시각화하기

섹션 제목: “v3. ReLU로 바꾸고 학습 시각화하기”

현대 딥러닝의 표준인 ReLU로 활성화 함수를 바꾸고, 학습 곡선을 그려 봅니다.

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
y = np.array([[0], [1], [1], [0]], dtype=np.float32)
model_v3 = Sequential([
Dense(4, activation='relu', input_shape=(2,)), # <- ReLU로 변경
Dense(1, activation='sigmoid')
])
model_v3.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
history = model_v3.fit(X, y, epochs=2000, verbose=0)
# 학습 곡선 그리기
plt.plot(history.history['loss'])
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('XOR 학습 곡선 (ReLU)')
plt.grid(True)
plt.show()
print("최종 예측:", model_v3.predict(X, verbose=0).round(2).flatten())

실행 결과 예시:

최종 예측: [0.02 0.98 0.98 0.02]

학습 곡선은 초반에 0.69 근처에서 시작해 급격히 떨어진 뒤 0에 가까워집니다. 0.69는 ln(2)로, 무작위 추측의 손실값입니다. 여기서 내려가기 시작하면 학습이 진행되고 있다는 신호입니다.


학습된 신경망이 실제로 어떤 경계선을 그렸는지 그림으로 확인합니다.

import numpy as np
import matplotlib.pyplot as plt
# 0-1 사이 격자점 생성
xx, yy = np.meshgrid(np.linspace(-0.2, 1.2, 100), np.linspace(-0.2, 1.2, 100))
grid = np.c_[xx.ravel(), yy.ravel()].astype(np.float32)
# 모든 격자점의 예측값
Z = model_v3.predict(grid, verbose=0).reshape(xx.shape)
plt.contourf(xx, yy, Z, levels=20, cmap='RdBu_r', alpha=0.7)
plt.colorbar(label='예측값')
# 실제 4개 XOR 점 표시
plt.scatter([0, 1], [0, 1], c='blue', s=200, label='클래스 0', edgecolors='black')
plt.scatter([0, 1], [1, 0], c='red', s=200, label='클래스 1', edgecolors='black')
plt.xlabel('x1'); plt.ylabel('x2')
plt.title('XOR 결정 경계')
plt.legend()
plt.show()

예상 결과: 대각선 방향으로 파란-빨강 영역이 번갈아 나타나는 곡선 경계가 보입니다. 직선이 아니라 휘어진 경계가 네 점을 정확히 나눕니다.


활동 유형: 모둠(4인) · 25분

활동 1. 뉴런 수 최소값 찾기 (10분)

섹션 제목: “활동 1. 뉴런 수 최소값 찾기 (10분)”

TensorFlow Playground에서 XOR 데이터에 대해 Test loss 0.05 이하를 달성할 수 있는 최소 뉴런 수를 찾습니다. 뉴런 1개, 2개, 3개 순으로 늘려가며 기록합니다.

은닉층 구성성공 여부학습 시간(epoch)
뉴런 1개
뉴런 2개
뉴런 3개

모둠별로 “우리가 찾은 최소 구조”와 “그 이유”를 1분씩 발표합니다.


XOR 대신 AND 진리표 [[0],[0],[0],[1]]을 학습시키는 코드를 작성하세요. 은닉층이 없어도 풀리는지 확인합니다.

힌트

AND는 선형 분리 가능한 문제입니다. 네 점을 그려 보면 하나의 직선으로 (1,1)만 분리할 수 있습니다. 단층으로 충분합니다.

정답 코드
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
X = np.array([[0,0],[0,1],[1,0],[1,1]], dtype=np.float32)
y = np.array([[0],[0],[0],[1]], dtype=np.float32)
model = Sequential([Dense(1, activation='sigmoid', input_shape=(2,))])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(X, y, epochs=1000, verbose=0)
print(model.predict(X, verbose=0).round(2))
# 예상: [[0.01], [0.06], [0.06], [0.93]]

입력이 3개인 “홀수 개의 1이 있으면 1을 출력”하는 문제를 신경망으로 풀어 보세요. 데이터는 8개 샘플입니다.

힌트

입력 3개, 출력 1개입니다. 은닉 뉴런은 4-8개 정도면 충분합니다. input_shape=(3,)로 바꾸는 것을 잊지 마세요.

정답 코드
import numpy as np
from itertools import product
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
X = np.array(list(product([0,1], repeat=3)), dtype=np.float32)
y = np.array([[sum(row) % 2] for row in X], dtype=np.float32)
model = Sequential([
Dense(8, activation='relu', input_shape=(3,)),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(X, y, epochs=3000, verbose=0)
print(np.hstack([X, model.predict(X, verbose=0).round(2)]))

sklearn.datasets.make_circles로 생성한 원형 데이터(200개)를 학습시키는 신경망을 설계하세요. 정확도 95% 이상을 목표로 합니다.

힌트

원형 경계를 만들려면 은닉층이 여러 방향의 직선을 조합해야 합니다. 뉴런 8개 정도부터 시작해 보세요. 데이터를 train/test로 나누는 것도 잊지 마세요.

정답 코드
import numpy as np
from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
X, y = make_circles(n_samples=200, noise=0.1, factor=0.5, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = Sequential([
Dense(8, activation='relu', input_shape=(2,)),
Dense(8, activation='relu'),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=200, verbose=0)
loss, acc = model.evaluate(X_test, y_test, verbose=0)
print(f"테스트 정확도: {acc:.2f}")

오늘 배운 Dense(뉴런수, activation=...) 두 줄 구조는 실무 AI의 기초 뼈대입니다.

  • 신용카드 사기 탐지: 거래 특성 30여 개를 입력받아 Dense(64) → Dense(32) → Dense(1, sigmoid) 구조로 사기 여부를 예측합니다. XOR 학습과 코드 형태가 거의 같습니다.
  • 이미지 분류의 마지막 층: CNN이 이미지에서 뽑아낸 특성 벡터를 받아 최종 분류를 하는 부분도 Dense 층입니다. 입력이 픽셀이 아닌 “이미 추출된 특성”이라는 점만 다릅니다.
  • 추천 시스템: 사용자·상품 임베딩을 결합해 “이 사용자가 이 상품을 살 확률”을 출력하는 최종 층도 Dense + sigmoid입니다.

오늘 XOR 문제를 푼 코드가 사실은 현업 AI 엔지니어가 매일 쓰는 코드 패턴과 같습니다. 데이터만 커지고 층만 깊어질 뿐 구조는 동일합니다.



객관식 1. 단층 퍼셉트론으로 XOR 문제를 풀 수 없는 근본적인 이유는 무엇입니까?

① 학습률이 너무 작아서 ② 데이터가 4개뿐이어서 ③ 결정 경계가 하나의 직선이기 때문에 ④ 활성화 함수가 시그모이드여서

정답 확인

정답: ③ 단층 퍼셉트론의 결정 경계는 $w_1 x_1 + w_2 x_2 + b = 0$이라는 직선 하나입니다. XOR의 네 점은 대각선 방향으로 같은 클래스가 놓여 있어 어떤 직선으로도 분리할 수 없습니다. 이것을 “선형 분리 불가능”이라고 합니다.

객관식 2. Keras 코드에서 Dense(4, activation='linear') 은닉층을 추가해도 XOR이 풀리지 않는 이유는?

① 뉴런 4개가 너무 적어서 ② linear 활성화는 비선형 변환을 하지 않아 여러 층이 한 층과 같아지기 때문 ③ Dense 층 대신 Conv2D를 써야 하기 때문 ④ 학습 epoch이 부족해서

정답 확인

정답: ② linear는 $\sigma(z) = z$로 아무 변환도 하지 않습니다. 이 경우 $\mathbf{W}_2(\mathbf{W}_1 \mathbf{x}) = (\mathbf{W}_2 \mathbf{W}_1)\mathbf{x}$가 되어, 은닉층이 있어도 수학적으로는 하나의 직선을 그리는 단층과 같아집니다. 비선형 활성화(tanh, ReLU, sigmoid 등)가 있어야 공간이 “휘어져” 곡선 경계가 생깁니다.

객관식 3. TensorFlow Playground에서 나선형(Spiral) 데이터를 분류하려 할 때, 가장 효과적으로 작동할 가능성이 높은 설정은?

① 은닉층 0개 ② 은닉층 1개, 뉴런 2개 ③ 은닉층 3개, 뉴런 6-6-4 ④ 은닉층 1개, 뉴런 1000개

정답 확인

정답: ③ 복잡한 패턴일수록 “깊이”(층의 수)가 중요합니다. 얕고 넓은 신경망(④)보다 적절히 깊은 신경망(③)이 계층적 특성을 잘 학습합니다. 이것이 “딥러닝”이라는 이름의 유래입니다.

서술형 1. “은닉층이 없으면 XOR을 풀 수 없다”는 사실을 학교 후배에게 설명한다면 어떻게 하겠습니까? (1) 기하학적 이유, (2) 은닉층이 하는 역할, (3) 활성화 함수의 필요성을 모두 포함해 3-5문장으로 서술하세요.

예시 답안

XOR은 네 점에서 같은 클래스가 대각선으로 놓여 있어서, 평면에 그리는 직선 한 개로는 나눌 수 없습니다(기하학적 이유). 은닉층은 입력을 여러 직선으로 동시에 바라본 결과를 만들어, 출력층이 그것들을 조합해 곡선 경계를 만들 수 있게 해 줍니다(은닉층 역할). 단, 활성화 함수가 없으면 여러 층을 쌓아도 결국 직선 하나와 같아지기 때문에, 층 사이에 tanh이나 ReLU 같은 비선형 함수가 꼭 있어야 “휘어짐”이 생깁니다(활성화 필요성).

자기점검 체크리스트

  • 은닉층이 비선형 문제를 해결하는 원리를 직선과 곡선의 비유로 설명할 수 있다
  • TensorFlow Playground에서 XOR·원형·나선형 데이터를 분류하는 구조를 찾을 수 있다
  • Keras Sequential API로 Dense 2층 신경망을 작성해 XOR을 학습시킬 수 있다
  • “한 개의 자로는 그릴 수 없는 경계를, 두 개의 자를 합치면 그릴 수 있을까?”에 자신의 답을 말할 수 있다

수업을 마치며 노트에 다음 세 가지를 적어 보세요.

  • 오늘 수업에서 가장 인상 깊었던 순간은 언제입니까? (예: 단층이 실패한 순간, v2에서 한 줄 추가로 풀린 순간, 결정 경계가 휘는 그림 등)
  • Playground의 은닉 뉴런 그림을 보며 새롭게 이해한 것이 있다면 무엇입니까?
  • 은닉층의 개수나 뉴런 수를 바꿔 보고 싶은 실험이 있다면 어떤 것입니까? 왜 그 실험이 궁금한가요?

오늘 Keras의 model.fit()은 단 한 줄이었지만, 그 안에서 신경망은 수천 번의 시행착오를 거쳐 가중치를 조금씩 수정했습니다. 6차시에서는 그 내부를 열어 경사하강법역전파가 어떻게 오차를 거꾸로 전달하며 가중치를 업데이트하는지 들여다봅니다.

다음 질문: “신경망은 자신이 얼마나 틀렸는지 어떻게 알고, 그 책임을 각 뉴런에게 어떻게 나눠줄까요?”