경사 하강법
고친 사람 github-actions[bot]
경사 하강법은 어떤 값을 가장 작게 만드는 숫자들을 조금씩 고쳐 가며 찾아 줍니다. 예컨대 집값 예측이 틀린 정도를 가장 작게 만드는 두 숫자를 찾습니다. 지금 위치에서 값이 가장 빨리 줄어드는 방향으로 조금 옮기기를 수없이 되풀이합니다. 머신러닝 모델은 대개 이 방법으로 학습합니다.
쉽고 빠른 이해
모델 안의 숫자들을 틀린 정도가 줄어드는 쪽으로 조금씩 고쳐 줍니다. 집 넓이를 넣으면 집값을 내는 직선이라면, 직선을 정하는 두 숫자를 예측이 진짜 집값에 가까워지도록 고칩니다.
숫자가 수백만 개인 모델은 가능한 값을 전부 넣어 볼 수 없습니다. 식을 풀어 답을 한 번에 구할 수 없는 모델도 많습니다. 그래서 조금씩 고쳐 가며 답에 다가갑니다.
- 숫자들을 아무 값으로 정합니다.
- 지금 값에서 틀린 정도가 어느 쪽으로 가장 빨리 커지는지 구합니다.
- 그 반대쪽으로 조금 옮깁니다.
- 틀린 정도가 더 줄지 않을 때까지 2 와 3 을 되풀이합니다.
대가는 둘입니다. 한 번에 옮기는 폭을 잘못 고르면 너무 느리거나 틀린 정도가 가장 작은 곳(바닥)을 지나쳐 튕겨 나갑니다. 전체에서 가장 작은 곳이 아니라 근처에서만 작은 곳에 멈출 수도 있습니다.
상세
이 절은 경사 하강법이 무엇을 받아 무엇을 내는지부터 봅니다. 그다음 숫자 하나짜리 작은 함수로 절차를 세 번 손으로 따라갑니다. 한 번에 옮기는 폭, 데이터를 나눠 쓰는 방법, 멈추는 지점, 드는 비용은 그 뒤에 차례로 봅니다.
짙은 안개 속 산비탈에 선 사람을 떠올려 봅니다. 멀리는 안 보이고 발밑이 어느 쪽으로 기울었는지만 느껴집니다. 이 사람은 가장 가파르게 내려가는 쪽으로 한 발 내딛습니다. 다시 발밑을 느끼고 또 한 발 내딛기를 되풀이하면 골짜기 바닥에 닿습니다.
경사 하강법이 하는 일이 이것입니다. 산의 높이가 줄이려는 값입니다. 서 있는 위치가 고치려는 숫자들입니다. 이름의 경사는 기울기를, 하강은 내려감을 뜻합니다.
넣는 것과 나오는 것
머신러닝에서 줄이려는 값은 모델이 얼마나 틀렸는지입니다. 모델은 입력을 받아 답을 내는 함수입니다. 집 넓이를 넣으면 집값을 내는 식이 한 예입니다.
모델 안에는 답을 정하는 숫자가 들어 있습니다. 이 숫자를 파라미터라고 합니다. 집값 모델을
집값 = a × 넓이 + b 라는 직선으로 두면 a 와 b 가 파라미터입니다.
집 넓이 하나와 그 집의 실제 값 하나처럼, 입력과 정답을 짝지은 한 쌍을 예제라고 부릅니다. 예제를 모은 것이 학습 데이터입니다. 뒤에서 데이터를 「백만 건」처럼 셀 때 한 건이 예제 하나입니다.
모델이 얼마나 틀렸는지는 손실 함수가 숫자 하나로 잽니다. 이 숫자를 손실이라고 부릅니다. 예측이 정답에서 멀수록 손실이 큽니다.
파라미터가 바뀌면 예측이 바뀝니다. 그래서 손실도 바뀝니다. 학습은 파라미터를 손실이 작아지는 값으로 맞추는 일입니다.
손실 함수로 흔히 쓰는 것이 평균 제곱 오차입니다. 예제마다 예측과 정답의 차이를 제곱한 뒤 모두 평균 낸 값입니다. 제곱을 하므로 크게 틀린 예제일수록 손실에 크게 보탭니다.
경사 하강법에 넣는 것은 셋입니다. 손실 함수, 파라미터의 시작값, 한 번에 얼마나 옮길지를 정하는 작은 수입니다. 나오는 것은 손실을 작게 만드는 파라미터 값입니다.
파라미터가 한두 개면 가능한 값을 촘촘히 다 넣어 보고 손실이 가장 작은 것을 고를 수도 있습니다. 파라미터가 늘면 시험할 조합이 곱으로 불어납니다. 파라미터마다 값을 열 개씩만 시험해도 파라미터가 스무 개면 10의 20제곱 가지입니다.
층을 여러 겹 쌓은 모델인 신경망은 파라미터가 수백만 개를 넘기도 합니다. 이런 모델에는 손실이 가장 작은 값을 한 번에 구하는 식이 없습니다. 경사 하강법은 그런 식 없이 조금씩 고쳐 가며 답에 다가갑니다.
기울기
이 소절은 「값이 가장 빨리 줄어드는 방향」을 계산으로 바꾸는 법을 봅니다. 파라미터가 하나일 때부터 봅니다.
파라미터가 하나면 손실은 그 숫자 하나에 따라 오르내리는 곡선입니다. 곡선의 한 점에서 미분은 입력을 아주 조금 늘릴 때 값이 얼마나 빨리 변하는지를 알려 줍니다. 곧 그 점에서 곡선이 기울어진 정도입니다.
미분의 부호가 갈 방향을 정합니다. 양수면 오른쪽으로 갈수록 값이 커지므로 왼쪽으로 가야 줄어듭니다. 음수면 반대로 오른쪽으로 갑니다. 어느 쪽이든 미분의 부호와 반대로 가면 됩니다.
파라미터가 여럿이면 하나씩 따로 봅니다. 다른 파라미터는 멈춰 두고 하나만 조금 움직일 때 손실이 변하는 빠르기를 구합니다. 이것을 편미분이라고 합니다.
편미분을 파라미터마다 구해 한 줄로 모은 것이 기울기입니다. 영어로 gradient 라서 그래디언트라고도 부릅니다. 기울기는 파라미터 수만큼 칸이 있는 숫자 목록입니다.
기울기가 가리키는 방향으로 파라미터를 옮기면 손실이 가장 빨리 커집니다. 그래서 경사 하강법은 기울기의 반대 방향으로 옮깁니다. 파라미터가 하나일 때 「미분의 부호와 반대로」 가던 것과 같은 규칙입니다.
한 번의 갱신
파라미터를 한 번 고치는 것을 갱신이라고 부릅니다. 갱신 한 번은 아래 식 하나입니다.
새 파라미터 = 지금 파라미터 − 학습률 × 기울기
빼기가 「반대 방향」을 맡습니다. 기울기가 양수인 칸의 파라미터는 줄어듭니다. 음수인 칸의 파라미터는 늘어납니다. 모든 파라미터가 한 번에 함께 옮겨집니다.
식의 학습률은 한 번에 얼마나 옮길지를 정하는 작은 양수입니다. 0.1 이나 0.001 같은 값을 씁니다. 기울기가 방향과 가파름을 주면, 학습률은 그중 얼마만큼 옮길지를 정합니다.
바닥 근처에서는 곡선이 평평해져 기울기가 작아집니다. 그래서 학습률이 같아도 바닥에 가까울수록 옮기는 폭이 저절로 줄어듭니다. 바닥에서는 기울기가 0 이라 더 움직이지 않습니다.
손으로 따라가는 세 번의 갱신
이 소절은 파라미터가 w 하나뿐인 손실 함수로 갱신을 세 번 따라갑니다. 손실 함수는 L(w) = (w − 3)² 입니다. w 가 3 일 때 손실이 0 으로 가장 작습니다.
이 함수의 미분은 2(w − 3) 입니다. 파라미터가 하나뿐이면 기울기는 이 미분 값 하나입니다. w 가 3 보다 작으면 미분이 음수라 w 를 키우는 쪽으로 옮깁니다. 시작값은 w = 0, 학습률은 0.1 로 둡니다.
첫 갱신에서 기울기는 2 × (0 − 3) = −6 입니다. 새 w 는 0 − 0.1 × (−6) = 0.6 입니다. 손실은 9 에서 5.76 으로 줄었습니다. 아래 표는 이 계산을 세 번 이어 간 것입니다.
| 회차 | w | 기울기 | 손실 |
|---|---|---|---|
| 0 | 0 | −6 | 9 |
| 1 | 0.6 | −4.8 | 5.76 |
| 2 | 1.08 | −3.84 | 3.69 |
| 3 | 1.464 | −3.072 | 2.36 |
기울기가 회차마다 작아집니다. w 가 3 에 다가갈수록 곡선이 평평해지기 때문입니다. 3 까지 남은 거리는 3, 2.4, 1.92, 1.536 으로 매번 0.8배가 됩니다.
같은 절차를 파이썬으로 옮기면 아래와 같습니다. grad 는 미분 2(w − 3) 을 계산하는 함수입니다.
def grad(w):
return 2 * (w - 3)
w = 0.0
for _ in range(3):
w = w - 0.1 * grad(w)
print(round(w, 3)) # 0.6 1.08 1.464
세 번 출력한 값이 표의 w 칸과 같습니다. 반복을 50 번으로 늘리면 w 는 3 에 거의 닿습니다.
w = 0.0
for _ in range(50):
w = w - 0.1 * grad(w)
print(round(w, 4)) # 3.0
반올림하기 전의 값은 2.99996 쯤입니다. 남은 거리가 매번 0.8배로 줄 뿐 0 이 되지는 않습니다. 언제 멈출지는 아래 「멈추는 지점」에서 봅니다.
학습률
학습률을 바꾸면 같은 함수에서 무엇이 달라지는지 봅니다. 앞 예의 손실 함수를 다시 씁니다.
갱신 식을 3 까지 남은 거리로 다시 적으면 아래와 같습니다.
새 w − 3 = (w − 3) − 학습률 × 2(w − 3)
= (1 − 2 × 학습률) × (w − 3)
남은 거리에 갱신마다 (1 − 2 × 학습률) 이 곱해집니다. 학습률이 0.1 이면 0.8 이 곱해집니다. 이 수의 크기가 1 보다 작아야 남은 거리가 줄어듭니다.
| 학습률 | 남은 거리에 곱해지는 수 | 3 에서 0.001 안으로 들기까지 |
|---|---|---|
| 0.01 | 0.98 | 약 400 번 |
| 0.1 | 0.8 | 36 번 |
| 1.1 | −1.2 | 들지 않는다 |
학습률이 작으면 느립니다. 0.01 은 0.1 보다 열 배 넘게 갱신해야 같은 거리까지 들어옵니다.
학습률이 너무 크면 바닥을 건너뛰어 반대편 비탈로 넘어갑니다. 1.1 이면 w 가 0, 6.6, −1.32, 8.184 로 3 의 양쪽을 오가며 멀어집니다. 손실도 9, 12.96, 18.66 으로 커집니다. 이렇게 값이 끝없이 커지는 것을 발산이라고 합니다.
학습률은 학습을 시작하기 전에 사람이 정합니다. 학습이 스스로 고치는 파라미터와 달리, 밖에서 정해 주는 이런 값을 하이퍼파라미터라고 합니다.
학습 중에 학습률을 바꾸기도 합니다. 처음에는 크게 두어 빨리 다가갑니다. 갈수록 줄여 바닥 근처에서 덜 흔들리게 합니다. 이렇게 학습률을 바꿔 가는 계획을 학습률 스케줄이라고 합니다.
데이터를 나눠 쓰는 세 방법
손실은 학습 데이터 전체를 두고 매깁니다. 기울기를 구할 때는 데이터를 얼마나 쓰느냐에 따라 세 방법으로 갈립니다.
데이터 전체로 기울기를 구하는 방법이 배치 경사 하강법입니다. 방향은 정확합니다. 대신 데이터가 백만 건이면 갱신 한 번에 백만 건을 다 계산해야 합니다.
예제 하나를 무작위로 골라 그것만으로 기울기를 구하는 방법이 확률적 경사 하강법입니다. 영어 줄임말로 SGD(Stochastic Gradient Descent)라고 씁니다. 갱신 한 번이 아주 쌉니다. 대신 예제 하나가 전체를 대표하지 못해 방향이 흔들립니다.
둘 사이를 절충한 것이 미니배치 경사 하강법입니다. 데이터를 수십에서 수백 건씩 작은 묶음으로 나눕니다. 묶음 하나로 기울기를 구해 갱신합니다. 이 묶음을 미니배치라고 합니다. 머신러닝 학습은 대부분 이 방법을 씁니다. 이것도 흔히 SGD 라고 부릅니다.
| 방법 | 갱신 한 번에 보는 데이터 | 갱신 한 번의 비용 | 방향 |
|---|---|---|---|
| 배치 경사 하강법 | 전체 | 크다 | 정확하다 |
| 확률적 경사 하강법 | 예제 하나 | 아주 작다 | 많이 흔들린다 |
| 미니배치 경사 하강법 | 묶음 하나 | 작다 | 조금 흔들린다 |
세 방법은 한 번에 보는 데이터의 양만 다릅니다. 보는 데이터가 많을수록 방향이 정확해집니다. 그만큼 갱신 한 번이 비싸집니다.
미니배치를 모두 한 번씩 써서 갱신하면 데이터 전체를 한 바퀴 돈 것입니다. 이 한 바퀴를 에포크라고 합니다. 학습은 보통 여러 에포크를 돕니다. 에포크마다 데이터를 섞어 묶음을 새로 나누는 경우가 많습니다.
기울기를 구하는 역전파
경사 하강법은 기울기를 받아 파라미터를 옮기는 일만 합니다. 기울기를 어떻게 구하는지는 따로 정해야 합니다. 앞 예처럼 미분 식을 손으로 세우는 방법은 파라미터가 몇 개일 때나 됩니다.
신경망에서는 역전파가 기울기를 구합니다. 역전파는 손실에서 출발해 모델의 계산을 거꾸로 거슬러 갑니다. 그러면서 모든 파라미터의 편미분을 한 번에 구합니다. 파라미터가 수백만 개여도 모델이 답을 한 번 내는 계산의 몇 배 안쪽으로 끝납니다.
둘은 한 낱말처럼 붙어 다니지만 맡는 일이 다릅니다. 역전파는 기울기를 계산합니다. 경사 하강법은 그 기울기로 파라미터를 고칩니다. 아래 그림은 미니배치 하나마다 두 일이 이어지는 순서입니다.
flowchart TD
A["미니배치 하나를 꺼낸다"] --> B["모델이 답을 내고 손실을 구한다"]
B --> C["역전파가 기울기를 구한다"]
C --> D["경사 하강법이 파라미터를 갱신한다"]
D --> E{"남은 미니배치가 있나"}
E -->|있다| A
E -->|없다| F["한 에포크가 끝난다"]
다음 에포크는 데이터를 다시 나눈 첫 미니배치부터 돕니다.
멈추는 지점
경사 하강법이 어디에 멈추는지, 그곳이 가장 낮은 곳인지를 봅니다. 손실 함수의 모양이 답을 가릅니다.
그릇처럼 바닥이 하나뿐인 함수를 볼록 함수라고 합니다. 앞 예의 (w − 3)² 가 볼록 함수입니다. 볼록 함수에서는 학습률이 알맞으면 경사 하강법이 가장 낮은 곳으로 다가갑니다.
전체에서 가장 낮은 곳을 전역 최솟값이라고 합니다. 볼록 함수의 하나뿐인 바닥이 곧 전역 최솟값입니다.
울퉁불퉁한 함수에는 움푹한 곳이 여럿 있습니다. 둘레보다는 낮지만 전역 최솟값만큼 낮지는 않은 곳을 지역 최솟값이라고 합니다. 그곳에서도 기울기가 0 이라 경사 하강법은 멈춥니다.
기울기가 0 인 곳이 바닥만은 아닙니다. 한 방향으로는 바닥이고 다른 방향으로는 꼭대기인 점이 있습니다. 말 안장처럼 생겨서 안장점이라고 합니다. 이런 점 근처에서는 기울기가 작아 갱신이 아주 느려집니다.
신경망의 손실 함수는 볼록하지 않습니다. 그래서 경사 하강법이 전역 최솟값에 닿는다는 보장이 없습니다. 시작값을 바꾸면 다른 곳에 멈출 수 있습니다.
학습을 멈추는 때는 대개 아래 셋 중 하나입니다.
| 멈추는 조건 | 까닭 |
|---|---|
| 정해 둔 에포크 수를 다 돌았다 | 갱신을 끝없이 할 수는 없다 |
| 손실이 거의 줄지 않는다 | 더 돌아도 얻는 것이 적다 |
| 학습에 안 쓴 데이터에서 손실이 오르기 시작한다 | 모델이 학습 데이터를 외우기 시작했다 |
셋째 줄처럼 모델이 학습 데이터를 외워 새 데이터에서 더 틀리는 현상을 과적합이라고 합니다. 학습 데이터의 손실만 보고 계속 내려가면 이 현상이 커집니다.
학습에 안 쓴 데이터의 손실이 오르기 시작할 때 학습을 멈추는 방법을 조기 종료라고 부릅니다. 과적합이 더 커지기 전에 끊는 것입니다.
걸리는 시간과 메모리
경사 하강법에 드는 비용을 갱신 한 번과 전체로 나눠 봅니다. 데이터 건수를 n, 파라미터 수를 d, 미니배치 하나의 크기를 b 로 적습니다.
비용이 입력 크기에 따라 커지는 모양은 빅오 표기법으로 적습니다. O(n × d) 는 n 이나 d 가 두 배가 되면 비용도 두 배쯤 된다는 뜻입니다.
직선 모델처럼 예제 하나의 기울기를 구하는 데 파라미터 수만큼 계산이 드는 경우로 봅니다. 그러면 갱신 한 번의 비용은 기울기에 쓴 예제 수에 d 를 곱한 만큼입니다.
| 방법 | 갱신 한 번의 시간 | 한 에포크의 갱신 횟수 |
|---|---|---|
| 배치 경사 하강법 | O(n × d) | 1 |
| 확률적 경사 하강법 | O(d) | n |
| 미니배치 경사 하강법 | O(b × d) | n ÷ b |
세 방법 모두 한 에포크의 시간은 O(n × d) 로 같습니다. 달라지는 것은 한 에포크 동안 파라미터를 몇 번 고치느냐입니다. 미니배치 방식은 데이터를 한 바퀴 도는 동안 n ÷ b 번 고칩니다.
전체 시간은 갱신 한 번의 시간에 갱신 횟수를 곱한 것입니다. 갱신 횟수는 손실 함수의 모양과 학습률에 달려 있어 미리 정해지지 않습니다. 앞 예에서도 학습률만 0.1 에서 0.01 로 바꾸자 36 번이 약 400 번이 됐습니다.
메모리는 파라미터 d 개와 같은 크기의 기울기 하나면 됩니다. 곧 O(d) 입니다. 여기에 미니배치 하나를 담을 공간이 더해집니다.
경사 하강법으로 학습하는 모델
선형 회귀는 입력에 숫자를 곱해 더한 직선으로 답을 냅니다. 앞의 집값 모델이 선형 회귀입니다. 선형 회귀는 손실이 가장 작은 값을 한 번에 구하는 식이 있습니다. 이 식을 정규 방정식이라고 합니다. 데이터가 아주 크면 이 식 대신 경사 하강법으로 풉니다.
로지스틱 회귀는 스팸인지 아닌지처럼 둘 중 하나를 고르는 모델입니다. 손실이 가장 작은 값을 한 번에 구하는 식이 없어서 경사 하강법 같은 반복 방법으로 풉니다.
신경망은 거의 전부 경사 하강법과 그 변형으로 학습합니다. 지난 갱신의 방향을 기억해 두었다가 이번 갱신에 보태는 변형을 모멘텀이라고 합니다.
파라미터마다 학습률을 따로 조절하는 변형도 있습니다. AdaGrad(Adaptive Gradient)·RMSProp(Root Mean Square Propagation)·Adam(Adaptive Moment Estimation)이 그 예입니다.
관련 항목
경사 하강법이 속하는 상위 분류
알고리즘 · 최적화 · 수치 최적화 · 반복법 · 머신러닝
경사 하강법이 줄이는 값과 고치는 값
손실 함수 · 목적 함수 · 평균 제곱 오차 · 교차 엔트로피 · 파라미터 · 모델
경사 하강법이 기대는 미적분 개념
미분 · 편미분 · 그래디언트 · 벡터 · 볼록 함수
데이터를 나눠 쓰는 경사 하강법의 하위 종류
배치 경사 하강법 · 확률적 경사 하강법 · 미니배치 · 에포크
갱신의 폭과 방향을 다듬는 변형 알고리즘
모멘텀 · 네스테로프 가속 경사 · AdaGrad · RMSProp · Adam
학습 전에 사람이 정하는 하이퍼파라미터
하이퍼파라미터 · 학습률 · 배치 크기 · 학습률 스케줄
기울기를 구해 경사 하강법에 건네는 계산
역전파 · 자동 미분 · 연쇄 법칙 · 계산 그래프
경사 하강법을 멈추거나 헤매게 하는 지형
지역 최솟값 · 전역 최솟값 · 안장점 · 발산 · 기울기 소실 · 기울기 폭발
학습을 언제 멈출지 가르는 개념
과적합 · 조기 종료 · 검증 데이터 · 규제 (머신러닝)
경사 하강법으로 학습하는 모델
선형 회귀 · 로지스틱 회귀 · 신경망 · 딥러닝
경사 하강법 대신 최솟값을 찾는 최적화 방법
정규 방정식 · 뉴턴 방법 · 좌표 하강법 · 유전 알고리즘 · 모의 담금질
다른 이름: gradient descent · 경사하강법 · 그래디언트 디센트 · 기울기 하강법