딥 러닝의 중요한 개념 중 하나인 경사하강법.
딥 러닝 공부를 하면서 직관적으로 이해는 하고 있었지만 이번 기회에 확실히 짚고 넘어가기 위해 글을 작성합니다!
하하하!!
1. 경사하강법?
경사 하강법(Gradient Descent)은 기본적으로 함수의 기울기(경사)를 따라 손실을 최소화하는 방향으로 이동하는 최적화 알고리즘입니다. 이 알고리즘은 주어진 손실 함수의 값이 가장 작은 지점(최솟값)을 찾기 위해 사용됩니다.by chat gpt
1.1 위의 정의를 하나씩 뜯어봅시다!
- 문과 출신 개발자로써 저렇게 모르는 걸 챗gpt에 물어보면 단어들이 어려워서 이해하기 매우 어렵더라구요! 그래서 저와 같은 분들을 위해 자세히 설명해보고자 합니다!
- 중요한 것은 이 문장 입니다 이 알고리즘은 주어진 손실 함수의 값이 가장 작은 지점(최솟값)을 찾기 위해 사용됩니다.
그 전에 경사 하강법(Gradient Descent)은 기본적으로 함수의 기울기(경사)를 따라 손실을 최소화하는 방향으로 이동하는 최적화 알고리즘입니다.
이 문장 또한 짚고 넘어가자면
첫째 목적은 최솟값.
경사하강법을 검색하면 위 그림이 대표적으로 나옵니다.
노란색 동그라미 부분(최솟값)을 찾아가는 것이 경사하강법의 목표입니다.
둘째 기울기?(미분)
경사하강법의 최솟값을 찾는 방법은 미분(정확히는 편미분)을 통해 현재의 기울기를 파악하고 더 낮은 지점으로 움직이도록 하는 방식을 통해 최솟값을 찾아갑니다. (어? 이쪽이 더 기울었네~ 이쪽으로 가야지!)
최솟값을 찾아가는 것 그리고 그것은 미분으로 기울기를 계산해서 찾아간다!
일단 이것만 기억해주세요!
2. 손실함수
손실함수는 예측값과 실제값의 차이를 말합니다. 예측값과 실제값의 차이를 줄이는 것이 학습의 목표이기 때문에 위 경사하강법 설명에서도 최솟값을 찾아가는 것이라 강조해드렸었죠!
결론 부터 말씀드리자면 우리는 손실함수의 생김새를 모르는 상태에서 학습을 진행합니다.
위 경사하강법 이미지에서 U자의 곡선 그래프는 손실함수의 그래프 입니다.
위 그림에는 단순하게 보일지 몰라도 실제 손실함수의 예상 이미지를 보면
이렇게 복잡하게 생겼습니다.
하지만 우리는 어떤 딥러닝 모델을 학습 시킬때 손실함수의 정확한 생김새를 알 수 없습니다.
알고 있다면 모델을 학습시킬 필요도 없어지겠죠? 하하
하지만 우리는 손실함수의 편미분 함수인 편도함수를 알 고 있습니다.
즉 현재 상태에서의 기울기를 알 수 있다는 것이에요 !
그 기울기를 통해 점점 최솟값을 찾아나가는 것이 경사하강법 입니다!
이해를 돕기 위해 코드를 가져왔습니다.
import numpy as np
# 독립변수가 5개인 다섯 차원 데이터 생성
np.random.seed(0) # 랜덤 시드 고정
X = np.random.rand(100, 5) # 5개의 독립변수로 이루어진 100개의 데이터 랜덤 생성
y = np.random.rand(100) # 각 데이터에 대한 종속 변수 y값 타겟 랜덤 생성
# 초기 가중치와 편향 설정
# 초기 가중치는 랜덤으로 설정됩니다.
w = np.random.rand(5) # 다섯 개의 가중치
b = np.random.rand() # 편향
# 모델의 예측값 계산
# 데이터에 가중치와 편향을 적용시켜 예측값 생성
y_pred = np.dot(X, w) + b
# 손실함수 정의 MSE 계산
mse = np.mean((y_pred - y) ** 2)
#learning_rate는 학습의 보폭과 같은 느낌 이부분은 나중에 다시 포스팅 하겠습니다 !
learning_rate = 0.01
epochs = 1000
# 경사 하강법을 사용하여 모델 학습
for epoch in range(epochs):
# 손실 함수에 대한 w와 b의 편도함수 계산
# 2 * 블라블라 밑의 공식은 mse의 편도함수입니다.
# 편도함수에 이번 epochs의 X값과 y_pred - y차이값을 넣어서 기울기를 계산하는 것.
dw = 2 * np.mean(np.dot(X.T, (y_pred - y))) # 다섯 차원 데이터에 대한 편도함수
db = 2 * np.mean(y_pred - y)
# 모델 매개변수 업데이트
w -= learning_rate * dw
b -= learning_rate * db
# 모델 업데이트 후 예측값 다시 계산
y_pred = np.dot(X, w) + b
# 업데이트된 MSE 계산
mse = np.mean((y_pred - y) ** 2)
# 매 100번째 에포크마다 손실 출력
if (epoch+1) % 100 == 0:
print(f"Epoch {epoch+1}, MSE: {mse:.2f}")
위 코드를 통해 이해가 잘 되셨으면 좋겠네요!
질문과 피드백은 언제나 환영입니다!