계산주의와 인지신경과학 6주차_학습의 원리 #2: 델타 규칙(delta rule)과 오차 역전파 기초
고려대학교 일반대학원 심리학과
Published
2026년 4월 10일 금요일 4-5교시
6주차 수업 목표
패러다임의 전환 (맹목적 수용에서 비판적 수정으로): 단순 동시 활성화에만 의존하여 무한 덧셈을 수행하던 헵 규칙(Hebbian learning)의 한계를 비판적으로 검토하고, 오차를 기반으로 가중치를 정교하게 깎아내는 델타 규칙(delta rule)의 철학적, 수학적 원리를 심층적으로 이해함.
학습 심리학과의 수학적 조우: 델타 규칙이 동물 학습 심리학의 금자탑인 ’레스콜라-와그너(Rescorla-Wagner) 모델’과 어떻게 수학적으로 완벽히 동일한지 규명하고, ’예측오차(prediction error)’가 인지 시스템의 핵심 학습 동력임을 체화함.
경사하강법(gradient descent)의 직관적 체화: 미분과 기울기의 개념을 ’안대 낀 등산객이 산을 내려가는 과정’에 비유하여, 고차원 손실 공간(loss landscape)에서의 파라미터 최적화 원리와 학습률(learning rate)의 중요성을 파악함.
파국적 간섭(catastrophic interference)의 수학적 통제: 오차 수정 메커니즘이 비직교(non-orthogonal) 패턴 간의 특징 겹침 문제를 어떻게 스스로 억제하고 튜닝해내는지 파이썬 코드로 증명함.
기여도 할당 문제(credit assignment problem)와 오차 역전파: 다층 퍼셉트론(multi-layer perceptron, MLP)의 은닉층이 갖는 인지적 내부 표상(internal representation)의 의미를 이해하고, 미분의 연쇄법칙(chain rule)을 통해 최종 오차의 ’책임’을 하위 뉴런들에게 거꾸로 분배하는 역전파(backpropagation) 알고리즘을 코드로 구현함.
[그림 1] 학습의 원리 #2: 델타 규칙(delta rule)과 오차 역전파 기초
1부: 맹목적 덧셈에서 오차 기반 수정으로(델타 규칙)
1.1. 패러다임의 전환: 헵 규칙의 비극과 델타 규칙의 탄생
[그림 2] 학습 모델의 3단계 진화
이론적 배경(5주차 복기)
헵 규칙의 맹점: 5주차에서 확인했듯, 헵 규칙은 두 뉴런이 활성화되기만 하면 무조건 가중치를 증가시킴(\(\Delta w = \eta \cdot x \cdot y\)). 이는 데이터의 맥락이나 시스템이 목표로 하는 정답 여부를 전혀 고려하지 않는 ’맹목적인 덧셈 기계’에 불과함.
시스템 붕괴: 사과와 토마토처럼 특징(빨갛다, 둥글다)이 겹치는 비직교 패턴이 연달아 입력되면, 겹치는 시냅스의 가중치만 \(+3\), \(+4\)로 무한 누적됨(가중치 폭주). 결국 단서를 주었을 때 사과와 토마토가 기괴하게 섞인 프랑켄슈타인 기억이 인출되는 ’파국적 간섭’이 발생함.
델타 규칙(delta rule)의 철학
버나드 위드로우(Bernard Widrow)와 마시안 호프(Marcian Hoff)가 제안한 위드로우-호프 규칙(Widrow-Hoff rule)으로도 불림. 현대 기계학습의 뼈대를 이룬 공식 중 하나임.
핵심 철학: “학습은 오직 ’기대’와 ’실제’가 다를 때, 즉 놀랐을 때(surprise)만 일어난다.”
정답(target, \(T\))과 현재 인공신경망의 예측값(output, \(Y\))을 비교하여, 틀린 만큼만(error, \(\delta\)) 가중치를 고치는 피드백 기반의 지도 학습(supervised learning) 메커니즘임.
수식:\(\Delta w = \eta \cdot (T - Y) \cdot X\)
\(\eta\)
학습률: 한 번의 오차를 발견했을 때 가중치를 얼마나 크게 수정할 것인가를 결정하는 보폭.
설명
가정: 목표 정답(target)이 1.0인데, 신경망의 현재 예측치(output)가 0.0이었다고 가정해보자.
오버슈팅(overshooting)의 위험: 이때 신경망이 “아! 내가 1.0만큼 틀렸구나! 당장 가중치(w)에 1.0을 더해서 100% 고쳐야지!”라고 해버리면, 데이터에 섞인 약간의 노이즈나 예외상황 때문에 정답을 지나쳐 엉뚱한 곳으로 튕겨나갈 위험이 큼.
그래서 델타 규칙 공식 중간에 학습률(\(\eta\)) = 0.2이라는 안전장치를 걸어둠. \(\Rightarrow\) 가중치 수정량: 0.2(학습률) * 1.0(오차) * 1(입력) = 0.2.
“내가 1.0만큼 틀린 건 알겠지만, 한 번에 다 고치면 위험하니까 이번 턴(epoch)에는 그 오차의 20%인 0.2만큼만 가중치를 살짝 고쳐보자!”라고 타협하는 것.
\((T - Y)\): 오차(\(\delta\)). 목표값에서 실제 출력값을 뺀 값. 이것이 가중치 변화의 ’방향’과 ’크기’를 동시에 결정함.
\(X\): 입력값. 오차를 발생시키는 데 기여한 바로 그 뉴런의 신호.
심화 해설
오차 제로(\(0\))의 법칙: 만약 신경망이 이미 정답을 완벽하게 맞혔다면(\(T = Y\)), 오차\((T - Y)\)는 \(0\)이 됨. 수식에 따라 가중치 변화량(\(\Delta w\))도 \(0\)이 됨. \(\Rightarrow\) “이미 완벽히 알고 있는 지식에 대해서는 뇌가 더 이상 시냅스 에너지를 낭비하며 가중치를 조작하지 않는다”는 인지적 경제성을 완벽히 구현함.
레스콜라-와그너 모델(Rescorla-Wagner model)과의 조우
델타 규칙과의 유사성: 1972년 발표된 고전적 조건형성의 수학적 모델인 레스콜라-와그너 공식(\(\Delta V = \alpha \beta (\lambda - \Sigma V)\))과 알파벳 기호만 다를 뿐 수학적 원리가 100% 동일함.
모델의 본질: ’놀람’의 수학화
1972년 제안된 고전적 조건형성(파블로프 학습)의 기념비적 수학 모델.
동물은 두 사건(종소리와 밥)이 단순히 “동시에 발생”했다고 맹목적으로 연결하지 않음.
학습은 오직 동물이 예상치 못한 결과에 놀랐을 때(prediction error)만 일어난다고 규명함.
\(\Delta V\)(학습량): 이번 경험을 통해 새롭게 수정할 단서(종소리)와 결과(밥)의 연합 강도.
\(\lambda\)(실제 현실): 실제로 주어진 밥의 유무 및 크기(예: 밥이 주어지면 1).
\(\Sigma V\)(기대치 총합): 현재 환경에 있는 모든 단서(종소리, 불빛 등)를 보고 동물이 ‘예상한’ 밥의 크기.
\((\lambda - \Sigma V)\)(예측오차): 실제 현실에서 내 예상을 뺀 값. 즉 놀람의 크기.
학습의 역동성(시간 흐름에 따른 변화)
초기 학습: 종소리 직후 밥이 처음 떨어지면 전혀 예상치 못했으므로 크게 놀람(오차 극대화 \(\Rightarrow\) 가파른 학습).
후기 안정화: 경험이 쌓여 종소리만 들어도 밥을 100% 확신하게 되면, 밥이 나와도 더 이상 놀라지 않음(오차 0 \(\Rightarrow\)\(\Delta V\)도 0이 되어 학습 종료).
최대 업적: 차단 효과(blocking effect)의 수학적 증명
현상: 쥐에게 [종소리 \(\rightarrow\) 밥]을 100% 학습시킨 뒤, [종소리+빛 \(\rightarrow\) 밥]을 제시하면 쥐는 새로운 단서인 ’빛’을 학습하지 않음.
원리: 이미 종소리만으로 밥의 등장(\(\lambda=1\))을 완벽히 예측(\(\Sigma V=1\))하고 있기 때문에 예측오차가 \(0\)임.
결론: “뇌는 이미 완벽하게 예측 가능한 결과에 대해서는, 새로운 정보(빛)가 동시에 주어져도 시냅스 에너지를 낭비하며 추가학습을 하지 않는다”는 뇌의 인지적 경제성을 완벽히 증명함.
[그림 3] 학습 심리학과 AI의 완벽한 수학적 조우
비유
헵 규칙(헬스장 근육맨): 양궁 선수가 과녁을 보지도 않고, 화살을 쏠 때마다 무조건 활시위를 당기는 근력을 키우는 맹목적 훈련. 결국 팔 근육만 너무 비대해져서 정밀한 폼이 다 망가짐.
델타 규칙(전문 코칭): 코치(정답 \(T\))가 화살이 과녁 중앙에서 10cm 우측으로 빗나갔다(오차)고 피드백을 주면, 딱 그 10cm를 좌측으로 보정할 만큼만 근육의 각도를 미세하게 수정하는 훈련. 정중앙을 맞추면 훈련(가중치 수정)을 즉각 종료하고 에너지를 보존함.
[그림 4] 맹목적 근육 키우기 vs. 정밀한 영점 조절
[실습 1-1] 델타 규칙의 기본: 오차 기반 단일 가중치 튜닝
오차가 어떻게 가중치 업데이트의 브레이크 역할을 하며 시스템을 스스로 수렴(convergence)하게 만드는지 파이썬 코드로 뜯어보기.
[그림 5] [실습 1-1] 코드 해부: 오차 기반 단일 가중치 튜닝
Code
import numpy as np# 1. 초기 세팅 (아무것도 모르는 백지 상태의 시냅스)# 초기 시냅스 가중치: 아직 학습되지 않은 임의의 작은 연결 강도(0.1)를 부여함.w =0.1# 학습률(learning_rate): 한 번의 오차를 발견했을 때 가중치를 얼마나 수정할지(오차의 20%만 반영) 결정함.learning_rate =0.2# 입력 자극: 뇌에 빛 자극신호가 강하게 들어옴(1.0)을 모사함.x =1.0# 목표 정답(target): 빛 자극이 들어왔을 때 신경망이 도달해야 할 이상적인 반응 강도(1.0)를 설정함.target =1.0print("=== [실습 1-1] 델타 규칙: 틀린 만큼만 정밀하게 고친다 ===")print(f"목표 정답(target): {target}\n")# 2. 반복 학습(epochs)# 가중치의 변화과정을 기록하기 위해 빈 리스트를 생성함.history_w = []# 1번부터 10번까지 총 10회(epoch)의 반복경험(학습)을 진행함.for epoch inrange(1, 11):# 전방 계산(forward pass): 현재의 시냅스 가중치(w)에 입력 신호(x)를 곱하여 신경망의 현재 예측치(output)를 계산함. output = w * x # 오차 계산(error calculation): 목표로 하는 정답(target)에서 현재 신경망의 예측치(output)를 빼서 순수한 오차(error, 델타)를 구함. error = target - output # 역방향 수정(backward update): 헵 규칙과 달리 '오차(error)'를 곱해주어 오차가 클수록 크게, 작을수록 작게 가중치 변화량(delta_w)을 통제함. delta_w = learning_rate * error * x # 기존 가중치(w)에 새롭게 계산된 변화량(delta_w)을 더해 시냅스 연결 강도를 최종 업데이트함. w = w + delta_w # 변화된 가중치를 나중에 그래프나 로그로 보기 위해 기록 리스트에 추가함. history_w.append(w)# 매 에포크마다 예측치, 오차, 그리고 수정된 가중치 상태를 화면에 출력하여 모니터링함.print(f"[epoch {epoch:2d}] 예측치: {output:.4f} | 오차(error): {error:.4f} | 수정량: +{delta_w:.4f} -> 새 가중치: {w:.4f}")print("\n-> 통찰: 에포크가 지날수록 예측치가 정답(1.0)에 가까워짐에 따라, 오차(error)는 점점 0으로 줄어듦.")print("-> 오차가 줄어드니 가중치 수정량(delta_w)도 자연스럽게 0에 수렴하며, 시스템이 폭주하지 않고 스스로 학습을 멈추는 완벽한 항상성(homeostasis)을 보여줌.")
=== [실습 1-1] 델타 규칙: 틀린 만큼만 정밀하게 고친다 ===
목표 정답(target): 1.0
[epoch 1] 예측치: 0.1000 | 오차(error): 0.9000 | 수정량: +0.1800 -> 새 가중치: 0.2800
[epoch 2] 예측치: 0.2800 | 오차(error): 0.7200 | 수정량: +0.1440 -> 새 가중치: 0.4240
[epoch 3] 예측치: 0.4240 | 오차(error): 0.5760 | 수정량: +0.1152 -> 새 가중치: 0.5392
[epoch 4] 예측치: 0.5392 | 오차(error): 0.4608 | 수정량: +0.0922 -> 새 가중치: 0.6314
[epoch 5] 예측치: 0.6314 | 오차(error): 0.3686 | 수정량: +0.0737 -> 새 가중치: 0.7051
[epoch 6] 예측치: 0.7051 | 오차(error): 0.2949 | 수정량: +0.0590 -> 새 가중치: 0.7641
[epoch 7] 예측치: 0.7641 | 오차(error): 0.2359 | 수정량: +0.0472 -> 새 가중치: 0.8113
[epoch 8] 예측치: 0.8113 | 오차(error): 0.1887 | 수정량: +0.0377 -> 새 가중치: 0.8490
[epoch 9] 예측치: 0.8490 | 오차(error): 0.1510 | 수정량: +0.0302 -> 새 가중치: 0.8792
[epoch 10] 예측치: 0.8792 | 오차(error): 0.1208 | 수정량: +0.0242 -> 새 가중치: 0.9034
-> 통찰: 에포크가 지날수록 예측치가 정답(1.0)에 가까워짐에 따라, 오차(error)는 점점 0으로 줄어듦.
-> 오차가 줄어드니 가중치 수정량(delta_w)도 자연스럽게 0에 수렴하며, 시스템이 폭주하지 않고 스스로 학습을 멈추는 완벽한 항상성(homeostasis)을 보여줌.
경사하강(descent): 오차를 줄이려면 오르막(기울기)의 정반대 방향(마이너스 부호 적용)으로 걸음을 내디뎌야 함. 이를 수식화한 것이 \(W_{new} = W_{old} - \eta \cdot \nabla L\) 이며, 여기서 손실 함수의 미분값(\(\nabla L\))을 풀면 정확히 델타 규칙의 \((Y-T) \cdot X\) 형태가 도출됨.
학습률(\(\eta\))의 딜레마:
보폭(\(\eta\))이 너무 작으면 바닥에 도달하기까지 천년 만년이 걸리거나, 중간에 있는 얕은 웅덩이(local minimum)에 빠져 갇혀버림(과소 적합).
보폭(\(\eta\))이 너무 크면 계곡 반대편 언덕으로 튕겨 나가며 오차가 걷잡을 수 없이 더 커지는 발산(overshooting) 현상이 일어남. 모델 피팅(model fitting) 시 가장 주의해야 할 하이퍼파라미터임.
비유
안대 낀 등산객: 짙은 안개가 낀 거대한 분지 지형(한라산 백록담) 한가운데에 안대를 낀 등산객(신경망)이 헬기에서 떨어짐. 이 사람의 목표는 가장 고도가 낮은 골짜기 밑바닥(loss = \(0\))을 찾는 것임.
지도가 없으니 오직 발바닥에 느껴지는 현재 땅의 경사(미분값)만 느낌. 앞꿈치가 들려있으면(오르막), 뒤로 한 걸음 물러섬. 뒤꿈치가 들려있으면 앞으로 한 걸음 감.
이 ‘가장 가파른 내리막을 향해 한 걸음씩 걷는’ 무식하지만 확실한 반복행위가 바로 딥러닝과 인지 모델을 학습시키는 경사하강법의 본질임.
[그림 6] 손실 공간과 안대 낀 등산객
[실습 1-2] 학습률에 따른 경사하강법의 발산과 수렴 비교
학습률(보폭) 설정에 따라 모델이 정답을 향해 우아하게 내려가는지(수렴), 아니면 계곡 밖으로 튕겨 나가는지(발산) 코드를 통해 극명한 차이를 확인.
[그림 7] [실습 1-2] 학습률(\(\eta\))의 딜레마: 수렴과 발산
Code
import numpy as np# 1. 동일한 문제 환경 세팅# 비교를 위해 입력 신호(x)와 도달해야 할 정답(target)을 1.0으로 동일하게 고정함.x =1.0target =1.0# 2. 신경망 두 개의 가중치 및 학습률 차별 세팅# 첫 번째 신경망: 정상적인 신경망(w_good)w_good =0.1# 정상 신경망의 초기 가중치lr_good =0.2# 적당한 보폭으로 설정한 정상 학습률(안정적 수렴을 유도함)# 두 번째 신경망: 문제가 있는 신경망(w_bad)w_bad =0.1# 문제 신경망의 초기 가중치(출발선은 동일함)lr_bad =1.5# 의도적으로 너무 큰 보폭으로 설정한 과다 학습률(계곡 반대편으로 튕겨 나가는 발산을 유도함)print("=== [실습 1-2] 학습률의 마법과 저주 ===")print("목표: 가중치(w)가 1.0에 도달해야 함.\n")# 3. 경사하강법 5회 반복 시뮬레이션# 에포크를 5회만 짧게 돌려 발산 현상이 초반에 어떻게 일어나는지 관찰함.for epoch inrange(1, 6):# [정상 신경망의 예측, 오차 계산, 가중치 수정 과정] out_good = w_good * x # 현재 가중치로 예측치를 도출함 err_good = target - out_good # 오차를 계산함(정답 - 예측치) w_good = w_good + (lr_good * err_good * x) # 적절한 학습률(0.2)을 곱하여 델타 규칙으로 가중치를 업데이트함# [과다 학습률 신경망의 예측, 오차 계산, 가중치 수정 과정] out_bad = w_bad * x # 문제 신경망의 예측치를 도출함 err_bad = target - out_bad # 문제 신경망의 오차를 계산함 w_bad = w_bad + (lr_bad * err_bad * x) # 지나치게 큰 학습률(1.5)을 곱하여 델타 규칙으로 가중치를 무리하게 업데이트함# 매 에포크마다 두 신경망의 오차와 수정된 가중치 상태를 출력하여 직관적으로 비교함print(f"[epoch {epoch}]")print(f" - 적정 학습률 (lr=0.2): 오차 {err_good:5.2f} -> 새 가중치 {w_good:6.2f} (안정적 접근)")print(f" - 과다 학습률 (lr=1.5): 오차 {err_bad:5.2f} -> 새 가중치 {w_bad:6.2f} (지그재그 폭주!)")print("\n-> 통찰: 학습률(보폭)이 너무 크면, 계곡 바닥을 지나쳐 반대편 언덕 더 높은 곳으로 튕겨 나가는 '오버슈팅'이 발생하여 영원히 정답을 찾지 못함.")
=== [실습 1-2] 학습률의 마법과 저주 ===
목표: 가중치(w)가 1.0에 도달해야 함.
[epoch 1]
- 적정 학습률 (lr=0.2): 오차 0.90 -> 새 가중치 0.28 (안정적 접근)
- 과다 학습률 (lr=1.5): 오차 0.90 -> 새 가중치 1.45 (지그재그 폭주!)
[epoch 2]
- 적정 학습률 (lr=0.2): 오차 0.72 -> 새 가중치 0.42 (안정적 접근)
- 과다 학습률 (lr=1.5): 오차 -0.45 -> 새 가중치 0.77 (지그재그 폭주!)
[epoch 3]
- 적정 학습률 (lr=0.2): 오차 0.58 -> 새 가중치 0.54 (안정적 접근)
- 과다 학습률 (lr=1.5): 오차 0.23 -> 새 가중치 1.11 (지그재그 폭주!)
[epoch 4]
- 적정 학습률 (lr=0.2): 오차 0.46 -> 새 가중치 0.63 (안정적 접근)
- 과다 학습률 (lr=1.5): 오차 -0.11 -> 새 가중치 0.94 (지그재그 폭주!)
[epoch 5]
- 적정 학습률 (lr=0.2): 오차 0.37 -> 새 가중치 0.71 (안정적 접근)
- 과다 학습률 (lr=1.5): 오차 0.06 -> 새 가중치 1.03 (지그재그 폭주!)
-> 통찰: 학습률(보폭)이 너무 크면, 계곡 바닥을 지나쳐 반대편 언덕 더 높은 곳으로 튕겨 나가는 '오버슈팅'이 발생하여 영원히 정답을 찾지 못함.
1.3. 5주차의 복수: 델타 규칙으로 파국적 간섭 완벽히 억제하기
이론적 설명
5주차 실습에서 사과([1, 1, -1, -1])와 토마토([1, 1, 1, -1])를 직교성(orthogonality) 없이 단순히 한 도화지에 덧셈(헵 규칙)했을 때, 두 과일이 공유하는 특징(빨갛다, 둥글다)의 가중치가 비정상적으로 누적(\(+3\), \(+4\))되어 시스템이 붕괴했음.
하지만 델타 규칙은 오차를 줄이는 방향으로만 움직이므로, 이 ’비직교 패턴’들도 한 네트워크망 안에 잉크 번짐(폭주) 없이 안전하게 구별하여 저장할 수 있음.
해결 원리(특징 선택 및 억제 메커니즘)
네트워크에 사과를 보여주고 “이건 사과야(\(+1\))”라고 지도하고, 다음 날 토마토를 보여주고 “이건 토마토야(\(-1\))”라고 번갈아가며 오차를 튜닝함.
학습이 반복되면 네트워크는 놀라운 사실을 스스로 깨달음: 빨갛다(1번 노드)와 둥글다(2번 노드)는 두 과일에 다 들어 있어서 정답을 맞히는 데 전혀 도움이 안 된다!
델타 규칙은 오차를 최소화하기 위해 쓸모없는 공유 특징(1번, 2번 노드)의 시냅스 연결선 가중치를 스스로 아예 \(0\)에 가깝게 깎아버림(cancel out).
대신 사과와 토마토를 완벽히 가르는 결정적 차이인 3번 노드(물렁함)의 가중치만 극대화시켜서 문제를 해결함.
비유
Day 1: 사과 학습(목표 정답: \(+1\))
사과를 보여줌. 사과의 특징은 [빨갛다, 둥글다]임.
처음엔 신경망이 바보라서 \(0\)이라고 대답.
정답은 \(+1\)인데 \(0\)이라고 했으니, 오차가 발생.
가중치 튜닝: 델타 규칙에 따라 오차를 줄이기 위해 [빨갛다], [둥글다] 노드의 가중치를 살짝 올려줌(예: 각각 \(+0.1\)).
Day 2: 토마토 학습(목표 정답: \(-1\))
다음 날 토마토를 보여줌. 토마토의 특징은 [빨갛다, 둥글다, 물렁하다]임.
어제 사과를 배우면서 [빨갛다], [둥글다]를 \(+0.1\)로 올려놨기 때문에, 신경망은 토마토를 보고 “어? 이거 사과랑 비슷한데?”라며 \(+0.2\)라고 긍정적인 대답을 해버림.
그런데 코치가 “아니야! 이건 토마토야(\(-1\))!”라고 혼냄. 엄청난 오차가 발생.
가중치 튜닝: 오차를 줄이기 위해 이번엔 켜져 있던 [빨갛다], [둥글다], [물렁하다] 노드의 가중치를 크게 깎아내림(예: 각각 \(-0.2\)).
수백 번 번갈아 반복 튜닝
공통특징 [빨갛다, 둥글다]: 사과를 볼 때는 점수가 올라가고(\(+\)), 토마토를 볼 때는 점수가 깎임(\(-\)). 계속 더해졌다 빼지기를 반복하다 보니, 결국 이 노드들의 가중치는 \(0\)(쓸모없음)으로 수렴해버림.
차이점 [물렁하다]: 사과를 볼 때는 이 특징이 아예 안 켜지니 아무 변화가 없지만, 토마토를 볼 때만 켜져서 계속 마이너스(\(-\)) 방향으로 깎임. 결국 이 노드의 가중치만 \(-1\)을 향해 강력하게 튜닝됨.
오차의 튜닝: 사과와 토마토가 번갈아가며 만들어내는 오차(질책)를 피드백으로 삼아, 쓸모없는 공통점(빨강, 둥긂)의 가중치는 \(0\)으로 깎아내고 중요한 차이점(물렁함)의 가중치만 남기는 정밀한 영점조절 과정.
[실습 1-3] 델타 규칙을 통한 비직교 패턴의 간섭 억제 및 특징 추상화
파국적 간섭을 일으켰던 두 패턴을 델타 규칙으로 학습시켜, 가중치가 떡지지 않고 깎여나가며 수렴하는지 확인.
[그림 8] [실습 1-3] 특징 선택: 비직교 패턴의 파국적 간섭 억제
Code
# 1. 5주차의 악몽: 특징이 심하게 겹치는 비직교 패턴 준비# 4개의 감각 노드 구조: [빨강, 둥긂, 물렁함, 길쭉함]# 사과는 빨갛고(+1), 둥글고(+1), 물렁하지 않으며(-1), 길쭉하지 않음(-1)apple = np.array([1, 1, -1, -1])# 토마토는 빨갛고(+1), 둥글고(+1), 물렁하며(+1), 길쭉하지 않음(-1)tomato = np.array([1, 1, 1, -1])# 정답(target) 세팅: 사과가 들어오면 +1을 출력하고, 토마토가 들어오면 -1을 출력하도록 지도학습 정답을 지시함.target_apple =1.0target_tomato =-1.0# 2. 가중치 초기화# 4개의 감각특징을 받아들이기 위해 시냅스 연결 파이프 4개를 생성하고 가중치를 모두 0으로 비워둠.# 벡터/행렬의 관례에 따라 W는 대문자로 유지함.W = np.zeros(4)# 가중치를 조금씩 수정할 학습률을 0.1로 안정적으로 설정함.learning_rate =0.1print("=== [실습 1-3] 델타 규칙으로 파국적 간섭 억제 및 텐션 튜닝 ===")# 3. 번갈아 가며 델타 규칙 학습(epoch 50회)# 사과와 토마토를 한 번씩 번갈아 보여주는 과정을 50번 반복함.for epoch inrange(1, 51):# [사과 학습 단계]# 사과 데이터를 넣어 현재 뇌(W)가 사과를 얼마나 긍정적으로 판단하는지 예측함. out_apple = np.dot(W, apple) # 사과에 대한 이상적 정답(+1)에서 현재 예측치를 빼서 사과 오차를 계산함. err_apple = target_apple - out_apple # 사과의 입력값, 오차, 학습률을 곱해 가중치를 양의 방향(+)으로 수정함. W = W + learning_rate * err_apple * apple # [토마토 학습 단계]# 방금 수정된 뇌(W)에 토마토 데이터를 넣어 예측치를 산출함. out_tomato = np.dot(W, tomato) # 토마토에 대한 이상적 정답(-1)에서 현재 예측치를 빼서 토마토 오차를 계산함. err_tomato = target_tomato - out_tomato # 토마토의 입력값, 오차, 학습률을 곱해 가중치를 이번엔 음의 방향(-)으로 수정함. W = W + learning_rate * err_tomato * tomato # 학습 과정을 10번마다 화면에 출력하여 총 오차가 점진적으로 0을 향해 수렴하는지 모니터링함.if epoch %10==0: total_error =abs(err_apple) +abs(err_tomato)print(f"[epoch {epoch:2d}] 사과오차: {err_apple:5.2f} | 토마토오차: {err_tomato:5.2f} | 총오차: {total_error:5.2f}")# 4. 폭주가 억제된 최종 가중치 맵 확인# 반복학습이 끝난 후 최종적으로 결정된 시냅스 가중치 4개를 확인함.print("\n[학습 완료] 최종 안정화된 가중치(W):", W.round(2))print("-> 노드 1,2(빨강, 둥긂)와 노드 4(길쭉함)는 0으로 죽어버렸고, 노드 3(물렁함)만 -1로 강력하게 세팅됨!")# 학습된 신경망이 사과와 토마토를 입력받았을 때 목표한 정답을 완벽히 뱉어내는지 검증함.print("\n[검증 테스트]")print(f"사과 입력 시 모델 출력: {np.dot(W, apple):.2f} (우리가 지시한 정답: {target_apple})")print(f"토마토 입력 시 모델 출력: {np.dot(W, tomato):.2f} (우리가 지시한 정답: {target_tomato})")print("\n-> 심화 해설: 5주차 헵 규칙에서는 1번, 2번 노드(빨강, 둥긂)가 계속 덧셈 누적되어 잉크가 떡지고 붕괴했음.")print("-> 반면 델타 규칙은 두 과일을 구별하는 데 쓸모없는 공통 특징 가중치를 스스로 0으로 소거(cancel out)해버림.")print("-> 오직 차이점인 3번 노드(물렁함) 하나만 잡고서 두 사물을 완벽하게 분류해내는 '데이터 추상화(abstraction)'의 지능을 획득함!")
=== [실습 1-3] 델타 규칙으로 파국적 간섭 억제 및 텐션 튜닝 ===
[epoch 10] 사과오차: 0.12 | 토마토오차: -0.11 | 총오차: 0.23
[epoch 20] 사과오차: 0.01 | 토마토오차: -0.01 | 총오차: 0.02
[epoch 30] 사과오차: 0.00 | 토마토오차: -0.00 | 총오차: 0.00
[epoch 40] 사과오차: 0.00 | 토마토오차: -0.00 | 총오차: 0.00
[epoch 50] 사과오차: 0.00 | 토마토오차: -0.00 | 총오차: 0.00
[학습 완료] 최종 안정화된 가중치(W): [-0. -0. -1. 0.]
-> 노드 1,2(빨강, 둥긂)와 노드 4(길쭉함)는 0으로 죽어버렸고, 노드 3(물렁함)만 -1로 강력하게 세팅됨!
[검증 테스트]
사과 입력 시 모델 출력: 1.00 (우리가 지시한 정답: 1.0)
토마토 입력 시 모델 출력: -1.00 (우리가 지시한 정답: -1.0)
-> 심화 해설: 5주차 헵 규칙에서는 1번, 2번 노드(빨강, 둥긂)가 계속 덧셈 누적되어 잉크가 떡지고 붕괴했음.
-> 반면 델타 규칙은 두 과일을 구별하는 데 쓸모없는 공통 특징 가중치를 스스로 0으로 소거(cancel out)해버림.
-> 오직 차이점인 3번 노드(물렁함) 하나만 잡고서 두 사물을 완벽하게 분류해내는 '데이터 추상화(abstraction)'의 지능을 획득함!
2부: 은닉층의 발견과 책임의 분배(오차 역전파)
2.1. 단층 퍼셉트론의 치명적 한계와 선형 분리 불가능성
이론적 설명(단층구조의 기하학적 한계)
델타 규칙으로 많은 최적화 문제가 해결되었으나, 1969년 마빈 민스키(Marvin Minsky)와 시모어 패퍼트(Seymour Papert)는 저서 Perceptrons를 통해 단층 퍼셉트론(입력층과 출력층만 있는 단순 구조)의 치명적인 수학적 한계를 완벽하게 증명함.
AND와 OR 연산의 성공
AND(둘 다 참일 때만 1)나 OR(하나라도 참이면 1) 문제는 2차원 평면(그래프)에 4개의 데이터를 찍었을 때, 단 하나의 일직선(선형경계, linear boundary)을 그어 정답(1)과 오답(0) 그룹을 깔끔하게 가를 수 있음(선형분리 가능).
단층 퍼셉트론의 가중치 계산 수식(\(w_1x_1 + w_2x_2 + b = 0\))은 기하학적으로 볼 때 2차원 평면 위에 이 일직선 하나를 긋는 행위와 정확히 일치함.
XOR 문제(배타적 논리합)의 절망
하지만 XOR 문제는 “두 입력이 서로 다를 때만 참(1)을, 같으면(둘 다 0이거나 둘 다 1) 거짓(0)을 반환하라”는 조건임.
이를 2차원 평면에 점으로 찍으면 (0, 1)과 (1, 0)은 대각선으로 마주 보고, (0, 0)과 (1, 1) 역시 반대 대각선으로 마주 보는 교차 형태가 됨.
아무리 가중치를 정교하게 튜닝(경사하강)해도, 평면 위에 빳빳한 직선 단 하나를 그어서 대각선으로 마주 보는 점들을 같은 그룹으로 묶어낼 방법은 우주상에 존재하지 않음\(\Rightarrow\) 선형분리 불가능 문제.
심화 해설(인지적 유연성의 부재와 맥락의 상실)
4주차에서 깊이 논의했듯, 이 XOR 문제는 단순한 수학 논리 퍼즐이 아니라 고차원적 인간 인지의 필수요건인 맥락 의존성(context-dependency)을 상징하는 거대한 장벽임.
예시
인지 시스템에 “나는 커피(A)도 좋고, 오렌지 주스(B)도 좋지만, 두 개를 섞어 마시는 것(A AND B)은 최악이다”라는 취향을 학습시킨다고 가정해보겠음.
단층 퍼셉트론은 단순히 입력된 신호의 호감도(가중치)를 ‘독립적으로 더하는(덧셈)’ 역할만 하므로, 커피(+1)와 주스(+1)가 동시에 들어오면 긍정 수치가 폭발하여 무조건 ’아주 좋다(+2)’는 치명적인 오답 결론을 내림.
이처럼 단층 구조의 선형적 판단력으로는 “각각의 요소는 긍정적이지만, 두 요소가 ‘동시에’ 존재할 때는 부정적으로 의미가 뒤집힌다”는 비선형적이고 배타적인 상호작용(맥락)을 절대 분리해낼 수 없음. 결국 이 단순한 1차원적 덧셈 기계는 조금만 맥락이 꼬여 있는 환경을 만나면 영원히 에러율 50%의 늪에 빠져 허우적대며, 인공지능 역사에 길고 추운 첫 번째 AI 겨울을 불러오게 됨.
[그림 9] 선형 분리 불가능성: 1차원적 덧셈 기계의 절망
[실습 2-1] 파이썬으로 확인하는 단층 퍼셉트론의 선형 분리 한계(XOR 실패 목격)
수만 번을 델타 규칙으로 학습시켜도, 은닉층이 없는 단층 모델은 XOR 문제에서 오차를 줄이지 못하고 절망적인 0.5 근처를 맴돌게 됨을 직접 목격.
[그림 10] [실습 2-1] 파이썬으로 목격하는 평면의 한계
Code
import numpy as np# 1. XOR 데이터셋 준비# XOR 논리 회로: 두 입력이 [0,0]이거나 [1,1]로 같으면 정답은 0, 서로 다르면([0,1] 또는 [1,0]) 정답은 1을 출력해야 함.X_xor = np.array([[0,0], [0,1], [1,0], [1,1]])Y_xor = np.array([[0], [1], [1], [0]])# 2. 단층 퍼셉트론 가중치 세팅# 은닉층 없이 입력 2개에서 곧바로 출력 1개로 직행하는 2 x 1 가중치 행렬을 임의로(0.1, 0.2) 생성함.W_single = np.array([[0.1], [0.2]])learning_rate =0.1print("=== [실습 2-1] 단층 퍼셉트론의 절망: XOR 문제 시도 ===")# 3. 5000번의 고된 델타 규칙 훈련# 직선(선형 모델)으로 대각선 데이터를 자르기 위해 무려 5,000번이나 오차를 수정함.for epoch inrange(5000):# 입력 데이터 4세트 전체를 한꺼번에 가중치와 내적 곱셈(선형 변환) 처리함. linear_out = np.dot(X_xor, W_single)# 선형 합산된 값을 시그모이드 함수에 통과시켜 모든 값을 0과 1 사이로 부드럽게 압축함(확률값 도출). output =1/ (1+ np.exp(-linear_out)) # 각각의 정답에서 현재의 압축된 예측치를 빼서 전체 에러를 계산함. error = Y_xor - output# 시그모이드를 쓴 비선형 단층 퍼셉트론의 델타 규칙 가중치 수정 공식을 적용함.# error에 시그모이드 미분값인 output*(1-output)을 곱한 뒤 입력 행렬의 전치(X.T)를 곱해 기울기를 구함. delta_w = learning_rate * np.dot(X_xor.T, error * output * (1- output))# 계산된 변화량만큼 단층 가중치를 업데이트함. W_single += delta_w# 4. 최종 예측 결과 확인print("\n[학습 완료] 단층 퍼셉트론의 XOR 예측 결과:")# 5,000번 훈련이 끝난 최종 가중치(W_single)를 사용하여 4가지 입력 패턴의 결과를 최종 산출함.final_prediction =1/ (1+ np.exp(-np.dot(X_xor, W_single)))# 4개의 입력 셋트를 루프로 돌면서 정답과 딥러닝 모델의 예측값을 나란히 출력하여 비교함.for i inrange(4):print(f"입력: {X_xor[i]} -> 예측: {final_prediction[i][0]:.4f} (정답: {Y_xor[i][0]})")print("\n-> 심화 해설: 5000번이나 학습시켰지만, 예측값이 모두 0.5 언저리로 붕괴해버림.")print("-> 직선 하나로는 대각선 데이터를 가를 수 없기 때문에, 신경망이 '모르겠다(0.5)'라고 포기해버린 수학적 절망 상태를 보여줌.")
=== [실습 2-1] 단층 퍼셉트론의 절망: XOR 문제 시도 ===
[학습 완료] 단층 퍼셉트론의 XOR 예측 결과:
입력: [0 0] -> 예측: 0.5000 (정답: 0)
입력: [0 1] -> 예측: 0.5000 (정답: 1)
입력: [1 0] -> 예측: 0.5000 (정답: 1)
입력: [1 1] -> 예측: 0.5000 (정답: 0)
-> 심화 해설: 5000번이나 학습시켰지만, 예측값이 모두 0.5 언저리로 붕괴해버림.
-> 직선 하나로는 대각선 데이터를 가를 수 없기 때문에, 신경망이 '모르겠다(0.5)'라고 포기해버린 수학적 절망 상태를 보여줌.
2.2. 오차 역전파(backpropagation): 책임은 누구에게 있는가?
이론적 설명(기여도 할당의 딜레마)
단층 퍼셉트론의 한계를 부수기 위한 해결책은 명확했음. 입력층과 출력층 사이에 은닉층이라는 새로운 중간 다리를 놓아 다층 퍼셉트론(multi-layer perceptron, MLP) 구조를 만드는 것임.
그러나 다층 구조가 되면서 인지과학과 AI 모두에 거대한 딜레마가 발생함. 바로 기여도 할당 문제(credit assignment problem)임.
최종 출력층(운동신경)에서 오차가 발생했을 때, 이 오차의 책임은 바로 앞단인 [은닉층 \(\rightarrow\) 출력층을 잇는 가중치(\(W_2\))]에 있는가? 아니면 아예 처음부터 데이터가 잘못 넘어온 [입력층 \(\rightarrow\) 은닉층을 잇는 가중치(\(W_1\))]에서부터 꼬인 것인가?
외부에서 정답(target)을 직접 알려주는 곳은 오직 최종 출력층뿐임. 그렇다면 정답을 알 수 없는 중간 기착지, 즉 [입력층 \(\rightarrow\) 은닉층을 잇는 가중치(\(W_1\))]는 도대체 자신의 오차를 어떻게 구해서 델타 규칙을 적용한단 말인가?
[그림 11] 다층 구조의 등장과 기여도 할당의 딜레마
해결책: 미분의 연쇄법칙
1980년대 제프리 힌튼(Geoffrey Hinton), 데이비드 루멜하트(David Rumelhart) 등이 제안한 오차 역전파 알고리즘이 10여 년의 AI 겨울을 끝내고 이 문제를 해결함.
고등학교 수학에 나오는 미분의 ’연쇄법칙(합성함수의 미분)’을 이용해, 최종 출력층에서 계산된 오차(\(\delta\))를 뒤에서부터 앞으로(backward) 가중치 파이프라인을 거꾸로 타고 흘려보내며 각 시냅스 다리(\(W_2\), \(W_1\))의 책임 비율을 분배함.
[그림 12] 사장님의 분노와 미분의 연쇄법칙
비유(회사 조직의 적자와 내리갈굼)
구조
입력층 = 말단 사원.
은닉층 = 중간 관리자.
출력층 = 사장.
손실(error) = 회사의 막대한 적자.
가중치 다리
\(W_1\) = 말단 사원의 보고를 중간 관리자가 신뢰하는 정도.
\(W_2\) = 중간 관리자의 기획안을 사장이 신뢰하는 정도.
순전파(forward pass): 말단 사원이 원본 데이터를 올리면(\(W_1\) 통과), 중간 관리자가 취합하고, 사장이 최종 결정함(\(W_2\) 통과). \(\rightarrow\) 결재가 났는데 회사가 10억 적자를 봄.
역전파(backward pass):
적자(오차)가 발생하면, 사장은 중간 관리자가 적자에 기여한 지분(기울기)을 따져 묻고, 그 책임만큼 중간 관리자에 대한 신뢰도(가중치 \(W_2\))를 깎아버림.
질책을 받은 중간 관리자는 자기가 받은 벌점을 바탕으로, 애초에 데이터를 올린 말단 사원들의 책임 지분을 역추적하여 그들에 대한 신뢰도(가중치 \(W_1\))를 깎아내림.
요약: 이처럼 “정확한 책임 비율(오차)을 위에서 아래로 연쇄적으로 따져 묻고, 그 벌점만큼 서로 간의 신뢰도(가중치)를 수정하는” 구조가 역전파 알고리즘의 핵심임.
[그림 13] 오차 역전파: 책임의 연쇄 추궁
[실습 2-2] 다층 신경망의 순전파와 역전파 1회차 해부하기
복잡한 미분 수식 대신, 파이썬 행렬 연산을 통해 오차가 뒷단에서 앞단으로 어떻게 거꾸로 흘러 들어가는지 코드의 흐름(chain rule)을 뜯어봄.
“전치행렬”과 W2.T란?
전치행렬(transpose matrix): 행렬의 행(가로)과 열(세로)을 서로 맞바꾼 행렬을 뜻함. 수학기호로는 행렬 우측 상단에 알파벳 \(T\)를 붙여서 \(W^T\)라고 표기. 세로로 길쭉했던 행렬은 가로로 눕혀지고, 가로로 넓었던 행렬은 세로로 세워지는 연산.
W2.T의 의미: 파이썬의 numpy 라이브러리에서는 행렬 변수 뒤에 .T만 붙이면 전치행렬을 만들어줌. 즉 W2.T는 “W2 행렬의 가로세로 방향을 뒤집어라”라는 파이썬 명령어.
왜 역전파에서 ’전치’가 필수적인가?
[실습 2-2]의 뼈대를 보면 중간 관리자(은닉층)는 2명이고, 사장님(출력층)은 1명임.
순전파(업무보고 방향): \(W_2\) 사용
보고서는 2명(은닉층)\(\rightarrow\)1명(출력층) 방향으로 올라감.
이때 두 층을 연결하는 가중치 파이프 \(W_2\)는 중간 관리자 각각의 신뢰도를 담아야 하므로 [[0.6], [0.7]]이라는 2행 1열(세로로 긴 모양)의 행렬이 됨.
역전파(내리갈굼 방향): \(W_2^T\) 사용
회사가 적자(오차)를 보면, 이제 사장님이 중간 관리자들에게 책임을 물어야 함.
질책의 방향은 아까와 반대로 1명(출력층)\(\rightarrow\)2명(은닉층) 방향으로 ’역류’해야 함.
방향이 거꾸로 바뀌었기 때문에, 보고서가 올라갈 때 썼던 세로 파이프(\(W_2\), 2x1)를 그대로 쓸 수가 없음. 수학적으로 행렬의 아귀(차원)가 맞지 않기 때문.
그래서 사장님의 질책(\(\Delta\)) 1개가 2명의 중간 관리자에게 쫙 퍼져 내려가도록, 기존 파이프를 가로로 눕혀서 1행 2열([0.6, 0.7])(수학적으로는 전치를 해도 여전히 행렬이지만, 파이썬 상에서는 벡터로 취급됨)의 파이프로 억지로 방향을 뒤집어주는 작업이 필요. 이것이 바로 전치행렬(W2.T)을 곱하는 이유.
[그림 14] [실습 2-2] 행렬의 전치(Transpose)와 역류하는 파이프
Code
# 0. 사전 함수 정의# 어떤 값이든 0과 1 사이로 압축해주는 비선형 활성화 함수인 시그모이드 함수를 정의함.def sigmoid(x):return1/ (1+ np.exp(-x))# 신경망의 곡선 기울기(미분)를 구하는 함수. 시그모이드는 (결과값) * (1 - 결과값)으로 매우 간단히 미분됨.def sigmoid_derivative(out):return out * (1- out)# 1. 네트워크 뼈대 구성# 입력 노드 2개(말단 사원 2명)가 제출한 데이터 보고서를 세팅함.X = np.array([[1.0, 0.5]])# 최종 출력 노드 1개(사장님)가 기대한 완벽한 100% 이익(정답)을 세팅함.target = np.array([[1.0]])# 2. 가중치 초기화# 말단 사원(2명)에서 중간 관리자(2명)로 가는 W1 파이프(2x2 행렬)의 호감도를 양수로 고정 세팅함.W1 = np.array([[0.2, 0.3], [0.4, 0.5]])# 중간 관리자(2명)에서 사장님(1명)으로 가는 W2 파이프(2x1 행렬)의 호감도를 세팅함.W2 = np.array([[0.6], [0.7]])# 한 번 혼낼 때마다 가중치를 얼마나 깎을지 결정할 학습률을 0.5로 크게 설정함.learning_rate =0.5print("=== [실습 2-2] 오차 역전파 흐름 1회차 뜯어보기 ===")# --------------------------------------------------------# [Step 1] 순전파(forward pass): 입력 -> 은닉 -> 출력(업무보고 라인)# --------------------------------------------------------# 입력 데이터가 W1 가중치 망을 통과하여 은닉층에 도착한 순수 전기 합산량을 구함.hidden_input = np.dot(X, W1)# 은닉층 노드가 그 합산량을 시그모이드 함수로 압축시켜 내부 표상(중간 결재안)을 생성함.hidden_out = sigmoid(hidden_input)# 은닉층의 결과물이 W2 가중치 망을 통과하여 최종 출력층(사장님)에 도달한 합산량을 구함.final_input = np.dot(hidden_out, W2)# 사장님이 그 합산량을 시그모이드 함수로 압축시켜 최종 예측(회사 실적)을 뱉어냄.final_out = sigmoid(final_input)# 사장님이 기대한 정답(target)에서 방금 도출한 최종 실적(final_out)을 빼서 발생한 적자(총 오차)를 구함.error = target - final_out# 업무 보고가 끝나고 1차적으로 발생한 오차가 얼마인지 화면에 출력함.print(f"1. 사장님 최종 예측: {final_out[0][0]:.4f} | 타겟: {target[0][0]:.4f} | 발생한 오차: {error[0][0]:.4f}")# --------------------------------------------------------# [Step 2] 역전파 1단계: 출력층 -> 은닉층 가중치(W2) 책임 묻기# --------------------------------------------------------# 사장님 층의 국소 오차(델타) = 총 발생한 오차 * 사장님 층의 곡선 기울기(시그모이드 미분값).d_output = error * sigmoid_derivative(final_out)# 델타 규칙: (은닉층 출력물의 전치 행렬) * (사장층 델타) * (학습률)을 통해 W2를 얼마나 고칠지 양을 계산함.delta_w2 = learning_rate * np.dot(hidden_out.T, d_output)# W2 가중치 파이프가 얼마나 두꺼워지거나 깎여나가야 하는지 화면에 출력함.print(f"2. 중간관리자와 사장 사이의 가중치(W2) 업데이트량:\n{delta_w2.round(4)}")# --------------------------------------------------------# [Step 3] 역전파 2단계: 은닉층 -> 입력층 가중치(W1) 책임 묻기 (내리갈굼의 핵심)# --------------------------------------------------------# [가장 중요한 연쇄법칙 단계] 은닉층은 자신만의 정답이 없으므로, 방금 구한 사장층의 델타(d_output)를# 기존의 W2 파이프(전치행렬 형태)를 타고 '거꾸로(역류)' 내려보내 중간 관리자들의 순수 책임량을 추산함.error_hidden = np.dot(d_output, W2.T)# 역류해 들어온 은닉층의 에러 합산량에 자신의 곡선 기울기(시그모이드 미분값)를 곱해 은닉층의 진짜 국소 오차(델타)를 완성함.d_hidden = error_hidden * sigmoid_derivative(hidden_out)# 델타 규칙: (원래 입력물의 전치 행렬) * (은닉층 델타) * (학습률)을 통해 W1 가중치를 어떻게 고칠지 양을 계산함.delta_w1 = learning_rate * np.dot(X.T, d_hidden)# W1 가중치가 어떻게 업데이트되어야 하는지 최종적으로 화면에 출력함.print(f"3. 말단사원과 중간관리자 사이의 가중치(W1) 업데이트량 (오차 역류의 결과):\n{delta_w1.round(4)}")print("\n-> 통찰: 은닉층 가중치(W1)는 밖에서 주어지는 오차 정답을 몰라도, 오차 역전파를 통해 W2를 거쳐 역류해 들어온 수학적 책임(d_hidden)을 받아 스스로를 수정할 수 있음!")
=== [실습 2-2] 오차 역전파 흐름 1회차 뜯어보기 ===
1. 사장님 최종 예측: 0.6906 | 타겟: 1.0000 | 발생한 오차: 0.3094
2. 중간관리자와 사장 사이의 가중치(W2) 업데이트량:
[[0.0198]
[0.021 ]]
3. 말단사원과 중간관리자 사이의 가중치(W1) 업데이트량 (오차 역류의 결과):
[[0.0048 0.0054]
[0.0024 0.0027]]
-> 통찰: 은닉층 가중치(W1)는 밖에서 주어지는 오차 정답을 몰라도, 오차 역전파를 통해 W2를 거쳐 역류해 들어온 수학적 책임(d_hidden)을 받아 스스로를 수정할 수 있음!
2.3. 은닉층의 비선형적 공간 왜곡과 XOR의 정복
이론적 설명(은닉층의 역할과 공간 왜곡)
단층 퍼셉트론이 데이터를 가르기 위해 빳빳한 직선 하나만 그을 수 있다면, 은닉층과 비선형 활성화 함수(sigmoid 등)가 결합된 다층구조는 데이터가 놓인 차원의 뼈대 자체를 구부러뜨리고 왜곡하는 강력한 능력을 가짐.
오차 역전파는 단순히 결과의 정답을 맞히는 것을 넘어, 이 공간을 ‘어떻게 구부려야’ 꼬여 있는 데이터를 가장 잘 가를 수 있는지 은닉층 뉴런들에게 그 기준을 수학적으로 학습시킴.
심화 해설(내부 표상과 고차원 분리)
인지과학적으로 은닉층을 통과한다는 것은 망막에 맺힌 날것의 2차원 감각 데이터(XOR)를 뇌가 이해하기 쉬운 고차원적 개념으로 재배치하여 내부 표상(internal representation)을 형성하는 과정임.
2차원 평면에 대각선으로 얽혀있던 평범한 XOR 데이터는, 은닉층 노드들(hidden nodes)이 각자의 가중치 기준에 맞게 이리저리 당기고 휘게 만들면서 3차원 이상의 구부러진 언덕으로 재배치됨.
데이터가 3차원 입체로 구부러지면, 그 구부러진 골짜기 사이로 평평한 색종이(선형평면[hyperplane])를 쑥 집어넣어 데이터를 두 그룹으로 완벽하게 잘라낼 수 있음. 이것이 은닉층이 지닌 비선형성 마법의 본질임.
비유(종이 접기와 한 번의 가위질)
종이 접기 비유: 검은 점 2개와 흰 점 2개가 대각선 모양으로 엇갈려 그려져 있는 평평한 도화지(XOR 데이터)가 있음. 이 도화지를 바닥에 그대로 둔 채, 자를 대고 직선으로 단 한 번 가위질(단층 퍼셉트론)을 해서 검은 점과 흰 점을 나눌 방법은 절대 없음.
하지만 도화지를 허공으로 들어 올려 입체적으로 둥글게 접거나 꼬아버리면(은닉층의 비선형 왜곡), 엇갈려 있던 검은 점들과 흰 점들의 ’높이(차원)’가 달라지게 됨.
이렇게 2차원 종이를 3차원 입체로 비틀어버리면, 허공에서 단 한 번의 평평한 가위질(최종 출력층의 선형 경계)만으로도 두 집단을 완벽하게 잘라낼 수 있음.
[그림 15] 은닉층의 본질: 비선형적 공간 왜곡
[실습 2-3] 다층 신경망(MLP)의 10,000번 역전파 루프와 XOR 문제 정복
[실습 2-1]에서 단층 퍼셉트론이 절대 풀지 못했던 XOR 데이터셋을, 방금 만든 2층짜리 다층 신경망(MLP)과 역전파 루프에 넣어 10,000번 훈련시켜 완벽히 풀어낼 수 있음.
[그림 16] [실습 2-3] 다층 신경망(MLP)의 공간 왜곡과 XOR 정복
Code
# 1. 풀리지 않던 XOR 데이터셋 재준비# 입력 4종류와 이에 매칭되는 정답 4종류를 배열로 정의함.X_xor = np.array([[0,0], [0,1], [1,0], [1,1]])Y_xor = np.array([[0], [1], [1], [0]])# 2. 다층 신경망 (2입력 -> 4은닉 -> 1출력) 뼈대 세팅# 동일한 결과를 재현하기 위해 파이썬 난수 생성기의 시드(씨앗) 값을 42로 고정함.np.random.seed(42)# 입력층(2개)에서 은닉층(4개)으로 가는 W1 행렬을 생성하고, -1에서 1 사이의 난수로 무작위 초기화함.# 은닉 노드를 4개로 넉넉히 두어 2차원 평면을 고차원 입체로 충분히 비틀어 휘게 만듦.W1 = np.random.uniform(-1, 1, (2, 4))# 은닉층(4개)에서 출력층(1개)으로 가는 W2 가중치 파이프 4개를 난수로 초기화함.W2 = np.random.uniform(-1, 1, (4, 1))# 오차 역전파 시 가중치를 한 번에 크게 수정하여 빠르게 학습시키기 위해 학습률을 1.0으로 대폭 키움.learning_rate =1.0print("=== [실습 2-3] 오차 역전파를 이용한 XOR 문제의 완벽한 정복 ===")# 3. 10,000번의 순전파와 역전파 무한 루프 반복 훈련for epoch inrange(10000):# [순전파 단계]# 전체 입력 데이터(X_xor)를 은닉층(W1)으로 보내 시그모이드 비선형 함수로 압축 및 왜곡(내부 표상)시킴. hidden_out = sigmoid(np.dot(X_xor, W1))# 왜곡된 은닉층 데이터를 출력층(W2)으로 보내 최종 딥러닝 예측값(final_out)을 도출함. final_out = sigmoid(np.dot(hidden_out, W2))# [오차 계산 단계]# 최종 예측값이 정답(Y_xor)에서 얼마나 벗어났는지 모든 데이터 셋에 대해 오차 행렬을 계산함. error = Y_xor - final_out# [역전파 단계: 연쇄 법칙]# 출력층 사장님의 델타(국소 오차)를 미분 기울기를 곱해 계산함. d_output = error * sigmoid_derivative(final_out)# 사장님의 델타(d_output)를 W2 파이프를 타고 역류시킨 뒤, 은닉층 자체의 미분 기울기를 곱해 은닉층의 델타를 도출함. d_hidden = np.dot(d_output, W2.T) * sigmoid_derivative(hidden_out)# [가중치 업데이트 단계]# 계산된 사장층 델타에 학습률과 은닉층 출력 정보를 곱해 출력층 앞 가중치(W2)를 수정 누적함. W2 += learning_rate * np.dot(hidden_out.T, d_output)# 계산된 은닉층 델타에 학습률과 입력 정보를 곱해 말단-은닉 사이의 가중치(W1)를 수정 누적함. W1 += learning_rate * np.dot(X_xor.T, d_hidden)# 2000번 루프가 돌 때마다 현재의 전체 신경망이 손실 공간에서 얼마나 바닥(0)으로 내려왔는지 # '오차 제곱의 평균(MSE loss)'을 화면에 출력하여 모니터링함.if epoch %2000==0: loss = np.mean(np.square(error))print(f"[epoch {epoch:4d}] loss: {loss:.4f} (손실 공간을 타고 밑바닥으로 수렴 중...)")# 4. 학습 완료 후 최종 딥러닝 예측 결과 검증print("\n[학습 완료] XOR 예측 결과 테스트:")# 만 번의 훈련을 마치고 완벽히 조율된 W1과 W2를 사용해 마지막으로 전체 입력값에 대한 예측을 한 번 더 수행함.final_prediction = sigmoid(np.dot(sigmoid(np.dot(X_xor, W1)), W2))# 각 입력 패턴에 대해 모델이 출력한 예측값이 0 또는 1의 정답과 얼마나 가까워졌는지 출력함.for i inrange(4):print(f"입력: {X_xor[i]} -> 딥러닝 예측: {final_prediction[i][0]:.4f} (정답: {Y_xor[i][0]})")print("\n-> 최종 결론: 단층 모델로는 0.5에서 계속 멈추던 XOR 문제를, 은닉층을 통한 '비선형 공간 왜곡'과 역전파의 '미분 책임 배분'을 통해 완벽하게(0과 1에 극도로 수렴하게) 풀어냄!")print("-> 이것이 오늘날 모든 딥러닝 모델과 뇌 과학 연결주의 아키텍처를 작동시키는 근본 동력임.")
=== [실습 2-3] 오차 역전파를 이용한 XOR 문제의 완벽한 정복 ===
[epoch 0] loss: 0.2629 (손실 공간을 타고 밑바닥으로 수렴 중...)
[epoch 2000] loss: 0.0016 (손실 공간을 타고 밑바닥으로 수렴 중...)
[epoch 4000] loss: 0.0007 (손실 공간을 타고 밑바닥으로 수렴 중...)
[epoch 6000] loss: 0.0004 (손실 공간을 타고 밑바닥으로 수렴 중...)
[epoch 8000] loss: 0.0003 (손실 공간을 타고 밑바닥으로 수렴 중...)
[학습 완료] XOR 예측 결과 테스트:
입력: [0 0] -> 딥러닝 예측: 0.0187 (정답: 0)
입력: [0 1] -> 딥러닝 예측: 0.9894 (정답: 1)
입력: [1 0] -> 딥러닝 예측: 0.9829 (정답: 1)
입력: [1 1] -> 딥러닝 예측: 0.0142 (정답: 0)
-> 최종 결론: 단층 모델로는 0.5에서 계속 멈추던 XOR 문제를, 은닉층을 통한 '비선형 공간 왜곡'과 역전파의 '미분 책임 배분'을 통해 완벽하게(0과 1에 극도로 수렴하게) 풀어냄!
-> 이것이 오늘날 모든 딥러닝 모델과 뇌 과학 연결주의 아키텍처를 작동시키는 근본 동력임.
6주차 요약 및 다음 주 예고
[그림 17] 패러다임 비교: 선형적 덧셈에서 차원의 조작으로
요약
인지 시스템은 단순한 동시성 덧셈(헵 규칙)만으로는 복잡한 간섭현상을 통제할 수 없음.
레스콜라-와그너 모델이 시사하듯, 뇌는 예측오차를 계산하여 가중치를 미분적으로 깎아내는 델타 규칙(경사하강법)을 사용함.
역전파 알고리즘
다층구조에서 최종오차의 책임을 ’데이터를 기초 가공하는 은닉층(중간 관리자)’으로 거꾸로 전달함.
연결주의 모델이 직선적 사고의 한계를 넘어, 공간을 왜곡하고 복잡한 문제를 해결할 수 있게 만든 결정적인 수학적 엔진임.
다음 주(7주차) 예고
시냅스 가중치가 충분히 훈련된 이후, 뇌는 외부에서 쏟아지는 불확실한 감각정보(증거)들을 초당 단위로 어떻게 긁어모아 최종적인 의사결정을 내리는가?
이 과정에서 왜 어려운 문제는 반응시간(RT)이 오래 걸리는지, ‘빠른 결정(속도)’과 ’신중한 결정(정확성)’ 사이의 타협(trade-off) 메커니즘을 확률적인 그래프로 시뮬레이션하는 표류확산 모델(drift diffusion model, DDM)을 다룰 예정임.