신경망의 최적화 알고리즘은 대부분 경사 하강법에서 확장된 형태로 경사하강법은 매우 단순한 알고리즘으로 쉽게 이해하고 적용할 수 있다.
신경망의 학습 목표
신경망의 손실 함수는 차원이 매우 높고 복잡하기에 최적화가 어렵다. 손실 함수에는 지역 최소(Local minimum), 전역 최소(Global minimum)이 있다.
Local minimum
함수에서 부분적으로 낮은 곳
Global minimum
함수 전체에서 가장 낮은 곳
차원이 클수록 Global minimum을 찾기 힘들고 비용이 많이 든다. 또한 문제가 크고 복잡할 경우 전역 최소를 찾는 것이 어렵고 때로는 불가능이다.
따라서 대부분의 최적화 알고리즘의 목표는 Local minimum을 찾는 것이다.
단, 가장 좋은 Local minimum을 찾기 위해서는 해를 여러 번 찾아 그 중에 가장 좋은 해를 사용하거나 동시에 여러 해를 구해서 함께 고려한다.
최적의 알고리즘
최적화 문제는 관측 변수가 많고 닫힌 형태로 정의되지 않기 때문에 함수를 미분해서 최대, 최소를 구할 수 없다.
그렇기에 임의의 초기화 상태에서 반복적으로 조금씩 해에 접근해야한다.
최적화 알고리즘은 손실 함수 곡면을 매번 근사하는데 이때 사용하는 미분 차수에 따라 1차 미분, 2차 미분, 3차 미분 방식으로 나뉜다.
1차 미분
- 경사 하강법
- 경사 하강법의 변형(SGD, SGD 모멘템, AdaGrad, RMSProP, Adam
1.5차 미분
- 준 뉴턴 방법(Quasi-newton method)
- 켤레 경사 하강법(Conjugate gradient descent)
- 레벤버그-마쿼트 방법(Levenberg-marquardt method)
2차 미분
- 뉴턴 방법(Newton method)
- 내부점법(Interior point method)
2차 미분 방식은 곡률 Curvature을 사용하므로 최적해를 빠르게 찾을 수 있지만 손실 함수 곡면이 볼록 Convex해야 사용할 수 있으며 계산 비용과 메모리 사용량이 많이 든다.
1.5차 미분 방식은 1차 미분을 이용하여 2차 미분을 근사하는 방식으로 최적해를 빠르게 찾을 수 있다. 하지만 신경망 학습과 별도로 2차 미분을 근사하는 알고리즘을 실행해야 하고 근사된 2차 미분값을 저장해야 하므로 메모리 사용량이 많이 든다.
1차 미분 방식은 속도를 상대적으로 느리지만 손실 함수 곡면이 볼록하지 않아도 사용할 수 있어 안정적으로 사용하기에 좋다. 그렇기 때문에 신경망에서는 주로 1차 미분 방식을 많이 사용한다.
경사하강법
손실 함수의 최소 지점을 찾기 위해 경사가 가장 가파른 곳을 찾아서 한 걸음씩 내려가는 방법이다.
$$ \theta ^{+}=\theta - \alpha \frac{\partial J}{\partial \theta} $$
경사 하강법 적용
가중치, 가중 합산 출력 변수, 활성 함수 출력 변수
Parameter 업데이트 식
\( w^{1}_{nm} \) 값을 업데이트 하기 위해서는 손실 함수에 대한 가중치의 미분 \( \frac{\partial J}{\partial w^{1}_{nm}} \)를 구해서 아래와 같이 업데이트 한다.
$$ {w^{1}_{nm}}^{+}=w^{1}_{nm}-\alpha \frac{\partial J}{\partial w^{1}_{nm}} $$
손실 함수에 가중치 변수가 포함되어 있지 않기 때문에 연쇄 법칙(Chain Rule)을 통해서 업데이트 해야한다.
$$ \frac{\partial J}{\partial w^{1}_{nm}}=\frac{\partial J}{\partial y}\cdot\frac{\partial y}{\partial z^{2}}\cdot\frac{\partial z^{2}}{\partial a^{1}_{m}}\cdot\frac{\partial a^{1}_{m}}{\partial z^{1}_{m}}\cdot\frac{\partial z^{1}_{m}}{\partial w^{1}_{nm}} $$
각 위의 식을 아래의 식으로 미분한 값이다.
각 함수의 미분을 곱하여 \( \frac{\partial J}{\partial w^{1}_{nm}} \)을 정의할 수 있다.
실전 코드
Dataset
import pandas as pd
from torch.utils.data import DataLoader
data_path = './data/Student Study Hour V2.csv'
data = pd.read_csv(data_path)
batch = 32
X = list(data['Hours'])
y = list(data['Scores'])
dataset = list(zip(X,y))
dataset
import numpy as np
import torch
epochs = 10
lr = 0.01
loss_list=[]
w = torch.rand(1)
b = torch.rand(1)
print(w, b)
w.requires_grad = True
b.requires_grad = True
for epoch in range(epochs):
for i in dataset:
x, y = i
y_hat = x*w+b
loss = ((y_hat-y)**2).mean()
w.retain_grad()
b.retain_grad()
loss.backward()
w = w - lr * w.grad
b = b - lr * b.grad
loss_list.append(loss.item())
print('loss {:.5f}, w {:.5f}, b {:.5f} '.format(loss.item(), w.item(), b.item()))
import matplotlib.pyplot as plt
plt.figure(figsize = (15, 4))
plt.plot(loss_list)
'Machine Learning > 기법' 카테고리의 다른 글
[ML] Optimizer 옵티마이저, 최적화 (0) | 2023.01.13 |
---|---|
[ML] 손실 함수 (0) | 2023.01.10 |
[ML] 회귀 모델 (0) | 2023.01.04 |
[ML] 다중 분류 모델 (0) | 2023.01.04 |
[ML] 활성화 함수 Activation Function (0) | 2022.09.05 |