확률론과 이의 필요성 - in Deep Learning
확률론, 왜 필요한가?
- 딥러닝은 기본적으로 확률론 기반의 기계학습 이론에 바탕을 두고있다.
- 이유는 회귀, 분류 각각 다음과 같다.
- 회귀분석의 경우 L2 Norm은 예측 오차의 분산을 최소화하는 방향으로 학습한다.
- L2가 두 점의 거리를 계산하는것을 바탕으로 두면 어떤점을 시사하는지 알수있다.
- 분류문제의 경우 교차엔트로피는 모델 예측의 불확실성을 최소화 하는 방향으로 학습한다.
- 회귀분석의 경우 L2 Norm은 예측 오차의 분산을 최소화하는 방향으로 학습한다.
- 두 학습 모두 분산 혹은 불확실성을 최소화 하는것에 목표가 있으며, 이를 측정하는 방법을 알아야한다.
데이터에 대한 몽타주
- 데이터 공간에 다음과 같이 데이터가 분포해있다 생각해보자.
%20%20%20%20
- 데이터 공간을 $x \times y$ 라 표기하고, 데이터 공간에서 데이터를 추출하는 분포를 $D$라 하자.
- 확률변수로는 $(X, y) \sim D$ 라 하자.
확률변수는 확률분포 D에 따라 이산형, 연속형 확률변수로 구분한다.
이산확률변수
- 확률변수가 가질 수 있는 경우의 수를 모두 계산하여 다해 모델링한다. 아래의 식과 같다.
$$ P(X\in A)=\sum_{x\in A}P(X=x) $$
## 연속확률변수
- 데이터 공간에 정의된 확률변수의 밀도 위에 적분을 하여 모델링한다. 아래의 식과 같다.
$$ P(X\in A)=\int _AP(x)dx $$
- 우리는 이를 위의 데이터의 형태(모양)을 보고 결정한다.
- 아래의 주변확률분포도는 전체 공간에 대해 그래프로 그린것이다.
%20%20%20%20
- 이렇게 된 경우, y의 공간이 모두 통합되어 보이기 때문에 y의 정보가 없다.
- 아래의 조건부확률분포는 $y=1$ 인 데이터에 대해 그래프로 그린것이다.
%20%20%20%20
- 이렇게 된 경우, 명확하게 x와 y에 대한 관계가 보이게 된다.
$P(y|X)$
이는조건부확률이 입력변수 X에 대해 정답 y일 확률을 의미한다.
- 단, 연속확률분포의 경우 확률이 아닌 밀도로 해석한다.
이는 각각 사용이 다음과 같다.
- 분류 문제에서 $softmax(W\phi+b)$이 데이터 x로부터 추출된 특징패턴 $\phi(x)$와 가중치행렬 W를 통해 조건부 확률을 계산한다.
- 회귀문제의 경우 조건부기대값 $E[y|x]$를 추정한다.
- 이는 L2 Norm과 같다.
여기서 기대값이란?
- 쉽게 말하면 평균으로 데이터를 대표하는데 대표적인 통계값이다.
- 연속확률분포의 경우 적분, 이산확률분포의 경우 급수를 사용한다.
- 이를 이용하여 분산, 첨도, 공분산 등 여러 통계값을 계산할수 있다.
무작위 - 몬테카를로 샘플링
- 위의 그림을 보며 이해하는것이 도움이 되어 가져왔다. 직관적이다.
- 기계학습에서 많은 문제들은 확률분포를 명시적으로 모르는 경우가 많다.
- 이로인해 데이터를 이용해 기대값을 계산할 때 몬테카를로 샘플링을 사용한다.
- 몬테카를로 샘플링의 경우 독립추출만 보장된다면 대수의 법칙(Law of Large Number)에 의해 수렴성을 보장한다.
- 몬테카를로 샘플링의 식은 다음과 같다.
$$ E_{X \sim P(x)}[f(x)] \approx\frac1n \sum^N_{i=1}f(x^i), $$
예시
- 다음의 함수가 있다 가정하자.
$$ f(x)=e^{-x^2} $$
- 해당 함수는 해석적으로 적분이 불가능한 함수다. 이곳에 몬테카를로를 적용하여 [-1, 1] 구간에 대해 적분해보자.
- 여기서 위의 식을 적용할 때 n은 구간의 길이 즉 2로 정한다.
- 식은 다음과 같다.
$$ \frac12\int^1_{-1}e^{-x^2}\approx \frac1N\sum^N_{i=1}f(x^i) $$
- 위의 식에 대해 2배를 하게되면 전체 크기의 적분값이 나온다.
코드화
- 코드로 보는것이 조금 더 편하다.
import numpy as np
def mc_int(fun, low, high, sample_size=100, repeat=10):
# 먼저, 구간의 길이를 구한다.
int_len = np.abs(high - low)
stat = []
# 정해진 횟수만큼 반복시행한다.
for _ in range(repeat):
# 정해진 구간만큼, 정해진 갯수를 랜덤하게 뽑는다.
x = np.random.uniform(low=low, high=high, size=sample_size)
# 뽑힌 random 값을 함수에 넣어 결과를 가져온다.
fun_x = fun(x)
# 결과에 대해 모두 구간만큼 곱한다음,
int_val = int_len * np.mean(fun_x)
# 배열에 저장한다.
stat.append(int_val)
# 쌓인 랜덤한 x에 대한 결과들을 각각 결과와 오차로 계산해 반환한다.
return np.mean(stat), np.std(stat)
def f_x(x):
return np.exp(-x**2)
print (mc_int (f_x, low -1, high 1, sample_size 10000, repeat 100))