이번에 볼 경사 하강법 알고리즘은 미니배치 경사 하강법(Mini-batch Gradient Descent)입니다. 배치와 확률적 경사 하강법을 알고 있다면 이해하기 쉽습니다. 각 스텝에서, 전체 훈련 세트(배치 경사 하강법과 같은)나 하나의 샘플(확률적 경사 하강법 같은)을 기반으로 그래디언트를 계산하는 것이 아니라, 미니배치라 부르는 임의의 작은 샘플에 대해 그래디언트를 계산합니다.
확률적 경사 하강법에 비해 미니배치 경사 하강법의 주요 장점은 행렬 연산에 최적화된 하드웨어, 특히 GPU를 사용해서 얻는 성능 향상입니다. 특히, 미니배치를 어느정도 크게 하면, 이 알고리즘은 파라미터 공간에서 SGD보다 덜 불규칙하게 움직입니다. 결국 미니배치 경사 하강법이 SGD보다 최솟값에 더 가까이 도달하게 될 것입니다. 하지만, 한편으로는 지역 최솟값에서 빠져나오기는 더 힘들지도 모릅니다. (선형 회귀와 같지 않고 지역 최솟값이 문제가 되는 경우)
이제, 미니배치 경사 하강법 코드를 실행해보고, 세 가지 알고리즘이 어떻게 움직이는지 확인해봅니다.
#미니배치 경사하강법
theta_path_mgd=[]
n_iterations = 50
minibatch_size = 20
np.random.seed(42)
theta = np.random.randn(2,1) #무작위 초기화, 2행 1열
t0 , t1 = 200, 1000
def learning_schedule(t) :
return t0 / (t + t1)
t = 0
#따라서 m은 길이이므로 길이만큼의 인덱스를 랜덤하게 shuffle하는 셈.
#1-50까지 epoch
for epoch in range(n_iterations):
#numpy.ramdom.permutation() 은 랜덤하게 순서를 만듭니다.
shuffled_indices = np.random.permutation(m)
X_b_shuffled = X_b[shuffled_indices]
y_shuffled = y[shuffled_indices]
for i in range(0, m , minibatch_size):
#t가 늘어나면서 학습률이 점점 작아지게 됨
t += 1
xi = X_b_shuffled[i : i+minibatch_size]
yi = y_shuffled[i : i+minibatch_size]
gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi )
eta = learning_schedule(t)
theta = theta -eta *gradients
theta_path_mgd.append(theta)
theta
theta_path_bgd = np.array(theta_path_bgd) #batch gredient descent
theta_path_sgd = np.array(theta_path_sgd) #stochastic gredient descent
theta_path_mgd = np.array(theta_path_mgd) #mini-batch gredient descent
plt.figure(figsize=(7,4))
plt.plot(theta_path_sgd[: , 0], theta_path_sgd[:, 1], 'r-s', linewidth=1, label='SGD')
plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1], 'g-+', linewidth=2, label='mini-batch')
plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1], 'b-o', linewidth=3, label='batch')
plt.legend(loc='upper left', fontsize=16)
plt.xlabel(r'$theta_0$', fontsize=20)
plt.ylabel(r'$theta_1$ ', fontsize=20, rotation=0)
plt.axis([2.5, 4.5, 2.3, 3.9])
plt.show()
모두 최솟값 근처에 도달했지만 배치 경사 하강법의 경로가 실제 최솟값에서 멈춘 반면, 확률적 경사하강법과 미니배치 경사 하강법은 맴돌고 있음을 알 수 있습니다.
하지만 배치 경사 하강법은 매 스텝에서 많은 시간이 소요되고, 확률적 경사 하강법과 미니배치 경사 하강법도 적절한 학습 스케줄을 사용하면 최솟값에 도달한다는 것을 잊지 말아야 합니다.
알고리즘 |
m이 클 때 |
외부메모리 학습지원 |
n이 클 때 |
하이퍼파라미터 수 |
스케일 조정 필요 |
사이킷런 |
정규방정식 |
빠름 |
X |
느림 |
0 |
X |
LinearRegression |
배치 경사 하강법 |
느림 |
X |
빠름 |
2 |
O |
N/A |
확률적 경사 하강법 |
빠름 |
O |
빠름 |
2 이상 |
O |
SGDRegressor |
미니배치 경사 하강법 |
빠름 |
O |
빠름 |
2 이상 |
O |
N/A |
*정규방정식은 선형 회귀만을 위한 알고리즘이지만, 경사 하강법은 앞으로 보게 될 여러 가지 다른 모델도 훈련시킬 수 있다.
*위 모델들은 훈련 결과에 거의 차이가 없습니다. 모두 매우 비슷한 모델을 만들고 정확히 같은 방식으로 예측합니다.
블로그 이 글의 상당 부분은 [핸즈온 머신러닝, 한빛미디어/오렐리앙 제롱/박해선] 서적을 참고하였습니다. 나머지는 부수적인 함수나 메서드에 대해 부족한 설명을 적어두었습니다. 학습용으로 포스팅 하는 것이기 때문에 복제보다는 머신러닝에 관심이 있다면 구매해보시길 추천합니다. 도움이 되셨다면 로그인 없이 가능한 아래 하트♥공감 버튼을 꾹 눌러주세요! 출처
'## 오래된 게시글 (미관리) ## > Python (Linux)' 카테고리의 다른 글
31. Python - 규제(릿지 회귀, 라쏘 회귀, 엘라스틱넷, 조기종료) (0) | 2019.01.27 |
---|---|
30. Python - 다항 회귀 (0) | 2019.01.25 |
28. Python - 확률적 경사 하강법 (0) | 2019.01.25 |
27. Python - 배치 경사 하강법 (0) | 2019.01.24 |
26. Python - Matplotlib에 한글 사용법 (0) | 2019.01.23 |