딥러닝의 가중치 업데이트 공식

오늘은 딥러닝에서 가장 중요한 공식 중 하나인 **”새로운 가중치 = 기존 가중치 – 학습률 × gradient”**를 아주 쉽게 설명해보겠습니다. 이 공식이 어떻게 작동하는지, 왜 이렇게 생겼는지, 그리고 실제로 어떻게 쓰이는지 차근차근 알아볼게요! 🎯

🏔️ 산 정상 찾기 게임으로 이해하기

상황 설정

여러분이 짙은 안개 속에서 산의 가장 낮은 곳(골짜기)을 찾아야 한다고 상상해보세요. 주변이 전혀 보이지 않고, 오직 자신이 서 있는 곳의 경사만 느낄 수 있습니다.

이때 어떻게 해야 할까요? 당연히 경사가 내려가는 방향으로 한 발씩 움직이면 됩니다!

딥러닝과의 연결

  • 산의 높이 = 오차(얼마나 틀렸는지)
  • 현재 위치 = 현재 가중치
  • 경사 = gradient
  • 한 걸음의 크기 = 학습률

📚 각 요소 자세히 알아보기

1. 가중치(Weight)란?

가중치는 신경망이 가진 지식이라고 생각하면 됩니다.

예시: 시험 공부

  • 처음 공부 시작 = 랜덤한 가중치
  • 문제 풀면서 배움 = 가중치 업데이트
  • 완전히 이해함 = 최적의 가중치
# 간단한 예시
초기_가중치 = 0.5  # 처음엔 대충 찍음
정답 = 2.0         # 실제 답
예측값 = 초기_가중치 * 입력값  # 우리의 추측

2. Gradient(기울기)란?

Gradient는 **”지금 내가 틀린 정도”와 “어느 방향으로 고쳐야 하는지”**를 동시에 알려줍니다.

실생활 예시:

  • 농구 슛을 쏘는데 왼쪽으로 빗나감 → “오른쪽으로 더 가야 함”
  • 수학 문제 답이 작게 나옴 → “더 큰 수로 계산해야 함”
# Gradient 계산 예시
실제_답 = 10
내_답 = 7
오차 = 실제_답 - 내_답  # +3 (내 답이 작다)
gradient = 오차 * 입력값  # 얼마나, 어느 방향으로 고쳐야 하는지

3. 학습률(Learning Rate)이란?

학습률은 한 번에 얼마나 고칠지 결정하는 값입니다.

비유하자면:

  • 🐢 작은 학습률(0.01) = 조심조심 한 걸음씩
  • 🐰 큰 학습률(0.5) = 큰 보폭으로 뛰어감
# 학습률의 영향
gradient = 10  # "10만큼 고쳐야 해!"

# 작은 학습률
학습률_작음 = 0.01
수정량_작음 = 학습률_작음 * gradient  # 0.1만 고침

# 큰 학습률
학습률_큼 = 0.1
수정량_큼 = 학습률_큼 * gradient  # 1.0 고침

🤔 왜 빼기(-)를 사용할까?

여기서 많은 학생들이 헷갈려합니다. “왜 더하기가 아니라 빼기일까?”

산을 내려가는 비유

  1. 오른쪽이 올라가는 경사 (양수 gradient) → 왼쪽으로 가야 함 (빼기)
  2. 왼쪽이 올라가는 경사 (음수 gradient) → 오른쪽으로 가야 함 (빼면 더해짐)
# 구체적인 예시
현재_위치 = 5

# 경우 1: 오른쪽이 올라감
gradient = +2  # 양수: 오른쪽이 더 높음
새_위치 = 현재_위치 - 0.1 * gradient  # 5 - 0.2 = 4.8 (왼쪽으로 이동)

# 경우 2: 왼쪽이 올라감  
gradient = -2  # 음수: 왼쪽이 더 높음
새_위치 = 현재_위치 - 0.1 * gradient  # 5 - (-0.2) = 5.2 (오른쪽으로 이동)

🎯 전체 과정 예시

숫자 맞추기 게임

컴퓨터가 숨긴 숫자를 맞추는 게임을 만들어봅시다!

import numpy as np
import matplotlib.pyplot as plt

# 1. 초기 설정
정답 = 7.0
현재_추측 = 2.0  # 처음엔 아무 숫자나
학습률 = 0.1

# 학습 과정 기록
추측_기록 = []
오차_기록 = []

# 2. 학습 시작! (20번 반복)
for 단계 in range(20):
    # 현재 얼마나 틀렸나?
    오차 = 정답 - 현재_추측
    
    # gradient 계산 (여기선 단순히 오차)
    gradient = -오차  # 음수: 추측이 작으면 늘려야 함
    
    # 가중치 업데이트
    현재_추측 = 현재_추측 - 학습률 * gradient
    
    # 기록 저장
    추측_기록.append(현재_추측)
    오차_기록.append(abs(오차))
    
    print(f"단계 {단계+1}: 추측={현재_추측:.2f}, 오차={오차:.2f}")

시각화

plt.figure(figsize=(12, 5))

# 추측값 변화
plt.subplot(1, 2, 1)
plt.plot(추측_기록, 'b-o')
plt.axhline(y=정답, color='r', linestyle='--', label='정답')
plt.xlabel('단계')
plt.ylabel('추측값')
plt.title('추측값이 정답에 가까워지는 과정')
plt.legend()

# 오차 변화
plt.subplot(1, 2, 2)
plt.plot(오차_기록, 'g-o')
plt.xlabel('단계')
plt.ylabel('오차')
plt.title('오차가 줄어드는 과정')
plt.show()

🎨 더 복잡한 예시: 직선 그리기

이번엔 점들을 가장 잘 지나가는 직선을 찾아봅시다!

# 데이터 준비
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 7, 8])  # 대략 y = 1.5x + 0.5

# 초기 추측
기울기 = 0.5  # 아무 값
절편 = 0.0    # 아무 값
학습률 = 0.01

# 학습
for 반복 in range(100):
    # 현재 직선으로 예측
    예측 = 기울기 * x + 절편
    
    # 오차 계산
    오차 = y - 예측
    
    # gradient 계산
    gradient_기울기 = -2 * np.mean(오차 * x)
    gradient_절편 = -2 * np.mean(오차)
    
    # 가중치 업데이트
    기울기 = 기울기 - 학습률 * gradient_기울기
    절편 = 절편 - 학습률 * gradient_절편
    
    if 반복 % 20 == 0:
        print(f"반복 {반복}: y = {기울기:.2f}x + {절편:.2f}")

💡 중요한 팁들

1. 학습률 선택

# 너무 작으면...
학습률 = 0.0001  # 🐌 너무 느림! 1000번 반복해도 안 끝남

# 적당하면...
학습률 = 0.01   # 👍 딱 좋음! 빠르고 안정적

# 너무 크면...
학습률 = 1.0    # 💥 폭발! 답을 지나쳐서 발산함

2. Gradient가 0인 경우

if abs(gradient) < 0.001:
    print("거의 정답에 도달했어요! 더 이상 움직일 필요 없음")
    break

3. 실제 사용 예

class 간단한_모델:
    def __init__(self):
        self.가중치 = np.random.randn()
        self.편향 = 0
    
    def 예측(self, x):
        return self.가중치 * x + self.편향
    
    def 학습(self, x, y, 학습률=0.01):
        # 1. 예측
        예측값 = self.예측(x)
        
        # 2. 오차 계산
        오차 = y - 예측값
        
        # 3. Gradient 계산
        gradient_가중치 = -np.mean(오차 * x)
        gradient_편향 = -np.mean(오차)
        
        # 4. 가중치 업데이트 (핵심 공식!)
        self.가중치 = self.가중치 - 학습률 * gradient_가중치
        self.편향 = self.편향 - 학습률 * gradient_편향

🎮 직접 해보기: 미니 게임

def 숫자_맞추기_게임():
    import random
    
    정답 = random.randint(1, 100)
    내_추측 = 50.0
    학습률 = 0.1
    
    print("1~100 사이의 숫자를 맞춰보세요!")
    
    for 시도 in range(20):
        print(f"\n시도 {시도+1}: 현재 추측 = {내_추측:.1f}")
        
        # 힌트 받기
        if 내_추측 < 정답:
            gradient = -1  # 더 크게 해야 함
            print("더 큰 수입니다!")
        elif 내_추측 > 정답:
            gradient = 1   # 더 작게 해야 함
            print("더 작은 수입니다!")
        else:
            print(f"정답! 숫자는 {정답}이었습니다!")
            break
        
        # 가중치 업데이트 공식 적용!
        조정량 = 학습률 * abs(정답 - 내_추측)
        내_추측 = 내_추측 - gradient * 조정량
        
        # 범위 제한
        내_추측 = max(1, min(100, 내_추측))

# 게임 실행
숫자_맞추기_게임()

📝 정리하며

“새로운 가중치 = 기존 가중치 – 학습률 × gradient” 공식은:

  1. 가중치: 우리의 현재 지식/추측
  2. Gradient: 틀린 방향과 정도
  3. 학습률: 한 번에 고칠 양
  4. 빼기(-): 오차를 줄이는 방향으로 이동

이 공식은 마치 목표를 향해 한 걸음씩 나아가는 것과 같습니다:

  • 너무 빨리 가면 목표를 지나칠 수 있고
  • 너무 천천히 가면 시간이 오래 걸리죠

실제로 이 단순한 공식이 ChatGPT 같은 인공지능의 핵심이 됩니다! 물론 실제로는 수십억 개의 가중치를 동시에 업데이트하지만, 원리는 똑같답니다.

이제 여러분도 딥러닝의 핵심 원리를 이해하셨네요! 🎉 다음에 인공지능 뉴스를 볼 때, “아, 컴퓨터가 가중치를 업데이트하면서 학습하는구나!”라고 생각할 수 있을 거예요.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다