블로그에 딥러닝에 대한 이론 지식 등도 정리를 해보려고 한다!
필자도 현재는 많이 배우는 단계라 (뭐든지 해보고 부딪히면서 배우는 스타일... 🤣),
공부한 내용을 글로 정리해두면 더 기억에 남을 것이라는 생각이 들었다.
오늘은 딥러닝에서 가장 흔하게 사용되는 알고리즘 중 하나인 Gradient descent, 즉 경사 하강법에 대해 알아보자!
Gradient Descent (경사 하강법)
경사 하강법이란 1차 미분계수를 이용하여 에러를 최소화하기 위해 함수의 최소값을 찾아가는 iteractive한 방법이다.
쉽게 말하면 임의의 초기값을 기준으로, 최소값을 찾아나가는 데에 최적화된 알고리즘이다.
머신러닝에서는 경사하강법을 사용하여 모델의 매개변수를 업데이트하는 식으로 진행된다.
더 쉽게 이해하기 위해 위 이미지를 참고해보자!
오른쪽 가장 높은 산(high cost)에서 왼쪽 아래의 가장 짙은 파란색의 바다(low cost)로 이동하는 것을 목표로 가정해보자. 이미지에 표시되어있는 화살표는 주어진 지점에서 가장 가파른 기울기, 즉 cost function을 가장 빠르게 감소시키는 방향을 표시하고 있다.
이러한 Gradient Descent를 수학적으로 정의하면 다음과 같다.
- := 는 대입연산자를 나타낸다. 초록색 원을 기준으로
- α 는 Learning Rate로, 학습 속도를 의미한다. 즉, 기울기를 나타내는데 얼마나 큰 폭으로 변화할 것인가에 대해 나타낸다. α가 클 수록 step에 이동하는 길이가 길어진다. 아래 이미지 처럼, 기준점이 최소값 (winner, in this case)에 가까워질 수록 변화하는 Learning rate가 점점 줄어드는 것을 확인할 수 있다. 이를 통해 우리는 학습률이 낮을 수록 더 정확하다는 것을 알 수 있다! 반면, 학습률이 낮기 때문에 최소값을 얻는데 걸리는 시간 또한 오래 걸린다.
- 파란 색으로 밑줄 친 부분은 미분 계수(Derivative Term)을 의미한다. cost function을 θ에 대해 미분한 값인데, θ₀,θ₁ 총 2가지 변수의 영향을 받고 있다.
그렇다면 다른 알고리즘들과 비교했을 때, 왜 Gradient Descent가 가장 많이 쓰이는 것일까?
아래와 같이 Linear regression 그래프를 찾아야된다고 가정해보자. 즉, 파란색 랜덤한 값들이 정해졌을 때, 가장 데이터를 잘 예측할 수 있는 빨간 선을 찾아내야한다고 생각해보자. 그렇다면 지금 위 그래프에 그려진 빨간 선이 최적의 선일까? 눈으로 판단하기에는 정보들이 너무 부정확하다. 이럴 때 바로 error(예측 값과 실제 값의 차이)를 가지고 판단하면 된다. 그럼 error가 최소화되는 빨간 선은 어떻게 찾을 수 있을까?
단순하게 생각한다면, 그래프 위에 가능한 모든 빨간 선을 그리고 error를 계산하는 것일 것이다. 하지만 이는 계산량이 너무 많아질 것이다... 모든 기울기에 대한 에러 값을 구할 수 있을 지언정 (아래 이미지의 오른쪽 그래프 처럼 2차함수로 나타낼 수 있음), 굉장히 비효율적이다.
이를 위해 나온 것이 바로 gradient descent이다!
위에서도 설명한 것 처럼, 임의의 한 점을 찍고 그 점의 미분 값을 구한 뒤, 그 미분 값을 통해 접선의 기울기를 알 수 있다. 이는 무엇을 뜻하느냐하면, 바로 파라미터를 어느 쪽으로 얼마나 더 움직일 지를 알려준다!
- 음수면 오른쪽으로 이동
- 기울기의 절대값이 크면 더 가파르게 움직임
- 최소값과 가까워질 수록 조금씩 천천히 움직임
훨씬 효율적인 방법이라, 이미 다양한 머신러닝, 딥러닝에 사용되고는 한다!
Python 코드로 보는 경사 하강법
W = np.random.uniform(-1, 1)
b = np.random.uniform(-1, 1)
learning_rate = 0.7
for epoch in range(200):
Y_Pred = W * X + b
error = np.abs(Y_Pred - Y).mean()
if error < 0.001:
break
# gradient descent 계산
w_grad = learning_rate * ((Y_Pred - Y)*X).mean() # 업데이트 해야하는 값
b_grad = learning_rate * (Y_Pred - Y).mean() # 업데이트 해야하는 값
# W, b 값 갱신
W = W - w_grad
b = b - b_grad
if epoch % 10 == 0:
Y_pred = W * X + b
plot_prediction(Y_Pred, Y)
이번에는 Python 코드를 통해 Gradient Descent를 구현해보았다!
다음 결과를 확인해보면 알 수 있드시, 두 선이 점점 가까워지는 것을 볼 수 있다!
(파란 선이 gradient descent 알고리즘을 통해 점점 업데이트 되고 있는 것이다.)
경사하강법을 이용할 때에는 적절한 Learning-rate를 설정하여야 한다.
Learning-rate가 크면 최적점을 넘어가버릴 수 있기 때문이다.
Stochastic Gradient Descent (확률적 경사 하강법)
이제 끝~~ 인 줄 알았지만... 경사 하강법에는 크게 세가지 종류가 있다!
경사 하강법은 파라미터 θ가 바뀔 때마다 Loss function의 결과값이 얼마나 바뀌는지, 그래디언트 벡터(gradient vector), 즉 기울기를 측정해야 한다. 또한 최소값에 도달하기 위해 그래디언트 벡터가 아주 작아질 때 까지(허용오차 범위 내로 들어올 때 까지) 진행되어야 한다. 즉, 한 번 업데이트를 할 때마다(한 step마다) 모든 데이터의 편도함수를 계산해야 한다는 것이다! 그렇기 때문에 훈련 세트가 커지면 속도가 매우 느리다는 단점이 있다 ㅠㅠ
경사 하강법은 배치 경사 하강법으로, 전체 학습 데이터를 하나의 배치로 (배치 크기가 n) 묶어 학습시킨다.
반면! 확률적 경사 하강법은 전체 데이터 중 단 하나의 데이터를 이용하여 경사 하강법을 1회 진행 (배치 크기가 1)하는 방법이다. 즉, 배치 경사 하강법과 정반대로, 무작위로 한 개의 데이터를 선택하고, 그 데이터값에 대한 그래디언트 벡터(기울기)만 계산한다. 매 스텝에서 적은 데이터만 처리하기 때문에 경사 하강법과 비교했을 때 계산 속도가 더 빠르다는 장점이 있다. 또한 훈련 세트가 크더라도 어렵지 않게 훈련시킬 수 있는 것은 물론, 배치 경사 하강법에 비해 적은 데이터로도 학습이 가능하다고 한다 (전체가 아닌, 단 하나의 데이터를 이용하여 기울기를 구하기 때문).
또한 확률적으로 랜덤하게 움직이기 때문에, 지역 최소값을 피하는 데에 훨씬 유리하다.
하지만 전역 최소값이 있는 구간에 들어오고 난 후에는 배치 경사 하강법처럼 이동하지는 않기 때문에 최소값에 도달하기 어렵다는 단점 또한 존재한다.
마인즈컴퍼니 기술블로그에 따르면, 이를 해결하기 위해 초기 learning rate를 상대적으로 크게 설정하여 지역 최소값보다 더 빠르게 다가갈 수 있게 만들어주고, 이후 learning rate를 점진적으로 줄여가며, 전역 최소값에 보다 더 정확하게 수렴할 수 있게 만들어주는 Learning rate annealing 이라는 방법을 사용하는 방법도 있다고 한다.
Mini-batch Gradient Descent (미니 배치 경사 하강법)
마지막으로 미니 배치 경사 하강법에 대해 알아보자!
미니 배치 경사 하강법은, 배치 경사 하강법과 확률적 경사 하강법의 장단점을 합친 방법으로, 실제로 가장 많이 사용되는 방법이다. 먼저 훈련 데이터셋을 등분한 샘플 세트(미니 배치)에 대해 그래디언트 벡터를 계산한다.
미니배치 경사 하강법은 배치 경사 하강법보다는 불규칙하고 확률적 경사 하강법보다는 안정적이기 때문에, 배치 경사 하강법보다는 짧은 시간안에, 그리고 확률적 경사 하강법보다는 정확한 전역 최소값에 도달할 수 있다는 장점을 가지고 있다.
하지만 이 말은 동시에 배치 경사 하강법보다는 지역 최소값에서 빠져나오기 힘들고, 확률적 경사 하강법보다는 비교적 느리다는 단점도 있다는 것을 의미한다...
따라서 이런 점에 유의해서, 세 가지의 경사 하강법 방법 중 적절한 것을 선택하는 것이 좋을 것 같다!
다음에는 위에서 잠깐 언급했던 Loss function에 대해서도 다뤄보겠다! ㅎㅎㅎ
[참고]
'𝑷𝒓𝒐𝒈𝒓𝒂𝒎𝒎𝒊𝒏𝒈 > 𝐴𝐼' 카테고리의 다른 글
[AI/DL] Image Segmentation (0) | 2023.05.26 |
---|---|
[AI] Android Studio, flutter project에 딥러닝 모델 배포, 적용하기 (Pytorch-lite) (1) | 2023.05.15 |
[AI] GPT에 대한 고찰 (0) | 2023.01.31 |