이 글은...
Andrew Ng 교수의 Deep Learning 강좌 C1W2L18 까지의 내용을 정리한 것이다. NumPy를 사용할 때 주의할 점과 문제를 예방하는 법을 알아보았다. 그리고 로지스틱 회귀의 비용함수가 유도되는 과정을 공부하였다.
내용 요약
파이썬과 NumPy 벡터
NumPy를 이용해서 벡터를 만들 때 흔히 실수할 수 있는 예시를 들었다. 크기가 5인 정규분포를 가지는 벡터를 만들려면 아래와 같이 입력한다.
>>> a = np.random.randn(5)
>>> print(a)
[ 0.68386802 0.36410561 -0.67967483 -0.83958757 -2.05102972]
언뜻 보면 (1, 5) 크기의 행렬 같지만 그렇지 않다.
>>> print(a.shape)
(5,)
여기서 a는 랭크가 1인 배열이다. 강의에서 예시를 든 것처럼 a를 transpose 시켜보면 이렇다.
>>> print(a.T.shape)
(5,)
아무런 문제 없이 코드가 실행되지만 원하던 결과가 아니다. 원하던 결과는 (5, 1)이다. np.dot()
같은 연산도 아무 문제 없이 실행되지만, 결과는 그렇지 않다. np.dot(a.T, a)
의 결과는 (5, 5) 크기의 행렬이 될 것으로 예상하지만 결과는 실수가 나온다.
우리가 원했던 (1, 5) 크기의 벡터를 만들려고 한다면 이렇게 입력해야 한다.
>>> a = np.random.randn(1,5)
>>> print(a)
[[-0.3223847 -1.22128545 -0.45032089 0.03778338 -0.66156257]]
a를 출력한 결과를 보면 대괄호가 이중으로 있다는 것을 알 수 있다. 이것이 (1, 5) 행렬이다. 위에서 했던 실험을 똑같이 진행하면 아래와 같이 결과가 다르다는 것을 알 수 있었다.
>>> print(a.shape)
(1, 5)
>>> print(a.T.shape)
(5, 1)
>>> print(np.dot(a.T, a).shape)
(5, 5)
벡터를 만들 때 반드시 행과 열의 크기를 명시해주는 습관을 지녀야 한다. 그리고 벡터 계산을 하기 전에 예상하는 크기가 맞는지 확인하는 과정도 코드에 집어넣는 게 좋다.
assert(a.shape == (1, 5))
assert()
함수는 입력된 조건을 만족하지 않으면 오류를 출력하고 코드를 중단해준다. 잘못된 입력으로 인해서 나타나는 오류를 미리 예방해주는 역할을 한다.
로지스틱 회귀의 비용함수 설명
로지스틱 회귀에서 사용하는 비용함수가 어떻게 만들어졌는지 설명한다.
로지스틱 회귀에서 y의 예측값($\hat{y}$)은 이런 식이다.
$\hat{y}=\sigma{(w^Tx+b)}$
여기서 예측값이란 $x$가 주어졌을 때 $y$가 1인 확률이다. 이 말은 이런 식으로 나타낼 수 있다.
$\hat{y}=P(y=1|x)$
이 식으로 $y$가 1인 확률과 1이 아닌 확률을 아래처럼 쓸 수 있다.
$\text{If }; y=1:\quad P(y|x)=\hat{y}$
$\text{If }; y=0:\quad P(y|x)=\hat1-{y}$
이제 이 식을 하나로 합쳐본다.
$P(y|x)=\hat{y}^y(1-\hat{y})^{(1-y)}$
두 식을 합친 형태가 왜 이런 형태가 되는지 바로 알 수는 없었다. 하지만 $y$가 1일 때와 0일 때를 가정하여 값을 대입해보면 앞서 보았던 두 식과 똑같이 표현되는 것을 확인할 수 있었다. 이런 직관은 어떻게 만들어지는지 알 수는 없지만 일단은 확률 함수가 이렇게 생겼다는 것을 알고 넘어갔다.
$\log$함수는 강한 단조 증가 함수이다. 따라서 $\log P(y|x)$를 최대화하는 것은 $P(y|x)$를 최대화하는 것과 같은 결과를 낸다. 그러므로 방금 만들어놓은 식 양변에 $\log$를 붙여서 표현하면 아래와 같다.
이 부분에서 어떻게 $\log$를 붙일 생각을 할 수 있는지 궁금했다.
$\begin{matrix}
\log P(y|x) &=&\log (\hat{y}^y(1-\hat{y})^{(1-y)}) &(1)\
&=&y\log{\hat{y}} + (1-y)\log{(1-\hat{y})}&(2)\
&=&-L(\hat{y},y)&(3)
\end{matrix}$
식(1)에서 식(2)로 넘어가는 것은 로그의 성질 때문에 가능하다. 중요한 것은 식(2)는 이전에 살펴보았던 손실함수 $L$에 음수를 취한 값이라는 것이다. 로지스틱 회귀에서는 손실함수 결괏값이 작으면 작을수록 확률이 커지는 것을 의미한다는 것을 여기서 알 수 있다.
이제 비용함수를 알아볼 차례다. $m$개 훈련 세트가 있을 때 이것의 전체 확률은 각 샘플 $x^{(i)}$에 대한 확률 $y^{(i)}$의 곱으로 나타낼 수 있다. 식으로 쓰면 아래와 같다.
$P(\text{labels in training set})=\Pi_{i=1}^mP(y^{i}|x^{i})$
이 식에도 양변에 $\log$를 취하면 다음과 같이 된다.
$\begin{matrix}
\log P(\text{labels in training set})&=&\log \Pi_{i=1}^{m}P(y^{i}|x^{i}) & (1)\
&=&-\Sigma_{i=1}^{m}L(\hat{y},y) & (2)
\end{matrix}$
식(1)에서 식(2)로 넘어갈 때 당황스러웠지만 곰곰이 생각해보면 별것 아니라는 것을 알게 되었다. $\log$의 곱은 $\log$의 더하기로 표현할 수 있다는 것과 파이라고 읽는 $\Pi$이 기호가 모든 원소를 곱하는 것이라는 것을 알고 나니 이해가 되었다.
이제 비용함수를 나타낼 차례다. 앞서 손실함수를 구할 때와 마찬가지로 비용함수, 즉 손실함수의 평균이 최소가 될 때 학습이 잘되었다고 판단할 수 있기 때문에 음수를 곱하여 나타낸다. 마지막으로 스케일을 맞추기 위해 훈련 세트의 수 $m$를 나누면 비용함수가 완성된다.
$\begin{matrix}
J(w,b)&=&-P(\text{labels in training set}) \
&=&{1 \over m}\Sigma_{i=1}^{m}L(\hat{y},y)
\end{matrix}$
'연구 노트 > 머신러닝' 카테고리의 다른 글
[TIL] 210406 - Deep LearniNg (~C1W3L05) (0) | 2021.04.06 |
---|---|
[TIL] 210405 - Deep LearniNg (~C1W3L03) (0) | 2021.04.05 |
[TIL] 210331 - Deep LearniNg (~C1W2L15) (0) | 2021.03.31 |
[TIL] 210330 - Deep LearniNg (~C1W2L13) (0) | 2021.03.30 |
[TIL] 210329 - Deep LearniNg (~C1W2C10) (0) | 2021.03.29 |