지금까지 선형대수와 확률과 통계를 공부하며, 기초적인 수학을 공부했습니다. 이제 매개변수 공간을 탐색하고, 미분을 하며 경사하강을 해서 기울기가 0이 될 때까지 학습을 시키는 과정을 공부하겠습니다.
먼저 학습하는데 사용되는 데이터의 차원을 고려해야합니다. 만약 높은 차원의 즉 특징이 많은데 비해 훈련 집합의 크기가 작은 경우 참인 확률 분포를 구하는 일은 불가능에 가까워 집니다. 그렇기 때문에 머신 러닝은 적절한 모델을 선택하고 목적 함수를 정의하고 모델의 매개변수 공간을 탐색해서 목적함수가 최저가 되는 최적점을 찾는 전략을 사용합니다.
즉 특징 공간에서 해야하는 일을 모델의 매개변수 공간에서 하는 일로 대치하는 것입니다. 아래는 이러한 최적화를 이용해서 머신러닝의 문제풀이를 하는 과정을 보입니다.
반대로 특징 공간에 비해 매개변수 공간은 수배에서 크면 수만배로 넓습니다. 위의 식처럼 선형 회귀 상에서는 특징 공간이 1차원이고 매개변수 공간은 2차원입니다.
그리고 MNIST 데이터 셋에서 인식하는 딥러닝의 모델은 784 차원의 특징 공간이고, 매개변수 공간은 수십만에서 수백만 차원의 매개변수 공간을 가집니다. 굉장히 값의 차이가 크죠?
다음 그침은 최적해를 탐색해가는 과정입니다. 이 때 왼쪽의 x햇은 전역 최적해(제일 낮습니다.)이며, x2와 x4는 지역 최적해(전역 제외 각 봉우리마다 최솟값)입니다. 보통 학습에서는 x2와 같은 전역 최적해에 가까운 지역 최적해를 찾고 만족하는 경우가 많습니다.
즉 기계 학습에서 해야할 일은 J(theta)를 최소로 하는 최적해 theta(hat)을 찾는 것으로, 식으로 정리하면 다음과 같습니
다.이러한 최적화 문제를 해결하는 알고리즘은 다양합니다. 먼저 낱낱탐색 알고리즘입니다. 일단 파이썬 기반으로 수도코드를 작성하겠습니다. 입력으로는 훈련집합 X와 Y를 주고, 최적해 hat_theta를 반환합니다.
# 가능한 해를 모두 생성해서 집합 S에 저장
min = sys.maxint
for cur_theta in S :
if(J(cur_theta) < min) :
min, best_theta = J(cur_theta), cur_theta
hat_theta = best_theta
딱 봐도 어려운 알고리즘은 아닙니다. 하지만 이 방식의 치명적인 단점은 차원이 조금만 높아져도 적용이 불가능합니다. 예로 들어서 4차원의 붓꽃 데이터의 경우 각 차원을 1000으로 나눈다면 1000^4 개의 점을 평가해야 합니다.
다음은 무작위 탐색 알고리즘입니다. 이 방식은 아무 전략이 없는 순진한 즉 랜덤 방식의 알고리즘입니다. 이 방식도 일단 위의 입출력과 동일합니다.
min = sys.maxint
do :
cur_theta = random.random()
if J(cur_theta) < min :
min, best_theta = J(cur_theta), cur_theta
while 멈춤 조건
hat_theta = best_theta
또 다른 알고리즘은 기계 학습이 사용하는 전형적인 알고리즘입니다. 여기서는 목적함수가 작아지는 방향으로 주로 미분을 해서 찾아냅니다.
theta = random.random()
do :
J(theta) 가 작아지는 방향으로 delta_theta를 구한다.
theta = theta + delta_theta
while 멈춤 조건
hat_theta = theta
미분은 고등학교때도 죽어라 들었겠을 것이다. 1차 도함수 f'(x)를 통해서 함수의 기울기 즉 값이 커지는 방향을 지시할 수 있다. 즉 -f'(x)를 통하면 목적함수의 최저점을 찾을 수 있다는 뜻이다. 즉 바로 위의 의사 코드는 delta_theta로 -f'(x)를 사용하는데, 이는 경사 하강 알고리즘의 핵심 원리이다.
이 이 때 만약 변수가 여러개인 경우 편미분을 이용해서 벡터를 구한다. 이 때 미분값이 이루는 벡터를 그레디언트라 부르며, 매개변수 집합 theta가 많은 변수가 있는 경우인 머신 러닝의 경우 편미분을 많이 사용한다.
합성함수의 경우는 연쇄 법칙을 이용해서 미분을 해낸다.
예로들면 다음과 같은 식을 연쇄법칙을 이용해서 미분한다.
이러한 연쇄법칙은 다음과 같은 다층 퍼셉트론이 있다고 가정하자.
만약 내가
같은 수을 구한다고 가정하면, 이럴 때 연쇄 법칙을 이용해서 구하게 된다.
다변수 행렬의 도함수를 구한다고 할 때는 야코비언 행렬이란 것을 사용하게 된다. 예로 들면 다음과 같은 식으로 도함수를 구하게 된다.
이 외에도 이계도함수를 구한다고 하면 헤시안 행렬을 사용하게 된다. 예시는 다음과 같다.
이제 경사 하강법에 대해 이야기를 하자. 조건은 위와 같다고 가정하자. 이런 경우 우리는 위에서 말했던 의사코드의 입력 값에 학습률 p를 추가해서 전달해야한다. 파이썬을 기반으로 한 의사코드는 다음과 같다.
theta = random.random()
gradient_list = []
total_gradient = 0
do :
for x in X :
gradient_list.append(gradient(x))
total_gradient = sum(gradient_list) / len(gradient_list)
theta = theta - (p * total_gradient)
while 멈춤 조건
hat_theta = theta
같은 입력값으로 한 샘플의 그레디언트를 계산한 뒤 즉시 갱신하는 스토캐스틱 경사 하강(SGD) 알고리즘이란 것도 있다.
theta = random.random()
do :
# X 섞기
for i in range(1, n) :
gradient(X[i])
theta = theta - (p * X[i])
while 멈춤 조건
hat_theta = theta
이 때 중요한 것은 4~7번째 줄로 이 반복을 한 세대라 부른다. 다른 방법으로는 X에서 임의의 샘플을 뽑아서 계산하는 방법도 존재한다.
'Deep Learning' 카테고리의 다른 글
[딥러닝] 신경망 (0) | 2021.10.17 |
---|---|
[딥러닝, 수학] 확률과 통계 (0) | 2021.10.17 |
[딥러닝, 수학]선형대수와 퍼셉트론 (0) | 2021.10.17 |
[딥러닝] 간단한 기계학습 (0) | 2021.10.12 |
[딥러닝] 인공지능과 데이터 (0) | 2021.10.12 |