정규분포의 확률밀도함수(Probability Density Function, PDF) 증명

 

0. 서론

확률밀도함수(PDF), 그 중에서도 정규분포함수가 왜 너무나도 당연하게 유도되는지를 증명해보려고 합니다.

신기하게도 하나하나 따라가다보면, 우리가 아는 그 유명한 종 모양 그래프가 나온답니다.

 

1. 정규분포의 함수 모양은 어떻게 생겼나?

아시는 분들은 대충 종 모양이라고 알고 계시겠고, 더욱 자세히 아시는 분들은 적어도 이 함수가 e의 지수함수꼴이라는 것은 알고계실겁니다.

그러나 그게 왜 그렇게 나오는지는 모르시는 경우가 많을 것이라 생각됩니다. 그럼 정말 '무지'에서 시작해서 이 그래프를 찾아가보도록 하겠습니다.

 

2. 조건들을 확인하자

우리가 아는 정규분포의 pdf의 조건들은 다음과 같습니다.

  1. $ \int_{-\infty}^\infty f(x) dx = 1 $ : 함수의 전체 넓이는 1(=전체 확률은 1)
  2. $ \int_{-\infty}^\infty x \cdot f(x) dx = \mu $ : 확률변수 x의 기댓값은 평균($ \mu $)
  3. $ \int_{-\infty}^\infty (x-\mu)^2 \cdot f(x) dx = \sigma^2 $ : 확률변수 x의 분산은 표준편차($ \sigma $)의 제곱
  4. $ \mu $를 기준으로 좌우 대칭
  5. 최대한 자연적인 분포(분포가 치우침이 없고 편향되지 않음)

이 조건들을 가지고 바로 함수의 모양을 찾아볼까요?

 

3. 최대한 자연적이다?

최대한 자연스러운 분포란 무엇일까요?

예를 들어, 동전을 던진다고 가정해봅시다.

가장 자연스러운 상황은 앞면이 나올 확률이 0.5, 뒷면도 0.5인 경우입니다.
왜냐하면 결과를 전혀 예측할 수 없기 때문이죠. (어느 쪽이 나올지 도무지 알 수 없음)

반면, 만약 앞면이 나올 확률이 0.99, 뒷면은 0.01이라면 어떨까요?
이건 거의 항상 앞면이 나오는 인위적인 상황으로, 결과를 예측하기 매우 쉽습니다.
더 이상 ‘무작위’라기보다는 ‘조작된’ 느낌이 들죠.

이처럼 우리가 말하는 ‘자연스러운 분포’
결과를 예측하기 가장 어려운 상태,
불확실성이 최대인 상태라고 할 수 있습니다.

그런데 생각해봅시다.

앞면이 나왔을 때 더 놀라운 경우는 어느 쪽일까요?

  • 확률이 0.5인 공정한 동전?
  • 아니면 0.99로 앞면이 나오는 조작된 동전?

당연히 전자입니다.

공정한 동전에서는 앞면과 뒷면이 동일한 가능성을 가지기 때문에,
결과가 나왔을 때 우리는 순간적으로 “아! 앞면이 나왔네!” 하고 반응하게 되죠.
반대로 조작된 동전에서는 앞면이 나와도 별로 새로울 것이 없습니다.
애초에 그럴 거라 거의 확신하고 있었으니까요.

이런 “놀라움의 크기”를 다른 말로 표현하면,
우리가 그 순간 “새롭게 알게 된 정보의 양”,
정보량이라고 할 수 있습니다.

정리해보면 이렇게 연결됩니다:

불확실성이 크다 = 예측이 어렵다 = 놀라움이 크다 = 정보량이 크다

그리고 정보이론에서는 이것을 '엔트로피(entropy)'라고 부릅니다. 정보량이 크면 엔트로피가 큽니다.

[엔트로피의 원래 의미에서도 무질서도가 증가하는게 엔트로피가 크다고 하잖아요? 무질서할수록 우리가 알아야할 정보량은 커집니다.]

 

자, 그럼 정리되었습니다. 정규분포의 pdf는 엔트로피가 최대가 되어야 합니다.

 

 

4. 엔트로피는 어떻게 정의되는가

엔트로피는 샤논 엔트로피 공식(Shannon entropy formula)으로 구할 수 있습니다.

정보이론에서 샤논이라는 분이 엔트로피(불확실성)을 정량적으로 측정하기 위해 제안한 공식이죠.

수식을 보면

$ H(X) = - \sum p_i \log_b p_i $

이와 같습니다.

여기서 b가 2이면 bit로 나오고, e이면 nat, 10이면 hartley라고 하는데, 10은 거의 안쓰니까 크게 신경 안쓰셔도 됩니다.

p는 확률이죠.

이 수식은 정보이론에서 파생되었기 때문에 bit로 계산되는 이산적 공식이지만, 이 개념을 이용해서 연속적으로도 활용할 수 있습니다.

또한 보통 연속적으로 사용할때는 b가 e인 nat(natural unit of information) 단위로 쓰이지만, 이 단위가 크게 중요한 부분은 아닙니다.

중요한건 이 공식으로 연속함수의 불확실성을 나타낼 것이라는 점입니다.

$ H[f] = - \int f(x) \ln f(x) dx $

이제 이 공식에서 f(x)가 가장 불확실함을 나타내는 함수를 찾으면 됩니다. 그렇다면 H[f] 즉, 함수 f의 엔트로피가 최대가 되면 되겠죠?

 

 

5. 값이 최대가 아니라, 함수가 최대라구요?

여기서 값이 최대인 것을 찾는 방법이 미분법이라고 한다면, 함수가 최대인 것을 찾는 방법은 변분법이라고 불립니다.

그러면 바로 H[f]를 바로 변분법을 쓰면 될까요?

아니겠죠..? 위에서 조건들이 엄청 많았는데 그것들을 무시하고 찾으면 안되는 거잖아요?

그렇다면 위의 조건들을 어떻게 반영할 것이냐.. 하면 여기서 라그랑주 승수법이라는것이 나옵니다.

어떤 함수에 대해서 각 조건들에 라그랑주 승수를 곱해서 원 함수에서 더하거나 빼서 그 함수를 조건짓는 겁니다.

그렇게 해서 중간에 나오는 식을 '라그랑지안'이라고 부릅니다.

그렇다면 H[f]에서 각 조건들을 빼주면 되겠죠?

$ \mathcal{L} = - \int f(x) \ln f(x) dx - \lambda_0 ( \int f(x) dx -1 ) - \lambda_1 ( \int x \cdot f(x) dx - \mu ) - \lambda_2 ( \int (x-\mu)^2 \cdot f(x) dx - \sigma^2 ) $

이렇게 정리될겁니다.

그리고 여기에서 변분법을 적용하여(함수로 미분하는 겁니다) 이 값이 0인 점을 찾으면 미분처럼 극값을 주는 함수를 찾을 수 있습니다.

$ \frac{\delta \mathcal{L}}{\delta f(x)} = - (1 + \ln f(x)) - \lambda_0 - \lambda_1 \cdot x - \lambda_2 \cdot (x-\mu)^2 = 0 $

으로 나올테고, 이를 정리하면

$ \ln f(x) = -1 - \lambda_0 - \lambda_1 \cdot x - \lambda_2 \cdot (x-\mu)^2 $

이 되고, 이를 다시 f(x)로 표현하면

$ f(x) = e^{-1 - \lambda_0 - \lambda_1 \cdot x - \lambda_2 \cdot (x-\mu)^2} $

$ f(x) = Ae^{- \lambda_1 \cdot x - \lambda_2 \cdot (x-\mu)^2} $

이렇게 정리할 수 있습니다.

그리고 여기서 '함수는 평균을 기준으로 좌우 대칭이다'라는 조건에 의해 $ \lambda_1 $은 0이 되어야만 합니다. x가 살아있으면 이 함수는 좌우 대칭이 깨지기 때문이죠. 따라서 다시 써보면

$ f(x) = Ae^{- \lambda_2 \cdot (x-\mu)^2} $

이렇게 정리가 됩니다.

그리고 이것을 통해서 정말 신기하게도, 이 함수의 '개형'을 알게 되었습니다.

그러면 이제 $ \lambda_2 $와 A만 알면 완벽한 정규분포식을 알 수 있겠군요!?

 

 

6. $ \lambda_2 $와 A 찾으러 떠나세~

여기서 다시한번 정리해보죠. 정규분포함수의 pdf는 $ f(x) = Ae^{- \lambda_2 \cdot (x-\mu)^2} $입니다.

그렇다면,

조건1:

조건 $ \int_{-\infty}^\infty f(x) dx = 1 $에서, f(x)를 대입하면

$ \int_{-\infty}^\infty Ae^{- \lambda_2 \cdot (x-\mu)^2} dx =1  $

이렇게 정리가되고, 이것을 풀면 $ \lambda_2 $와 A를 구할 수 있겠네요.

일단, A는 상수계수이므로 적분기호 밖으로 뺄 수 있을테니, $ \lambda_2 $부터 구해보도록하죠.

$ A \int_{-\infty}^\infty e^{- \lambda_2 \cdot (x-\mu)^2} dx = 1 $

그러나 여기서 안타까운 상황에 직면합니다.

$ e^{x^2} $꼴의 적분은 자명한 원시함수가 없음이 밝혀져있죠.(리우빌의 정리(Liouville’s theorem on integration in finite terms)에 의해 증명됩니다.)

그러면 풀지 못하냐.. 하면 우리 엄청나신 가우스님께서 이걸 약간의 트릭으로 아주 멋지게 풀어내십니다.

일단 $ x-\mu $를 $ u $로 치환해줍니다.

$ \int _{-\infty}^\infty e^{-\lambda_2 u^2} du $

여기서 해를 $ I $라고 하면 식은 다시

$ I = \int _{-\infty}^\infty e^{-\lambda_2 u^2} du $

이렇게 쓸 수 있습니다.

그리고 여기서 양변을 제곱해줍니다.

적분 변수를 구분해주기위해 다른 문자인 x, y를 씁니다. 여기서 x는 위에서의 x와 상관이 없습니다.(잠깐 쓰고 사라질 친구들이라 그냥 x쓰겠습니다)

$ I^2 = \left( \int _{-\infty}^\infty e^{-\lambda_2 x^2} dx \right)\left( \int _{-\infty}^\infty e^{-\lambda_2 y^2} dy \right) $

적분을 합치고, 수식을 정리하면

$ I^2 = \iint _{\mathbb{R^2}} e^{-\lambda_2 (x^2+y^2)} dx dy $

여기서 $ \mathbb{R^2} $는 '실수*실수 모든 영역에서'라는 뜻으로 $ \int _{-\infty}^\infty\int _{-\infty}^\infty = \iint_{\mathbb{R^2}} $입니다.

여기서 $ x^2+y^2 = r^2 $이라는, 원의 방정식이자 극좌표 표기 형식으로 바꿔보면,

$ dx dy $의 경우 미소 면적을 뜻하는 것인데, 극좌표 형식에서는 미소한 $ \theta $에 대해 부채꼴의 호의 길이인 $ rd\theta $와 $ dr$의 곱으로 표현할 수 있으므로 둘이 치환되며,

구간의 경우 $ r $이 0부터 무한대까지, 그리고 $ \theta $가 0에서 $2\pi$까지면 실수영역에서 $ \mathbb{R^2} $를 커버하므로 이와같이 치환하면 수식은

$ I^2 = \int_{0}^{2\pi}\int _{0}^\infty e^{-\lambda_2 r^2} rdrd\theta $

이와같이 바뀝니다.

여기서 안쪽 적분인

$\int _{0}^\infty e^{-\lambda_2 r^2} rdr$

부터 적분하면, $ \lambda_2 r^2 = v $,  $ 2\lambda_2 rdr = dv \Leftrightarrow rdr = \frac{dv}{2\lambda_2} $로 치환하면

$\frac{1}{2\lambda_2}\int_0^\infty e^{-v} dv $

이렇게 변형이 되고, $ \int_0^\infty e^{-v} dv = 1 $이므로

안쪽적분은 $\frac{1}{2\lambda_2}$가 나옵니다.

이제 바깥쪽 적분으로 들어가면

$ \frac{1}{2\lambda_2} \int_0^{2\pi}d\theta $이므로

$ I^2 = \frac{2\pi}{2\lambda_2} $

$ I = \sqrt{\frac{\pi}{\lambda_2}} $

가 됩니다.

$ A \int_{-\infty}^\infty e^{- \lambda_2 \cdot (x-\mu)^2} dx = 1 $

여기에서 적분부분이 $ I $이므로, $ A\sqrt{\frac{\pi}{\lambda_2}} = 1 $

$ A = \sqrt{\frac{\lambda_2}{\pi}} $

 

조건2:

여기서 저희는 분산조건도 만족시켜야 합니다.

$ \int_{-\infty}^\infty (x-\mu)^2 \cdot f(x) dx = \sigma^2 $

f(x)에 $ Ae^{- \lambda_2 \cdot (x-\mu)^2} $대입하고, 마찬가지로 $ x-\mu $를 $u$로 치환하면

$ \int_{-\infty}^\infty u^2 \cdot Ae^{- \lambda_2 \cdot u^2} du = \sigma^2 $

여기서 A를 적분 밖으로 빼면

$ A \int_{-\infty}^\infty u^2 \cdot e^{- \lambda_2 \cdot u^2} du = \sigma^2 $

요런식이 나오는데, 여기서 부분적분해야하나?라는 생각이 들수도 있지만, 아주 멋있는 해법이 있습니다.

아까

$ I = \int _{-\infty}^\infty e^{-\lambda_2 u^2} du = \sqrt{\frac{\pi}{\lambda_2}} $

였죠?

이걸 바로 $ \lambda_2 $로 미분해줍니다.

$ \frac{dI}{d\lambda_2} = \frac{d}{d\lambda_2}\int _{-\infty}^\infty e^{-\lambda_2 u^2} du = \int _{-\infty}^\infty \frac{d}{d\lambda_2}e^{-\lambda_2 u^2} du = \int_{-\infty}^\infty (-u^2) \cdot e^{- \lambda_2 \cdot u^2} du $

따라서

$ \int_{-\infty}^\infty u^2 \cdot e^{- \lambda_2 \cdot u^2} du = -\frac{d}{d\lambda_2}\sqrt{\frac{\pi}{\lambda_2}} $

$ = -\sqrt{\pi} \frac{d}{d\lambda_2} \lambda_2^{-\frac{1}{2}} $

$ = -\sqrt{\pi} (-\frac{1}{2}) \lambda_2^{-\frac{3}{2}} $

$ = \frac{1}{2}\sqrt{\frac{\pi}{\lambda_2^3}} $

$ = \frac{1}{2\lambda_2}\sqrt{\frac{\pi}{\lambda_2}} $

다시정리하면,

$ A \frac{1}{2\lambda_2}\sqrt{\frac{\pi}{\lambda_2}} = \sigma^2 $

위에서 $ A = \sqrt{\frac{\lambda_2}{\pi}} $이었으므로

$ \sqrt{\frac{\lambda_2}{\pi}} \frac{1}{2\lambda_2}\sqrt{\frac{\pi}{\lambda_2}} = \sigma^2 $

$ \frac{1}{2\lambda_2} = \sigma^2 $

$ \lambda_2 = \frac{1}{2\sigma^2} $

이렇게 $ \lambda_2 $가 구해지고, A는

$ A = \sqrt{\frac{\lambda_2}{\pi}} $

이므로 여기에 대입하면

$ A = \sqrt{\frac{1}{2\pi\sigma^2}} $

$ = \frac{1}{\sqrt{2\pi\sigma^2}} $

 

 

7. 결론

따라서 유도된 정규분포 pdf는

$ f(x) = \frac{1}{\sqrt{2\pi\sigma^2}}e^{- \frac{(x-\mu)^2}{2\sigma^2}} $

이와 같습니다.

 

완전 무에서부터 조건들만 가지고 정규분포 pdf가 증명되는게 너무 신기하지 않나요?

단순 선형 회귀에서 상관계수와 결정계수와의 관계(The relationship between a correlation coefficient and a coefficient of determination)

 

1) $ r(x, y) $

 $ r(x, y) = \frac{\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i-\bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 

2) $ r(\hat{y}, y) $

 $ r(\hat{y}, y) = \frac{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})(y_i-\hat{y}_i+\hat{y}_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i y_i-\bar{y} \hat{y}_i-\bar{y} y_i+\bar{y}^2)}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}[(y_i - \hat{y}_i)(\hat{y}_i-\bar{y})+(\hat{y}_i - \bar{y})^2]}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $
 $ \qquad \quad meanwhile, $
 $ \qquad \quad SST = SSR+SSE $ 
 $ \qquad \quad \sum_{i=1}^{n}(y_i - \bar{y})^2 = \sum_{i=1}^{n}((y_i - \hat{y}_i) + (\hat{y}_i - \bar{y}))^2 $ 
 $ \qquad \quad \qquad \qquad \qquad = \sum_{i=1}^{n}[e_i + (\hat{y}_i-\bar{y})]^2, e_i = (y_i-\hat{y}_i) $  
 $ \qquad \quad \qquad \qquad \qquad = \sum_{i=1}^{n}e_{i}^{2}+2\sum_{i=1}^{n}e_i(\hat{y}_i-\bar{y})+\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2 $  
 $ \qquad \quad \qquad \qquad \qquad \therefore \sum_{i=1}^{n}e_i(\hat{y}_i-\bar{y}) = 0 $ 
 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \sqrt{\frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 

3) $ r(x, y) = r(\hat{y}, y) $

 $ \hat{y}_i = \beta_0 + \beta_1 x_i $

 $ x_i = \frac{\hat{y}_i - \beta_0}{\beta_1} $

 $ \bar x = \frac{1}{n}\sum_{i=1}^{n}\frac{\hat{y}_i - \beta_0}{\beta_1} $

 $ \quad = \frac{1}{n \beta_1}(\sum_{i=1}^{n}\hat{y}_i - n\beta_0) $

 $ \quad = \frac{1}{n \beta_1}\sum_{i=1}^{n}\hat{y}_i - \frac{\beta_0}{\beta_1} $

 $ r(x, y) = \frac{\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i-\bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\frac{\hat{y}_i - \beta_0}{\beta_1}-\frac{1}{n \beta_1}\sum_{i=1}^{n}\hat{y}_i + \frac{\beta_0}{\beta_1})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\frac{\hat{y}_i - \beta_0}{\beta_1}-\frac{1}{n \beta_1}\sum_{i=1}^{n}\hat{y}_i + \frac{\beta_0}{\beta_1})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\frac{1}{\beta_1}\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}\frac{1}{\beta_1^2}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\frac{1}{\beta_1}\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)(y_i-\bar{y})}{\frac{1}{\beta_1}\sqrt{\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $
$ \qquad \quad y_i = \hat y_i + e_i $
$ \qquad \quad \sum_{i=0}^n y_i = \sum_{i=0}^n \hat y_i + \sum_{i=0}^n e_i $
$ \qquad \quad \sum_{i=0}^n y_i = \sum_{i=0}^n \hat y_i \; \because $ sum of errors = 0

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i-\bar y)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i - \bar y)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = r(\hat y, y) = \sqrt{\frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 

 $ \therefore r(x, y)^2 = r(\hat y, y)^2 = \frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sum_{i=1}^{n}(y_i-\bar{y})^2} = \frac {SSR}{SST} = R^2 $ (only in simple regression)

Failed to import 'pydot'. Please install 'pydot'. For example with 'pip install pydot'.

 

상황설명-

이 에러는 keras 혹은 의사결정나무(decision tree)에서 그래프를 그릴 때 사용하는 graphviz에 문제가 있을 때 발생합니다. 맥과 같은 linux os에서는 패키지가 깔리지 않았을 때, windows에서는 거의 무조건 발생하는 에러라고 보시면 됩니다. 사실 에러는 pydot자체적인 문제가 '아닙니다.' pip install pydot해도 오류는 해결이 되지 않아요.

 

해결법-

1) Mac과 같은 linux기반 OS + Anaconda

  (prompt)

  $ conda install graphviz

  [if needed]

  (coding tools)

  import os
  os.environ["PATH"] += os.pathsep + '~/opt/anaconda3/lib/site-packages/graphviz'

프롬프트에서 먼저 graphviz를 인스톨 해주시면 문제없이 돌아가는 경우가 많습니다. 그러나 설치한 뒤에도 계속해서 에러가 발생한다면 명시적으로 코드내에서 시스템 환경변수를 등록해주시면 됩니다.

 

2) Windows + Anaconda

  맥에 비해서 조금 복잡합니다.

  먼저 프롬프트에서

  $ pip install pydotplus

  를 입력하여 pydotplus를 설치해주십시오.

  이후
  https://graphviz.gitlab.io/_pages/Download/Download_windows.html
  홈페이지에 접속하여 OS에 맞는 graphviz설치 프로그램을 받아주신 뒤 설치하여 주십시오.(msi 확장자를 가진 파일로 다운로드 받아주시기 바랍니다.)

  만약 어떤 설정도 건드리지 않고 설치하였을 시 C드라이브 아래 Program Files (x86)경로에 깔릴 것입니다.

  이후
  import os
  os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'

  맥에서와 마찬가지로 코드 내에서 명시적으로 시스템 패스를 설정해주시면 됩니다.

  (실제 시스템 자체에서 패스 설정하는 방법이 있지만 복잡하여 코드 내 설정방법으로 설명드렸습니다.)

제작년에 keras로 CUDA환경을 구축하려다가 정말 정보의 심각한 부족으로 실패한 적이 있었는데, 이번에는 별 문제 없이 한번에 성공하여서 그 과정을 기록하려고 합니다.


저에게도 의미있는 기록이지만, 다른 분들도 많은 도움이 되셨으면 좋겠네요.



이번에는 keras같은 상위 wrapper 없이 텐서플로 그대로 진행하였습니다.


도움을 많이 받은 문서는

https://www.tensorflow.org/install/gpu

로, 텐서플로 페이지 자체에서 제공해주고 있습니다.


아래는 제 컴이 윈도우즈인 관계로 윈도우즈를 기본으로 합니다.

만약 linux와 같은 운영체제이신 경우 위의 텐서플로 홈페이지에서 리눅스는 어떻게 설치하는지 잘 알려줍니다!


1) 본인의 GPU가 CUDA GPU 환경을 제공하는지를 확인해 봅니다.

기본적으로 CUDA가 엔비디아nVidia사에서 만든 플랫폼이므로 엔비디아의 지포스 제품이면 일단 가능성은 있지 않을까 생각해 볼 수 있을 것 같습니다.

그리고 GTX 붙으면 일단 된다고 보시면 될 것 같습니다.

요기로 가시면 CUDA가 가능한 GPU인지 확인해 보실 수 있습니다. https://developer.nvidia.com/cuda-gpus

저는 GTX 1060이라 묻지도 따지지도 않고  그냥 설치했습니다.


2) 차례대로 NVIDIA® GPU drivers, CUDA® Toolkit, CUPTI, cuDNN을 깔아줍니다.

텐서플로-gpu는 먼저 깔아도 되고 위의 4가지 프로그램을 다 깔고 깔아도 되는 것 같습니다.

CUPTI는 굳이 안깔아도 될 것 같기는 한데, 저번에 한번 CUDA하려다 안되서 작은 가슴에 그냥 깔고 진행했습니다.


2*) gpu환경을 사용하기 위해서는 tensorflow-gpu를 깔아야 합니다. 아나콘다를 사용하시면 아나콘다 프롬프트에서 conda install tensorflow-gpu를, 아니시라면 pip install tensorflow-gpu를 입력하시면 tensorflow-gpu가 깔립니다. tensorflow-gpu가 깔리면, 이전과 같이 import tensorflow하시면 됩니다.


3) 다 깐 뒤에 시스템 PATH를 설정해 주어야 합니다.

여기서는 시스템 PATH를 설정해 주는데, 깔린 위치가 정확해야 합니다.

드라이버와 툴킷을 깔면 설치파일처럼 설치가 되고, CUPTI와 cuDNN은 압축파일로 풀리게 될 것 입니다.

여기서 설치파일은 상관이 없는데, CUPTI과 cuDNN은 압축을 푼 뒤 폴더 이름을 각자 'CUPTI'와 'tools'로 바꾸어 줍니다.

그리고 CUPTI 폴더는 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\extras'아래에 폴더를 통채로 복사 붙여넣기 해주시고, tools 폴더는 C드라이브 아래 바로 붙여넣어 주세요.


이후 아무 명령 프롬프트나 여시고(예를 들어 실행->cmd)

SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin;%PATH%

SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\extras\CUPTI\libx64;%PATH%

SET PATH=C:\tools\cuda\bin;%PATH%

요렇게 세 개를 써주시면 됩니다.


텐서플로에서 9.0만 지원한다고 그래서 찾다가 저는 9.1로 설치하였는데, v10도 텐서플로에서 잘 작동하는 것 같습니다. 만약에 오류가 나시면 v9.1로 시도해 보세요.


4) 제대로 깔려서 gpu에서 사용되는지 확인하기 위해서

파이썬을 켜시고(명령프롬프트에서 python 치셔도 되고, jupyter notebook에서 cell에 입력하셔도 됩니다.)

from tensorflow.python.client import device_lib 

print(device_lib.list_local_devices())

이렇게 입력해서 무언가 주르륵 나온다 하면 설치가 제대로 된 것입니다.

그리고 이후에 tensorflow 소스코드에서


device_name = "/gpu:0"

log_device_placement = True


with tf.device(device_name):

    x = tf.placeholder(tf.float32, shape=[None, 32, 32, 3])

    y = tf.placeholder(tf.float32, shape=[None, 10])

    .

    .

    .


with tf.Session(config=tf.ConfigProto(log_device_placement=log_device_placement)) as sess:

    sess.run(tf.global_variables_initializer())

    .

    .

    .


요런식으로 소스 코드를 수정해주시면 프로그램 실행 중 명령 프롬프트에서 실제로 GPU가 사용되는 현황을 볼 수 있습니다.

요 근래에 꾸준하게 통계에서부터 머신러닝을 거쳐 딥러닝을 배우고, 딥러닝을 배우고, 딥러닝을 또 배우다보니 뭔가 정리를 하고 싶은 욕망이 꾸물꾸물 올라오네요.


사실 인터넷에 찾아보면 정말 한 포스팅 내에 삐까뻔쩍하게 사진이랑 막 수식이랑 코드랑 막막 쓰이면서 그런 포스팅들이 넘쳐날 것을 알지만..


그래도 실제로 계속해서 배우는 사람의 입장으로 뭔가 거창한 거 빼고 담담하게 중요한 부분들만 간단하게 정리한 포스팅은 없지 않을...까? 해서 적어보는 포스팅입니다.


사실 한 포스팅안에 그 많은 딥러닝에 대한 내용을 담는 것도 어렵고 해서 제가 시간이 날 때마다 차근차근 써 볼 생각입니다.


그리고 제가 아는 한도 안에서 거창하지 않게 쓸 것이라, 이 부분에서는 이 글을 읽으시며 틀을 잡으시고 관련된 부분들을 찾아보시면 더 좋을 것 같습니다.(그리고 사실 그것이 제가 이 블로그를 만든 이유이기도 하지요.. 문턱에너지를 낮춰주는 블로그...)


그럼 시작해보겠습니다.


일단 역사보다는...


자, '딥러닝'은 왜 '딥러닝'일까요?


사실 딥러닝을 알기 전에 '머신러닝'이라는 것을 먼저 알아야 합니다.


딥러닝은 '기계가 스스로 학습한다'는 기계 학습 혹은 머신 러닝의 한 부분이기 때문이지요.


그리고 머신러닝에서는 입력과 출력 사이의, 사람으로 치자면 '추론의 단계'를 스스로 공부하는 것이죠.


이 추론의 단계를 '블랙 박스'라고 그냥 생각해 보자면


머신러닝은


'입력 -> 블랙 박스 > 출력'


이렇게 됩니다.


그리고 이 '블랙 박스'를 사람이 어느정도 수학적 알고리즘으로 만들어 주게 되면, 시행과 오차를 반복하며 스스로의 로직을 찾아갑니다.


그런데 딥러닝은 요 '블랙 박스' 부분이, "진짜로" 블랙 박스입니다.


머신 러닝은 사람이 어느정도의 수학적 알고리즘을 부여해 주고 그에 따른 답을 찾는 것이었다면(즉, 대략 찾아가는 방식을 아는 것이라면), 딥러닝에서는 아예 사람이 요 부분에 손을 대지 않습니다.


그래서 결국에 답이 나와도 '어째서 이 답이 이렇게 나오지?'하는 부분을 모르는 것입니다.


그리고 요 블랙 박스 부분이 머신 러닝과 다르게 긴 여러개의 과정을 가지기 때문에 '딥' 러닝이라고 부르는 것입니다. (긴것을 깊다고 볼수도 있지요)


반대로 머신러닝을 'Shallow learning'이라고 부르는 경우도 있습니다.


그리고 이 블랙박스 부분은 로젠 블라트라는 사람이 고안한 퍼셉트론에서 출발한 '인공 신경망'이 기본인데, 이 부분은 제가 이후에 다룰 수도 있고, 이 부분 부터는 인터넷에 정말 많은 정보들이 있으니 직접 찾아보셔도 좋을 것 같습니다.



사실 딥 러닝이라는 어려운 분야를 정말 짧고 단숨에 읽히는 포스팅으로 쓰기 위해 여러 지식을 한번에 묶어서 쓰려니 힘드네요...


그래도 이 글을 읽고 '와! 딥러닝! 아시는구나!' 하셨으면 좋겠습니다.


그럼 다음에 뵈어요~

+ Recent posts