인공지능 network 구조를 이해하기 위해 정리하는 글입니다.
|정의|
경사하강법(Gradient Descent)은 1차 근삿값 발견용 최적화 알고리즘이다. 기본 개념은 함수의 기울기(경사)를 구하고 경사의 절댓값이 낮은 쪽으로 계속 이동시켜 극값에 이를 때까지 반복시키는 것이다. 출처: wikipedia.org |
|사용용도|
사용용도를 알기 위해선 머신러닝의 일반적인 학습 방법에 대한 이해가 필요합니다.
머신러닝 모델은 입력된 데이터를 기반으로 학습합니다.
아직 충분한 데이터를 보지못단 학습모델은 정답이 아닌 결과를 출력할 가능성이 큽니다.
그런데 데이터에 대한 정답이 얼마나 가까운지는 어떻게 판단할까요?
이는 산술적인 거리(distance)로 예측한 결과와 실제값을 비교하여 정답을 맞힙니다.
이때 학습데이터로 계산한 거리들의 평균을 오차(loss)라고 합니다.
오차(loss)가 작은 머신러닝 모델일수록 주어진 데이터에 대해 더 정확한 답을 낸다고 생각하면 됩니다.
오차를 최소화하기 위한 여러 가지 알고리즘이 존재합니다.
그중 많이 쓰이는 알고리즘이 중 하나가 경사하강법(Gradient Descent)입니다.
가장 간단한 예제인 선형 회귀를 예로 들어보면,
선형으로 분포된 직선과 같은 함수를 찾는 것이다.
이때 오차를 구하기 위해 평균제곱오차(Mean Squared Error, MSE)를 이용한다.
|평균제곱오차(Mean Squared Error, MSE)|
평균제곱오차는 오차(error)를 구해서 제곱한 값들의 평균입니다.
오차는 위에서 말했듯이 예측값과 정답과의 차이를 의미합니다.
즉 정확도가 높을수록 MSE는 작음을 알 수 있습니다.
공식
|학습률(Learning Rate)이란?|
파라미터를 업데이트하는 정도를 조절하기 위한 변수입니다.
적절한 모델과 가중치초깃값을 설정했어도, 학습률에 따라서 모델의 학습정도가 달라질 수 있습니다.
|Proper Learning Rate 찾는 법|
위에서 학습률은 cost함수에서 최솟값을 구하기 위한 기울기로 사용되는 학습률이라고 말씀드렸는데요.
이는 학습의 속도를 조절하는 중요한 기준점이 됩니다.
이때 학습률이 클 수도 있고, 작아질 수도 있는데 이때
1) 학습률이 너무 큰 경우: 데이터가 이탈해 버려 최저점에 수렴하지 못합니다.
2) 학습률이 너무 작은 경우: 최저점에 도달하는데 매우 오랜 시간이 걸립니다.
따라서 적절한 학습률이란?
==> 정확하고 빠르게 최저점에 도달하는 학습률을 의미하고, 이를 반복문마다 찾는 게 가장 중요한 요인입니다.
올바른 학습률 설정방법은?
함수그래프를 보고 멀리 가도 학습률을 크게 해도 overshooting이 발생하지 않는 선에서 유지합니다.
만약 함수값이 최저점에 도달할 거 같다면 작게 하는 것입니다.
이는 epoch를 반복하면서 맞추는 방법밖에 없습니다.
아래 코드에서 자세히 설명드리겠습니다.
|예시|
경사하강법 python코드로 구현하기
def loss_ex1(w): # 2.75일 때, 최솟값 -14를 가진다.
loss = 2 * w * w - (11 * w) + 1 # y값
loss_grad = 4 * w - 11 # 미분값
return [loss, loss_grad]
def loss_ex2(w): # 1일때 최솟값 2를 가진다.
loss = 2 * w * w - (2 * w) + 3
loss_grad = 2 * w - 2 # 미분값
return [loss, loss_grad]
<2차 함수 2가지 예시>
l_r = 0.3 # 학습률
start = 10 # torch.tensor(10.0, requires_grad=True)
[before_loss, before_loss_grad] = loss_ex1(start) # 함수에 의한 값 받아오기
start -= l_r
for i in range(300):
[loss, loss_grad] = loss_ex1(start) # 함수에 의한 값 받아오기
print("epoch =", i+1,",", "기울기 =",round(loss_grad,1) ,",", "x절편 =", round(start,1),",", "y절편 =", round(loss,1), ",","lr =", round(l_r, 3) )# 값 찍어보기
if (loss_grad > -0.01) and (loss_grad < 0.01): # 종료조건 ==> 기울기가 0에 거의 도착햇을때
print("Answer : ", round(start, 2))
break
else:
if before_loss_grad*loss_grad > 0 and before_loss-loss > 0: # 기울기가 올바로 내려갈 때
if loss_grad>0: # 기울기가 오른쪽에서 올때
start -= l_r
else: # 기울기가 왼쪽에서 올 때
start += l_r
else: # 과적합 되었을 때 ==> 통통 튈 때
l_r -= 0.01 # 학습률의 절대값크기를 줄이기
if loss_grad>0: # 기울기가 오른쪽에서 올때
start -= l_r
else:
start += l_r
before_loss = loss
before_loss_grad = loss_grad
overshooting이 발생되지 않는 선에서 Learing_Rate를 계속 유지하였고
만약 과적합되었다면 else문에서 학습률을 줄였다.
참고) 펭귄브로의 3분 딥러닝 [파이토치맛]