2021. 10. 1. 01:44ㆍDeep Learning
본 게시글은 한빛미디어 『밑바닥부터 시작하는 딥러닝, 사이토 고키, 2020』의 내용을 참조하였음을 밝힙니다.
지금까지 퍼셉트론의 개념을 통해 입력값(input)과 가중치(weigth) 그리고 편향(bias)를 통해 결과를 도출하고,
손실함수를 통해 예측값과 실제(타깃)값과의 괴리를 측청하여 이를 가중치 업데이트에 반영하는 방법을 알아보았다.
이번에는 경사 하강법이라는 개념을 통해 실제로 가중치를 업데이트하는 방법을 알아보도록 하자.
경사하강법(gradient descent)
산에 조난자가 있다고 가정하자. 이 조난자는 눈이 다치는 바람에 앞을 볼 수 없고, 다시 베이스 캠프로 돌아가기 위해
경사를 더듬에서 원래 출발점이 있던 곳으로 내리막길을 따라 내려가야한다. 내려가다보면 내리막을 멈추고 어느 순간
평평해지는 부분을 만나게 된다. 2차 함수에서 기울기가 0이 되는 부분으로, 기울기가 0이라는 것을 그 주변에서는 가장
낮은 지점이라는 것을 의미한다.(내리막을 내려왔으니 최고점일리는 없다)
직관적으로 생각했을 때 애 주변에 가장 경사가 가파른 곳을 따라 가다보면 가장 내리막길이 있을 가능성이 높다.
하지만 이는 그 당장에서 할 수 있는 최선의 선택일 뿐이지 베이스 캠프가 존재할 것이라는 보장은 없다!
그래도 가장 낮은 지점을 찾기 위해서 우리가 할 수 있는 일은 가장 가파른 내리막길을 따라 한걸음 한걸음 다리를
옮기는 수밖에 없다.
위의 개념이 경사 하강법(gradient descent)이다.
손실 함수는 예측값과 타깃값과의 괴리, 즉 예측이 많이 틀릴 수록 손실 함수의 값을 커지고,
그 예측의 주변에 있는(비슷한 수준의) 예측 역시 비슷하게 큰 손실값을 가질 것이다.
다시 말해 해당 예측을 만들어낸 가중치들은 곧 큰 gradient 값들을 만들고 정답에 근접하기 위해서
큰 변화가 필요하다.(경사가 가파르다) 그 gradient 값들을 기존 가중치에서 차감하고 새로운 가중치로
업데이트한다. 반대로 정답에 근접한 예측값을 만들어낸 가중치들은 작은 손실값을 나타낼 것이고,
미미한 수준의 가중치 업데이트를 가져온다. (경사가 완만하다.)
출처 : https://blog.paperspace.com/intro-to-optimization-in-deep-learning-gradient-descent/
내가 최저점에 근접하기 위해 한걸음 한걸음 걸어가야한다. 보폭이 크면 클수록 빠르게 내려갈 수 있고
보폭이 작다면 그만큼 소요시간도 크게 가진다. 여기서의 보폭은 '학습률'의 비유이다.
학습률(learning rate)이란 가중치 업데이트를 할 때 업데이트 강도를 나타내는 지표이다.
학습률이 크면 올바른 가중치까지 도달하는 시간이 적게 소요된다. 쉽게 말하면 정답을 빨리 찾을 수 있다.
하지만 크게 하는 것이 능사는 아니다.
출처 : https://www.jeremyjordan.me/nn-learning-rate/
위 그림처럼 학습률이 너무 크면 최저점을 지나칠 가능성이 커서 오히려 학습에 방해가 된다.
가운데 그림처럼 처음에 학습률을 크게 했다가 시간이 지남에 따라 학습률을 점차 작게해서 시간효율/정확성 모두
달성하는 방식도 있다(나중에 알아보도록 하자).
경사 하강법을 코드로 구현해보자.
def gradient_descent(f, init_x, lr=0.01, step_num=100):
x = init_x
for i in range(step_num):
grad = numerical_gradient(f, x)
x -= lr*grad
return x
처음 주어진 변수값을 x에 저장하고 함수 f의 x에서의 그레디언트를 구한다.
계산된 그레디언트에 학습률을 곱하고 기존 변수(혹은 가중치)에서 이를 차감한다.
이 과정을 step_num 회만큼 반복하고 최종적으로 구해진 x를 반환한다.
def func1(x):
return (x[0]-2)**2 + 4*(x[1]-3)**2
최소값을 찾고자 정한 함수는 위와 같다. 위 함수가 더미(dummy) 손실함수라고 생각하면 된다.
3차원으로 그려봤을 때 위 함수는 (2, 3)에서 최소값을 갖는다.
>>> print(gradient_descent(func1,np.array([100.0, -10.0]),0.01, 1000))
[2.00000016 3. ]
초기값으로 x[0]에서 100, x[1]에서 -10을 주고 학습률을 0.01, 총 업데이트 과정을 1000번 거치도록 설정하였다.
이에 따라 가장 작은 x 값인 (2, 3)에 매우 근접하였음을 확인할 수 있다.
'Deep Learning' 카테고리의 다른 글
[밑바닥딥러닝] 9. 오차역전파법(backpropagation) - 계산그래프 (0) | 2021.10.03 |
---|---|
[밑바닥딥러닝] 8. 2층 신경망 구현, 미니배치 학습 (0) | 2021.10.01 |
[밑바닥딥러닝] 6. 수치 미분, 편미분 (0) | 2021.10.01 |
[밑바닥딥러닝] 5. 신경망 학습 - 손실 함수, 미니 배치 학습 (0) | 2021.09.30 |
[밑바닥딥러닝] 4. 신경망 구현 - 손글씨 인식 (0) | 2021.09.12 |