[카테고리:] 미분류

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

    오늘은 딥러닝에서 가장 중요한 공식 중 하나인 **”새로운 가중치 = 기존 가중치 – 학습률 × 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 같은 인공지능의 핵심이 됩니다! 물론 실제로는 수십억 개의 가중치를 동시에 업데이트하지만, 원리는 똑같답니다.

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