호다닥 작성하겠습니다.
경사하강법 gradient descent
경사하강법은 인공지능에서 많이 언급되는 단어입니다. ML, AL 책에서 정말 많이 본 개념이 경사하강법 gradient descent 이었습니다. 영어 단어로 gradient 는 기울기, 경사, 변화나 증감을 의미하고, descent는 하강, 내려오다, 내려가다, 내리막이 되다 란 의미를 가진 단어입니다. gradient descent는 내려오는 기울기의 변화 란 뜻이 되면서 미분의 개념이 연결됩니다. 미분 공식들은 현재 상태에서 앞으로 어떻게 변화할지를 측정하니까요. 인공신경망에서는 최적의 파라미터 값을 찾을 때 많이 사용됩니다.
편미분 partial derivate
AL에서의 미적분은 일반적인 미적분과는 다르게 다변량 미적분이 필요합니다. 일반적인 미적분은 함수가 f(x) = x^2 + x + 5 와 같은 다항식에서 미분과 적분의 개념을 구해서 순간변화율과 평균변화율 그리고 넓이의 값을 계산하는 것이죵. 그런데 multivariate calculus의 경우에는 변수가 하나만 있는 게 아니라 여러 개 존재합니다. 입력 값이 많다보니 여러개의 변수 값을 가지게 되는데 각 변수마다의 움직임을 측정해야 합니다. 동일하게 접선의 기울기를 구해서 측정하는 미분 개념이 들어가는데 여러 개의 변수를 미분할 때는 편미분(partial derivate)라고 합니다. 예를 들어서
미분 derivate
f(x) = = (x - 1)^2 를 미분하는 것은 f'(x) = 2x - 2 혹은 dy / dx 라고 표현
편미분 partial derivate
f(x, y) = x^2 - xy + 2를 편미분하면
∂f / ∂x = 2x - y
∂f / ∂y = -x
로 나옵니다.
편미분이 중요한 이유
에러의 최소값을 구하거나 레이어를 쌓을 때 backpropagation을 구할 때 필요합니다. 차원이 여러 개 넘어가면 애초에 손계산은 불가능하고 컴퓨터로 덧셈, 뺄셈, 곱셈, 나눗셈을 해야 하는데, 입력 노드 값은 하나인 경우는 잘 없습니다(...있을까??). 수십개의 멀티 입력값이 있고 각 항목 당 가중치와 오차를 계산해야 합니다. 쉽게 이해하면 화살표 하나의 움직임 당 back 방향으로 가중치를 계산하는 게 편미분입니다. 아무리 컴퓨터라도 시간이 걸리기 때문에 backpropagation을 구할 때는 시간이 좀 걸립니다. (특히, cpu) 대신 오차는 줄어듭니다. 한 번 왔다 가는 걸 1 epoch 로 계산합니다.
경사하강법 손계산하기
경사하강법 2차 함수를 통해서 간단하게 손계산을 해보면....
예를 들어, 어떤 오차가 f(x) = (x - 1)^2 의 함수의 형태로 값이 변한다고 가정하고 이 오차를 최소화한다고 한다면...✍️
직관적으로 생각했을 때, 최적값은 x = 1 입니다. 혹은 이차함수 미분했을 때의 값은 f'(x) = 2x -2 = 2(x -1)로 구해서 계산해도 되지만 이 함수는 간단하기 때문에 사람은 눈으로 풀 수 있죠. 하지만,
"이 계산을 컴퓨터에겐 어떻게 시키죠?"
일단 손으로 풀면...
뭐가 최소값인지 알 수 없는 상태라고 치고. 일단 대략 감에 의지해 시작점을 3 정도로 잡고,
3에서 시작해서 조금씩 내려갑니다. f'(x) 값이 0에 가까울 수록 최소값이니까,
일단 f'(x) = 2x -2 에서 0이 나오면 최적의 값입니다. derivate의 목표를 대략 0.000001로 잡고, 이 값이 나오도록 움직입니다.
어느 정도로 움직일 건지를 learning rate; lr이라고 하는데 0.01로 lr을 잡았습니다 (혹은 0.001, 0.0001 이렇죠..)
(이후 x값) = (현재 x값) - (learning rate) * dy/dx
현재 값 3 기준,
으로 계산 하면 3 - (0.01) * 4 = 2.96 입니다.
f'(3) =dy / dx = 6 - 2 = 4 이고
lr 이 0.01 이니 0.01 * 4 = 0.04
3 - 0.04 = 2.96 정도 입니다.
그럼 현재 값 3 - 2.96 = 0.04 정도의 차이가 생겼습니다.
그럼 다음 값은 2.96이고 이걸 다시 넥스트 스텝으로 구해 줍니다.
현재 값 2.96 기준,
2.96 - (0.01)*f'(2.96) = 2.96 - (0.01) * (3.92) = 2.9208 입니다.
(현재 값) - (이후 값) = (learning rate) * dy /dx
해당 차이는 0.0392 정도입니다
현재 값 2.9208 기준,
2.9208 - (0.01)*f'(2.9208) = 2.9208 - (0.01)*(3.84159) = 2.882384...
이전 값과의 차이는 0.0384159.....
순으로
계속 반복합니다
이전 값과의 차이를 0이 되도록 줄여나갔을 때, 나오는 x값이 최적값입니다.
이젠 컴퓨터 없인 힘들어서 코드로 실행하면,
# 원본 함수 (x-1)^2
def original_function(x):
return (x-1)**2
# 미분하기
def derivate_function(x):
print("derivate : ", 2*(x-1))
return 2 * (x - 1)
다음과 같이 함수를 정의하고
current_x = 3
learning_rate = 0.01
derivate_goal = 0.000000000000000001 # 최대한 0에 가깝도록 한다면?
current_minus_previous_value = 1
iteration_count = 0
while current_minus_previous_value > derivate_goal:
previous_x = current_x
current_x = current_x - rate * derivate_function(previous_x)
print("x(n+1) 값 : ", current_x)
current_minus_previous_value = abs(current_x - previous_x)
print("x(n+1)-x(n) : ", current_minus_previous_value)
iteration_count += 1
print("-"*100)
print(current_x)
print(iteration_count)
로 돌리면 결과는
1이 나오고.
거의 0에 가깝게 돌린 횟수는 1,655번 정도 돌렸습니다.
결론:
사람은 눈으로 보면 미분 함수 f'(x) = 2(x-1) 에서 minimum 값이 1이라는 걸 직관적으로 이해하지만,
컴퓨터는 그렇지 못하다. 해당 값이 나오기 위해 천번 이상 돌렸습니다~ 그리고 이런 과정을 짜는 게 AI, ML 분야입니다.
끝.
'NLP-writing' 카테고리의 다른 글
텍스트 분류 (0) | 2023.05.21 |
---|---|
한국어 텍스트 데이터 전처리 (5) | 2023.05.07 |
Linear Algebra 선형대수학 with NLP (0) | 2023.04.09 |
3. Probability - 베이지안Bayesian (0) | 2023.03.26 |
2 정규표현식을 익히자 Regular Expression with Python (0) | 2023.03.20 |