2018년 9월 2일 일요일

[The Art of Readable Code, 읽기 좋은 코드가 좋은 코드다] 2. 이름에 정보 담기

표면적인 수준에서의 개선



"표면적 수준이란 좋은 이름을 짓고, 좋은 설명을 달고, 코드를 보기 좋게 정렬하는 따위를 의미한다."

책의 첫 단락은 표면적인 수준에서의 개선부터 시작합니다. 이런 수정은 코드를 통째로 바꾸거나 동작하는 방식을 변화시키지 않고 '그 자리에서' 곧바로 만들 수 있기에 첫 시작으로 매우 적절하다 생각합니다.

물론 가독성에 관련된 논의는 이 수준보다 더 나아가 많은 내용을 담고 있겠으나 이는 차차 살펴갈 것이며 먼저 1부에서는 폭넓게 적용할 수 있고, 그다지 많은 노력을 요구하지 않는 내용을 우선적으로 다룹니다.

이름에 정보 담기


변수, 함수, 혹은 클래스 등의 이름을 결정할 때는 항상 같은 원리가 적용합니다. 
"이름을 일종의 설명문으로 간주해야 한다."
충분한 공간은 아니지만, 좋은 이름을 선택하면 생각보다 많은 정보를 전달할 수 있다는 것이죠. 구체적으로는 아래의 여섯 가지 방법을 제안합니다.
  • 특정한 단어 고르기
  • 보편적인 이름 피하기 (혹은 언제 그런 이름을 사용해야 하는지 깨닫기)
  • 추상적인 이름 대식 구체적인 이름 사용하기
  • 접두사 혹은 접미사로 이름에 추가적인 정보 덧붙이기
  • 이름이 얼마나 길어져도 좋은지 결정하기
  • 추가적인 정보를 담을 수 있게 이름 구성하기
앞으로는 책에 나온 내용을 모두 다 소개하기 보다는 개중 제가 재미있었던 내용들을 좀 골라서 예시와 함께 알아보겠습니다. 

특정한 단어 고르기


매우 구체적인 단어를 선택하여 "무의미한" 단어를 피하자. 

예를 들어 "get"은 지나치게 보편적입니다.

def GetPage(url):
    ...

여기서 "get"보다는 메소드가 어디에서 페이지를 가져오는 지 알려줄 수 있게 FetchPage() 혹은 DownloadPage()와 같이 구체적으로 명명하는 것이 더 좋습니다.

사실 위 예시보다 다음 예시가 더 좋았는데요. 다음과 같이 BinaryTree 클래스에서

class BinaryTree {
    int Size();
    ...
}

우리는 Size() 메소드가 반환하는 것이 무엇일 지 이름만 봐서는 알 수 없습니다. 트리의 높이, 노드의 개수, 혹은 트리의 메모리 사용량이 될 수도 있겠죠.  따라서 Height(), NumNodes(), 혹은 MemoryBytes() 등이 더 의미 있는 이름이라는 것에는 모두 동의하리라 생각합니다. 

같은 맥락에서 저자들은 thesaurus를 뒤져보고 더 나은 이름을 생각하기를 권합니다. 다만 너무 "재치" 있는 이름보다는 명확하고 간결한 이름이 더 좋습니다. 다음에 이어지는 내용들도 사실 같은 내용인데 예제들과 소소한 팁 위주로 살펴보곘습니다.

tmp나 retval 같은 표편적인 이름 피하기


"변수값을 설명하는 이름을 사용하라"

예를 들어, 다음과 같이 Euclidean norm을 계산하는 자바스크립트 코드에서

var euclidean_norm = function (v) {
    var retval = 0.0;
    for (var = i = 0; i<v.length; i+=1)
        retval += v[i];
    return Math.sqrt(retval);
};

retval보다는 sum_squares라고 이름을 붙여준다면 변수의 목적을 바로 이해할 수 있으며 나중에 버그를 잡을 때도 용의합니다.

retval += v[i]; 부분이 sum_squares += v[i]; 였다면 훨씬 눈에 잘 띄었겠죠.

물론 아래와 같이 정말로 대상이 짧게 임시적으로만 존재하고, 임시적 존재 자체가 변수의 가장 중요한 용도일 때는 tmp와 같은 변수를 사용할 수 있겠습니다.

두 변수를 서로 교환하는 알고리즘 예:

if (right<left) {
    tmp = right;
    right = left;
    left = tmp;
}

같은 맥락으로 i, j, iter, it 같은 이름이 인덱스나 루프 반복자로 사용되는 것은 충분히 괜찮습니다. 다만 이 역시도 디버깅의 용이성을 위해서 아래와 같이 소속을 표현해준다면 더 좋겠죠.

(i, j, k) -> (club_i, members_j, users_i) or (ci, mj, ui)

활용 예:
if (clubs[ci].members[ui] == users[mi]) # 버그! 처음 문자가 일치 하지 않는다.

따라서 표편적인 이름이 항상 나쁜 것은 아니지만, 이를 사용하려면 꼭 그렇게 해야하는 이유가 있어야 합니다. 


추가적인 정보를 이름에 추가하기 


단위(sec, millisecond, kg 등)를 포함하거나 다른 중요한 속성(unsafe, utf_8 등)이 있을 때는 변수에 그런 내용을 추가해주면 좋습니다. 

start -> start_ms, elapsed -> elapsed_ms
html -> html_utf-8 # html의 바이트가 UTF-8으로 변환되었다. 

이름은 얼마나 길어야 하는가?


만일 변수가 좁은 scope (예: 끽해야 몇 줄 안의 함수 scope)에서 사용된다면 멤버 변수가 "m"과 같이 매우 짧은 이름을 사용해도 별 문제가 없으나 이 변수의 scope이 클래스나 전역으로 넓어지면 가독성이 매우 떨어지게 되므로 상황에 따라 잘 사용하라고 하는군요. 

게다가 요즘은 긴 이름을 입력하는 것이 자동완성 기능으로 매우 편해져서 그리 주저할 일이 아닙니다. 그렇기 때문에 약어와 축약형은 매우 보편적인 경우(string-> str과 같이)를 제외하고는 지양하는 편이 좋겠습니다. 

이에 좀 더 더한다면 ConvertToString()에서 ToString()과 같이 불필요한 단어를 제거해서 간결하게 만드는 등의 팁이 있으나 앞의 내용들이 더 핵심에 가까운 것으로 보입니다. 

이로써 이름에 정보를 넣는 방법에 대해 요약해보았습니다. 

책에서 다음 장은 의미를 오해하기 쉬운 이름들에 대한 팁입니다만 사실 오늘 소개한 내용에 어느 정도 포함되는 것 같습니다. 다음 글에서는 미학(Aesthetics) 즉 "눈을 편하게" 하는 코드에 대해 정리하겠습니다. 





[PR12-Video] 71. Categorical Reparameterization with Gumbel Softmax


TensorFlowKR facebook comunity에서 모인 12명의 paper readers (PR12)가 읽어주는 Deep learning paper awesome list 100선 by Terry Um.

#71. Categorical Reparameterization with Gumbel Softmax


이 리뷰에서는 NIPS 2016 workshop에 같이 발표되었고 최근 ICLR 2017에 발표된 두 편의 논문을 리뷰하겠습니다. 재미있는 점은 이 두 편의 논문들이 똑같은 아이디어를 바탕으로 정확히 같은 수식을 사용하여 arXiv에도 고작 하루 차이로 올라왔다는 것입니다. 아이디어가 공중에 떠다닌다는 말이 정말 맞는가 싶습니다. 즐겁게 들어주시면 감사하겠습니다.


(추신) 24분 부분에 질문 주신 부분에 대해 답이 미진한것 같아 끝나고 곰곰히 생각해본 답글을 여기에 추가합니다.  둘 다 categorical dist를 만드는데 다른 방법을 사용할 뿐이라는것이 맞는 답인것 같습니다. 우리가 nn으로부터 샘플링을 하고 싶으면 logit을 받아서 softmax를 통과시켜서 확률값을 얻어서 이를 바탕으로 분포에 값을 넣어주고 그 분포로부터 샘플을 뽑는 방법이 있겠구요 (이 방법이 준범님이 말씀하신 보통의 방식인 것 같습니다. 결국 마지막 단에서 softmax하여 확률 값을 주니까요) 다만 샘플링을 하지 않고 확률값 자체를 라벨과 빼서 에러를 계산하는데 사용되는 것이라 백프롭에서는 문제가 없는것 같습니다. 자기자신으로 1이니까 그렇다고 생각하는데 혹 이상하면 말씀주세요. 그리고 두번째 방법이 logit에 검벨에서 뽑은 노이즈를 더하여 argmax를 통과시켜서 값을 얻으면 그 자체가 discrete categorical dist에서 나온 샘플입니다. 여기서 argmax를 softmax로 relaxation한 것이 gumbel softmax trick이구요 그래서 이렇게 복잡하게 과정을 거친 이유는 말씀드린 바와 같이 미분이 가능하게 해서 중간에 node가 껴있을때 gradient를 계산하기 위해서인 것으로 이해하면 되지 않을까 싶습니다.

(paper1) Categorical Reparameterization with Gumbel Softmax and
(paper2) The Concrete Distribution: A Continuous Relaxation of Discrete Random Variables

Paper1: https://arxiv.org/abs/1611.01144
Paper2: https://arxiv.org/abs/1611.00712
슬라이드: https://www.slideshare.net/thinkingfactory/pr12-categorical-reparameterization-with-gumbel-softmax

다음에 또 다른 주제로 뵈어요~!

다른 분들의 발표도 보고 싶다면: PR12 딥러닝 논문읽기 모임

다음 읽을거리






2018년 9월 1일 토요일

[The Art of Readable Code, 읽기 좋은 코드가 좋은 코드다] Intro. 코드는 이해하기가 쉬워야 한다.

많은 분들이 그러실텐데 저 역시도 항상 좋은 코드란 어떤 것인지 알고 싶었습니다. 이런 고민을 듣고 최근 회사 동료인 전상혁님이 "The Art of Readable Code"라는 책을 추천해주시기에 책을 도서관에서 빌려 읽고 있는데 정말 많이 배우고 있습니다. 책의 내용이 좋아서 한 권 사서 두고두고 읽으려 합니다.

이런 내용들을 코드에 직접 적용하면서 체득하는 것이 가장 좋겠지만 당장 단기간에 이뤄질 수 있는 일은 아니기에, 일단은 좋은 내용들이 머리에 좀 더 오래 남기를 바라며 책 내용을 정리해서 올리고자 합니다.

나중에 이 글을 찾은 분 혹은 미래의 나 스스로에게 초심자의 입장에서 어떤 점들이 도움이 되었는지를 보여줄 수 있을거라 기대합니다.

이 책은 무엇에 대한 것인가?


이 책은 매우 읽기 편한 코드를 작성하는 방법을 설명하는데요. C++, 파이썬, 자바스크립트, 자바 등을 포함한 다양한 언어로 작성된 코드를 예로 들며 설명해줍니다. 중간중간 껴있는 삽화들도 매우 재치있고 각 장의 주제와 연관되어 있어 이해를 도와줍니다.

재밌는 점은 언어들을 다 알지 못하더라도 책을 읽는 데는 별 어려움이 없다는 것입니다.
저자들이 얘기하기론 "코드의 가독성"이라는 개념 자체가 언어로부터 독립적이기 때문이라고 하지만 제가 보기엔 여기서 저자들의 내공이 드러나는 것이 아닌가 싶습니다.

크게 아래와 같이 4부로 나누어
  1. 표면적인 수준에서의 개선
  2. 루프와 로직를 단순화하기
  3. 코드를 재작성하기
  4. 선택된 주제들
여러 측면에서 코드를 이해하기 쉽게 만드는 방법을 설명해줍니다. 


가독성의 기본 정리

"코드는 다른 사람이 그것을 이해하는 데 들이는 시간을 최소화하는 방식으로 작성되어야 한다."

분량이 적다고 항상 좋은 것이 아닙니다. 좋은 예로 주석도 사실은 "코드를 더하는 행위"지만 코드를 더 빨리 이해하게 도와줍니다. 적은 분량으로 코드를 작성하는 것이 좋은 목표긴 하지만, 이해를 위한 시간을 최소화하는 것이 더 좋은 목표입니다.

또 다른 예로,

return exponent >=0 ? mantissa * (1 <<exponent) : mantissa / (1 << -exponent);

라는 코드보다는

if (exponent >=0) {
    return mantissa * (1 << exponent);
} else {
    return mantissa / (1 << -exponent);
}

이렇게 바꾼 코드가 앞서보다 간결하진 않지만 더 이해하기 쉽습니다.

이해를 위한 시간은 코드의 효율성, 아키텍처, 테스트의 용이성과 같은 다른 목표와 충돌할까봐 걱정할 수도 있으나, 저자들의 경험에 따르면 대다수의 경우 이러한 조건은 거의 아무런 방해가 되지 않다고 합니다.

가장 기본적인 대원칙은 코드를 "읽기 쉽게" 만드는 원리가 적용될 때마다 의심의 여지가 생기면 언제나 가독성의 기본 정리가 다른 어떤 규칙보다 앞선다는 점입니다.

"이 코드는 이해하기 쉬운가?"


만일 정리가 되지 않을 코드를 고치고 싶을 때는 먼저 뒤로 한 걸음 물러나서 스스로에게 물어보는 것이 중요합니다: "이 코드는 이해하기 쉬운가?". 만약 그렇다면 다른 코드로 건너뛰어도 별 상관이 없습니다.



2018년 8월 4일 토요일

What is the relationship between orthogonal, correlation and independence?

제게는 마주칠 때마다 헷갈려서 다시 고민하게 되는 개념들이 있는데, 그 중 대표적인 것이 바로 이 세 가지 녀석들입니다:

Orthogonality, Correlation, Independence.

오늘도 다시 한 번 마주칠 일이 있어서 또 하루종일 공부하는 우매한 짓을 저지른 후, 다시는 이러지 않도록(....이러고선 또 언젠가 다시 이 포스트를 보고 공부하겠지...뻔해...) 정리를 해보고자 합니다.

Independence


"Independence"는 통계적인 개념입니다. 두 random variables X와 Y의 joint distribution이 marginal distribution의 곱으로 표현이 될 때 statistically independent하다고 말한다. 각 variable의 density를 $f$라고 하면:
$$f(x,y) = f(x)f(y),$$
좀 더 일반적으로는 cumulative distribution function을 $F$라고 할 때, 
$$F(x,y) = F(x)F(y)$$
라고 표현할 수 있겠습니다.

Correlation


"Correlation"은 independence와 관련이 있으나 좀 더 약한 통계적 개념으로 두 random variables 간 (Pearson) correlation은 정규화된(standardized) variables의 곱의 기대값을 말합니다:
$$\begin{align*}\rho_{XY} &= \mathbf{E}\left[\frac{X-\mathbf{E}[X]}{\sqrt{\mathbf{E}[(X-\mathbf{E}[X])^2]}}\frac{Y-\mathbf{E}[Y]}{\sqrt{\mathbf{E}[(Y-\mathbf{E}[Y])^2]}}\right]\\
&= \frac{cov(X,Y)}{\sigma_X\sigma_Y}.\end{align*}$$
이 때, $\rho_{XY}=0$는 variables X와 Y가 서로 uncorrelated 되어있다는 말입니다. 한 가지 유의할 점은 두 random variables가 independent하면 항상 uncorrelated이지만 그 역은 성립하지 않는다는 점입니다. (순방향은 정의에 맞게 식을 전개해보면 되고, 역은 counter example을 들어 쉽게 증명할 수 있습니다.)

순방향에 대한 식 전개:
$$\begin{align*}\mathbf{E}[XY]&=\int\int xyP_{X,Y}(x,y)dxdy \\
& = \int\int xyP_X(x)P_Y(y)dxdy\\
&=\mathbf{E}[X]\mathbf{E}[Y] \end{align*}$$
역방향에 대한 counter examples:

여기서 한 가지 헷갈리는 부분이 나오는데요. 지금까지 얘기한 independence는 statistical independence인데 이게 linear independence랑 서로 관련이 있으면서도 다르다는 것입니다. Linear dependent한 경우 statistically dependent 입니다. 이는 $\alpha X = Y$를 만족하는 non-zero scalar $\alpha$가 있을 때,
$$cov(X,Y)=cov(\frac{1}{\alpha}Y,Y) = \frac{1}{\alpha}Var(Y) \neq 0 $$
인 것으로 확인할 수 있습니다. 그러나  X와 Y가 linear independent할지라도 $\rho_{XY}\neq 0$일 수 있기 떄문에 linear independence가 statistical independence를 보장해주지는 않죠.

Orthogonality


"Orthogonality"는 기하에서 온 개념으로 선형 대수학에서 일반적인 정의를 배울 수 있습니다.  선형대수학에서 정의하는 것을 보면, 두 벡터 $u$ 와 $v$가 서로 orthogonal하다는 것은 두 벡터 간의 내적 $<u,v>$이 정의된 내적 공간(inner product spaces)에서 다음 조건을 만족한다는 것입니다:
$$<u,v>=0.$$
즉, 어떤 벡터 간의 orthogonality는 정의한 내적에 따라 달라지기 때문에 주의해야 합니다.

내적은 여러 방식으로 정의될 수 있는데, 한 예로 벡터들이 다음과 같이 수열로 나타내질 때는 우리가 흔히 아는 dot product를 골라서 사용할 수 있겠습니다:
$$u=(u_1,u_2,\cdots,u_n), <u,v>=\sum_{i=1}^{n}u_i v_j.$$
앞서 설명을 유심히 봤으면 알겠지만 orthogonality는 본질적으로 통계적인 개념이 아닙니다.

Orthogonality는 본질적으로 통계적인 개념이 아니다!

그래서 우리가 헷갈리는 이유가 보통 선형대수학에서의 개념을 통계로 가져오면서 생기는 것에서 기인하는 경우가 많습니다.

A)


형식상 random variables의 공간은 vector space로 생각할 수 있습니다. 그러면 당연히 그 공간에서 내적을 다양한 방식으로 정의할 수도 있을텐데, 그 중 한 가지 방식이 바로 covariance를 내적으로 사용하는 것입니다:
$$<X,Y> = cov(X,Y) = \mathbf{E}(X-\mathbf{E}[X])\mathbf{E}(Y-\mathbf{E}[Y]).$$
두 random variables간 correlation이 0이면 covariance도 0이기 때문에, 이 정의에 의해서 ($\mathbf{E}[X]$나 $\mathbf{E}[Y]$ 중 하나가 0인 경우) uncorrelatedness가 orthogonality와 정확히 같아집니다. 따라서 두 random variables가 independent하면 (그리고 둘 중 하나는 zero-centered일 때) 서로 uncorrelated이며 orthogonal 하다고 얘기할 수 있습니다. 다른 방식으로는 $\mathbf{E}[XY]$으로도 내적을 정의할 수도 있습니다 (결국 같은 얘기).

다만, 앞서 얘기한 바와 같이 그 역은 항상 성립하지는 않는데요. 즉, 두 random variable이 orthogonal하다고 해서 independent하지는 않습니다. 이 부분에서 헷갈리는 것이 "음? 직교하는데 independent하지 않는 경우가 어떤게 있지?" 하는 생각이 바로 들게 되죠.

이 부분이 매우 어색하고 이상하다고 여겨지는 이유는 random variable을 어느 순간 fixed variable과 dot product를 가지고 노는 선형 벡터 쪽 영역으로 은근슬쩍 넘어가서 생각하기 때문입니다. 여기서의 직교는 내적을 covariance로 정의하였을 때를 기준으로 얘기하기 때문에 우리가 흔히 생각하던 fixed variable vectors 둘을 골라서 dot product한 기준으로 얘기하면 안 됩니다. 즉, 정의대로 orthogonal = uncorrelated인 경우만을 생각하면 uncorrelated이나 dependent인 경우는 쉽게 받아들일 수 있습니다.

예를 들어 $X$가 $\{-1,0,1\}$ 중 하나의 값을 동일한 확률로 뽑는 random variable일 때 $Y=X^2$에 대해 $\rho_{XY}=0$이지만 dependent임을 쉽게 알 수 있습니다. 사실 $X$가 0을 기준으로 symmetric pdf를 가지면 그 모든 예시에 대해 $X$와 $Y$는 서로 (covariance-wise) orthogonal하지만 dependent합니다.

B)


그러나 통계에서 다루는 모든 variables가 random variables는 아니라는 점에 주의해야 합니다. 특히, 선형 회귀 문제를 생각해보면 거기서 사용하는 입력값과 같은 독립 변수(independent variables)들은 random이 아니라 이미 "정해진" 값들입니다. Independent variables는 보통 수열로 주어지고 위에서 얘기한 바와 같이 자연스럽게 dot product를 내적으로 사용할 수 있겠습니다. 이 때, independent variables가 regression line에 대해 orthogonal인지 아닌지 등을 얘기하는데 이런 맥락에서 보면 애시당초 orthogonality는 statistical definition도 갖지 않고 random variable에 적용되는 얘기도 아니죠. (ANOVA에서의 orthogonal contrasts 등)

정리해보자면 A)에서는 uncorrelatedness와 orthogonality는 사실 같은 것에 대한 다른 이름일뿐입니다. 따라서 가장 좋은 것은 random variable에 대해 uncorrelatedness를 말할 때는 orthogonality라는 용어를 사용하지 않는 것입니다. 그리고 같은 논지로 B)의 맥락에서는 non-random variable에 대해 correlation이라는 용어를 사용하는 것을 지양하는 것이 좋겠습니다.

더 읽어볼 것...


아래 reference로 달아둔 링크 중 "Linearly Independent, Orthogonal, and Uncorrelated Variables"라는 제목의 레포트가 있습니다. Non-random variable에 대해 내적으로 dot product를 사용하여 지금까지 본문에서 바라본 statistical 관점이 아니라 대수적 혹은 기하적 관점에서 바라본 논문 형태의 레포트인데요. 내용을 매우 잘 설명한 좋은(짧은) 논문이지만, 이 경우 내적이 dot product로 달라졌으므로, orthogonality와 uncorrelatedness가 같지 않으며 자칫하면 지금까지 간신히 잡아둔 개념들이 더 헷갈릴 수 있습니다. 따라서 분명한 차이가 있다는 것을 염두에 두고 봐야 합니다.

* 그리고 위 레포트에서는 non-random variable에 대해서도 correlation의 개념을 사용합니다. 엄밀히 말하자면 이는 지금까지가 우리가 얘기했던 population에 대한 correlation coefficient가 아닌 sample correlation coefficient일 때 성립합니다. 앞서는 random variable이 표본 공간(sample space)에 대해 정의된 함수이며, 이 때 함수(random variables)들에 대한 내적을 얘기한 것이었다면, 위 레포트에서는 fixed or predefined variable 즉, sample에 대한 얘기이므로 분명히 다릅니다.

References





2018년 5월 9일 수요일

[Paper Skim] Spectral Normalization for Generative Adversarial Networks

Spectral Normalization for Generative Adversarial Networks

TL;DR: A novel weight normalization technique called spectral normalization to stabilize the training of the discriminator of GANs.
Keywords: Generative Adversarial Networks, Deep Generative Models, Unsupervised Learning
Accept: (Oral)
Rating: 8-8-8
Review: https://openreview.net/forum?id=B1QRgziT-

1. Introduction


Preferred network 그룹에서 나온 논문. (최근 핫한 일본 그룹) 그리고 Ian Goodfellow의 홍보 (보증?...) 개인적으로 매우 취향인 논문. (이후 더 자세히 리뷰 예정) 


GANs를 안정적으로 학습시키는 것을 새로운 weight normalization으로 해결해보고자 함. Spectral normalization이라 불리는 이 방법은,
  • Intensive hyper parameter이 필요없음. Lipshitz constant가 유일한 hyperparameter to be tuned. (심지어는 tuning 안 해도 잘 됨)
  • Implementation이 단순하고 computational cost가 적음. 
Batch normalization이나 weight decay, feature matching on the discriminator와 같은 regularization tech.가 없이도 working 잘 함.

2. Spectral Normalization


각 레이어의 spectral norm을 제약함으로써 Discriminator function $f$의 Lipschitz constant를 컨트롤 함. 

ReLU와 같은 activation function의 Lipschitz norm은 1이기 때문에 네트워크 전체를 볼 때 고려하지 않아도 되고, 결국 Weight의 Lipschitz norm을 나눠줌으로써 각 weight matrix $W$의 Lipschitz constant $\sigma(W)=1$:
$$\bar{W}_{SN}(W):=W/\sigma(W).$$

이를 바탕으로 $||f||_{Lip}$가 1로 상계를 갖도록(upper bounded) 함.

Gradient Analysis of the Spectrally Normalized Weights


The gradient of $\bar{W}_{SN}(W)$ w.r.t. $W_{ij}$:
\begin{align} \frac{\partial\bar{W}_{SN}(W)}{\partial W_{ij}}  &= \frac{1}{\sigma(W)}E_{ij} - \frac{1}{\sigma(W)^2}\frac{\partial \sigma(W)}{\partial W_{ij}}W \\&= \frac{1}{\sigma(W)}E_{ij} - \frac{[u_1v_1^T]_{ij}}{\sigma(W)^2}W \\&= \frac{1}{\sigma(W)} (E_{ij} - [u_1v_1^T]_{ij}\bar{W}_{SN}) \end{align}
여기서 $E_{ij}$는 $(i,j)$-th entry는 1 나머지는 0인 행렬이고 $u_1$과 $v_1$이 first left and right singular vecotrs of $W$. $h$를 hidden layer라고 하면 아래가 성립함:
\begin{align}\frac{\partial V(G,D)}{\partial W}&=\frac{1}{\sigma(W)}(\hat{E}[\delta h^T]-(\hat{E}[\delta^T\bar{W}_{SN}h])u_1v_1^T)\\
&= \frac{1}{\sigma(W)}(\hat{E}[\delta h^T]-\lambda u_1v_1^T) \end{align}
여기서 $\delta:=(\partial V(G,D)/ \partial(\bar{W}_{SN}h))^T, \lambda:=\hat{E}[\delta^T(\bar{W}_{SN}h)]$이고 $\hat{E}[\cdot]$은 각 미니 배치의 empirical expectiation을 나타냄.
For some $k\in \mathbb{R}$, $\hat{E}[\delta h^T]=ku_1v_1^T$일 때 $\frac{\partial V}{\partial W}=0$이 성립함.

여기서 식 (5)의 해석이 매우 재미있는데, 식의 첫번째 항은 normalize되지 않은 weights에 대한 미분이므로 별다를 것이 없고 두번째 항이 추가된 것으로 생각해보면, 이를 adaptive regularization coefficient $\lambda$만큼 첫번째 singular component를 penalize하는 regularization 항으로 본다면 다음과 같은 해석이 가능함:

$\lambda$가 양수라는 얘기는 $\delta$와 $\bar{W}_{SN}h$가 비슷한 방향을 가르키고 있다는 것을 의미함. 즉, $W$의 column space가 한 쪽 방향으로만 집중해서 update되는 것을 막아준다고 해석할 수 있음. 논문에서는 이를 통해 spectral normalization이 네트워크의 각 layer가 한 방향으로만 sensitive하지 않도록 막는다고 얘기함.

3. Spectral Normalization vs Other Regularization Techniques


Weight normalization은 결과적으로 너무 강한 constraint를 걸어버리는 경향이 있음. Weight normalization은 weight matrix의 rank를 1이 되도록 강제함 (matrix norm과 weight normalization definition에 의해 수식을 보면 확인할 수 있음). 

그런데 이렇게 하면 discriminator가 하나의 feature만을 보고 probability distribution을 구별해야하기 때문에 discriminator가 매우 sensitive하고 unstable하게 만드는 경향이 있음.

Orthonormal regularization on each weight는 spectral normalization과 유사하면서도 학습을 안정화해주기는 하지만,
$$||W^TW-I||_F^2$$
weights를 orthonormal하게 하므로써 (모든 singular value를 1로 강제하기 때문에) spectrum의 envelop을 망치고 중요한 정보를 잃어버리는 경향이 있음. Spectral normalization은 spectrum의 scale만을 조절하기 때문에 (최대 값을 1) 이와는 다름.

GP와 같은 경우는 위에서 설명한 다른 normalization tech.들과 같은 문제는 없지만 현재 generative distribution의 support에 매우 강하게 엮여있다는 약점이 있음. 이 때문에 학습이 진행됨에 따라 generative distribution의 support도 바뀌기 때문에 학습 과정이 불안정적이 된다는 단점이 생김. Spectral normalization은 학습하는 함수를 operator space에서 regularize하기 때문에 들어오는 데이터 batch에 보다 덜 민감한 것을 볼 수 있음.


4. Experiments


최초로 단일 네트워크로 이미지넷 1000개 범주의 이미지를 생성한 방법인 것만으로도 큰 의미를 지님.







2018년 5월 1일 화요일

[Paper Skim] AmbientGAN: Generative Models From Lossy Measurements

AmbientGAN: Generative Models From Lossy Measurements





TL;DR: How to learn GANs from noisy, distorted, partial observations
Keywords: Generative models, Adversarial networks, Lossy measurements
Accept: (Oral)
Rating: 8-7-7


GAN을 학습시키기 위해서 고퀄리티 샘플들이 필요한데 (예시: 노이즈가 없는 사진들) 보통 그런 경우가 많지 않다는 것을 지적하고 이를 해결하고자 한 논문. 

즉, 샘플에 occlusion이나 noise, blur 등의 문제가 있는 데이터셋만으로도 원래와 같이 고퀄리티 샘플(occulusion noise blur 혹은 unknown any noise가 없는)을 생성할 수 있는 Generative model을 학습하고자 함. 

직관적인 이해를 위해 결과부터 좀 소개하자면:

이렇게 맨 왼쪽과 같이 patch가 잘려서 zero가 되는 noise function으로 더럽혀진 데이터셋만 있는 경우에도 generator가 맨 오른쪽과 같이 어느정도 얼굴 형태를 생성해내는 모델을 학습함. (중간은 baseline)

개인적으로 재미있었던 실험은 MNIST 데이터를 패딩을 바탕으로 크기를 키운 다음 임의의 각도로 회전하고 한쪽 방향으로 sum 된 1D 데이터로 squash한 데이터들을 바탕으로 학습을 해도 generator가 아래와 같이 어느정도 숫자를 generate하는 모델을 학습해내는 것.


추가 정보로 회전각을 넣어주었을 때 더 잘 복원됨. (오른쪽, 사실 이건 의료 영상에서 CT와 같은 projection으로 생각해보면 자명함)

이 논문이 재미있는건 이렇게 이미지가 복원이 되는 조건을 명확하게 하고 수학적으로 증명을 하였다는 점. 

네트워크 구조도

Generator가 먼저 깨끗한 이미지 $X_g$를 만들면 $f_{\theta}$가 이를 corrupt하는 noise function을 학습해서 $Y_g$를 만들어내고 Discriminator가 corrupt된 real data $Y_r$와 이를 비교하게 하는 구조.

풀고자 하는 문제를 참 잘 특정해서 잡았다고 생각하는 것이, 우리가 얻을 수 있는 데이터는 실제로는 이미 어떤 unknown noise function에 의해 corrupt 되어 나온 것인 경우가 많다는 것이 기본 바탕.

AmbientGANs에서는 데이터가 충분히 많기만 하다면, 이런 noise function을 학습하고 기존의 data distribution을 복원하는 것이 가능하다는 것을 analytically & empirically 보임.

이거 보고 나서 결과를 improve해볼 수 있는 idea들이 몇 개 생각나긴 했는데 해보고 싶은것들이 막 생깁니다ㅋㅋ 당장 recon loss와 cyclic loss를 붙여볼 수 있겠네요.

참고자료





[Paper Skim] Progressive Growing of GANs for Improved Quality, Stability, and Variation

Progressive Growing of GANs for Improved Quality, Stability, and Variation


TL;DR: Train generative adversarial networks in a progressive fashion, enabling us to generate high-resolution images with high quality.
Keywords: generative adversarial networks, unsupervised learning, hierarchical methods
Accept: (Oral)
Rating: 8-8-8
Review: https://openreview.net/forum?id=Hk99zCeAb

GANs를 학습하는 새로운 방법을 제안.
핵심 아이디어는 generator와 discriminator를 점진적으로 키운다는 것: 저해상도에서 시작해서 세밀한 점들을 배울 수 있도록 새로운 레이어들을 추가하는 방식.
이런 방식을 취함으로 인해 GANs을 보다 안정적이면서 빠르게 학습하는 것이 가능해졌다고 얘기함; CelebA 1024^2 해상도 이미지를 만들어 내는 네트워크 학습.
또한 CIFAR10에서 비지도학습 방식으로 생성된 이미지들의 종류가 다양하도록 할 수 있는 간단한 방법을 제안함. Inception score가 8.80에 달한다고 함.

1. Introduction


고해상도 이미지를 만드는 것은 매우 어려운데 그 이유는 해상도가 높을 수록 생성한 이미지인지를 구분하는 것이 쉬워지기 때문.
게다가 큰 해상도 이미지로 인해 메모리 문제로 더 작은 minibatches를 사용하게되고 학습 안정성에 문제가 됨.
여기서 저자들의 주요 insight는 generator와 discriminator를 점진적(progressively)으로 키우는 것.

기존의 GAN 수식은 학습된 생성 모델이 굳이 학습 데이터 분포 전체를 모두 표현할 필요가 없었음. (?)
기존의 공통된 의견은 이미지의 질과 다양성이 서로 tradeoff 관계라는 것이었으나 최근 Odena et al. 2017에 의해 다른 의견이 제기됨. (확인 필요)
다양성에 대한 측정 방법에 대해 매우 많은 방식들이 제안되고 있는데:
including inception score (Salimans et al., 2016), multi-scale structural similarity (MS-SSIM) (Odena et al., 2017; Wang et al., 2003), birthday paradox (Arora & Zhang, 2017), and explicit tests for the number of discrete modes discovered (Metz et al., 2016). 
PGGAN에서는 이 외에 다양성을 보다 북돋기 위해 사용한 방법을 설명하고 이미지의 질과 다양성을 측정하기 위한 새로운 metric을 제안하였음.

2. Progressive Growing of GANs


키 아이디어 정리: 단계별 학습 (구몬??!)
"The complex mapping from latents to high-resolution images is easier to learn in steps" 


아래 그림에서 볼 수 있듯이 점진적으로 네트워크 레이어를 추가할 때 sudden shock이 일어나지 않도록 새로 추가하는 레이어를 부드럽게 (fade in) 넣어줌.



3. Increasing Variation using Minibatch Standard Deviation


이미지가 다양하게 생성되도록 하기 위해 GANs이 학습 데이터의 일부분만 집중하는 성질이 있는 것을 고려하여 Salimans et al. (2016)에서는 Minibatch discrimination 방식을 제안했었음. Feature statistics를 계산할 때 각각의 이미지만 보는 것이 아니라 minibatch 전체에 대해 계산하므로써 생성된 이미지와 학습 이미지들이 비슷한 statistics를 갖도록 하자는게 아이디어였음. (구체적 방식은 다시 체크) PGGAN에서는 이 접근 방식을 보다 단순하게 만들면서도 다양성은 증대하는 방법을 제안함. 

이 방식은 parameter 학습이 필요하거나 새로운 hyperparameter가 필요하지 않음. 먼저 minibatch에 있는 각 spatial location에서의 feature 각각의 stardard deviation을 계산함. 이 estimates를 모든 features와 spatical locations에 대해 평균을 내고 하나의 값을 계산함. 이 값을 복사해서 모든 spatial locations와 minibatch에 대해 concat하는 방식으로 (constant) feature map을 하나 추가함. 이 레이어는 discriminator의 어느 위치에도 들어갈 수 있으나 inset it towards the end가 가장 좋은 성능을 보였음. 
Parallel work으로 Lin et al. (2017)이 이와 유사한 방식(multiple images를 discriminator에 보여주는 것이 좋은 이유)을 이론적으로 설명한 바 있음. (체크)

4. Normalization in Generation and Discriminator


GANs에서의 normalization은 signal magnitude와 competition을 제한하는 쪽에 주안점을 두어야한다고 생각함.

4.1 Equalized Learning Rate


기존의 방식들이 weight initialization에 심혈을 기울이는 것과는 달리 여기서는 초기값은 대충 표준정규분포로 주되 runtime 중 weights의 scale을 조절하는 방향을 취함.

4.2 Pixelwise Feature Vector Normalization in Generator


Generator와 Discriminator가 서로 경쟁한 끝에 발산하는 경우를 막기 위해서 generator에서 하나의 conv layer를 지날때마다 각 pixel의 feature vector를 정규화. 
이 방식이 실험 결과는 크게 바꾸지 않았지만 signal magnitude가 급격히 커지는 현상을 매우 효과적으로 없애주었다고 함. 

5. Multi-Scale Statistical Similarity for Assesing GAN results


서로 다른 GAN을 비교하는 것은 여러모로 쉽지 않음. MS-SSIM(Odena et al., 2017)과 같은 방식은 large-scale mode collapse를 잘 발견하지만 color나 texture의 작은 loss들을 발견하지 못하는 단점들이 알려져있음. 그리고 학습 데이터와의 유사한 정도를 직접적으로 고려하지 않기 때문에 문제가 있음.

PGGAN에서는 각 scale 별로 학습데이터와 생성 데이터의 local structure가 서로 유사해야한다는 intuition을 바탕으로 local image patches의 분포 간의 multi-scale statistical similarity를 확인하는 방식을 취함(Laplacian pyramid, Burt & Adelson, 1987 다시 체크).  

6. Experiments


 판타스틱함!

Stillcut from ICLR oral presentation 


Video presentation










2018년 2월 24일 토요일

Minimizing the Negative Log-Likelihood, in Korean (3)

* This is the Korean translation of the original post by will wolf under his permission. You can find the English version at his blog: here. 저자의 허락을 득하고 번역하여 옮깁니다. 

저번 글까지 하여 우리는 이제 드디어 parameter의 좋고 나쁨을 정량화할 방법에 대해 얘기해볼 때가 되었습니다. 

Loss function


지금까지는 response variable이 어떻게 생성되고 각각의 관찰값에 따라 각 분포에 대한 parameters를 어떻게 계산하는지에 대해 알아보았습니다. 자, 그럼 어떤 parameters가 좋은 것인지 어떻게 정량화할 수 있을까요?

시작하기에 앞서, 잠시 cat or dog를 예측하는 것을 상기해보겠습니다. 만약 우리가 고양이 그림을 모델에게 넣어준다면 다음의 binomial distribution가 주어졌을 때, $\phi\approx0$이도록 계산을 해야겠지요.
$$P(\text{outcome}) =
\begin{cases}
1 - \phi & \text{outcome = cat}\\
\phi & \text{outcome = dog}\\
\end{cases}$$
가장 완벽한 경우, $\phi=0$가 될 것입니다. 그리고 loss function이 우리가 얼마나 답에 가까이 갔는지 정량화해주겠지요.

Maximum likelihood estimation


앞서 글들에서 소개하였던 세 개의 분포들 각각은 $\mu,\phi,\pi$와 같은 parameter를 갖습니다. 임의의 $y$를 주면 각 분포가 현재 우리가 관찰한 값이 나올 확률을 알려주게 되지요. (예를 들어 continuous-valued random variables의 경우, 분포는 확률 밀도 함수가 되고 이 함수가 우리가 찾는 확률 값에 비례하는 어떤 값을 내뱉습니다.)

만약 $y$를 고정하고 parameter 값들이 바뀌도록 설정한다면 같은 함수가 이제는 likelihood function이 됩니다. 이 함수가 하는 일은 고정된 $y$ 값에 대해서 현재 parameter의 likelihood에 대해 알려주는 것이죠. 

위에 설명히 명확하지 않다면 아래의 예시들을 생각해보시면 됩니다:
모로코 사람 한 명이 바(bar)에 들어왔다. 그는 소매 한 짝이 없어진 축구 저지를 입고 있다. 눈에는 멍이 들었고 바지에는 피가 묻어있었다. 이 사람은 오늘 어떤 하루를 보냈을까?
  1. 집에서 책을 읽었을 것이다.
  2. 자전거 경주를 연습 중이었을 것이다.
  3. 축구 경기에서 (타 팀을 경멸하며 모두 종합격투기 선수인) 그의 친구들과 맥주를 마시며 놀았을 것이다.
우리는 현재 우리가 갖고 있는 데이터가 가장 나옴직한 parameter를 고르고 싶을 것이고, 바로 이게 maximum likelihood estimate 입니다. 수학적으로는 다음과 같이 정의할 수 있습니다:
$$\underset{\text{parameter}}{\arg\max}\ P(y\vert \text{parameter})$$
지금까지 지겹도록 얘기한 것과 같이 $y$는 분포가 받는 parameter에 따라 변합니다. 게다가 이 parameter는 $\eta$라는 항으로 정의가 되었지요. 이어 $\eta=\theta^T x$입니다. 따라서 $y$는 $\theta$와 관측된 데이터 $x$에 대한 함수이죠. 아마도 이것은 여러분이 Day 1부터 알고 있었을 기계 학습의 가장 기본적인 이치일 것입니다.

관측된 데이터는 고정되어있으므로, $\theta$만이 우리가 바꿀 수 있는 유일한 부분입니다. 이에 맞게 위의 argmax 식을 바꾸면 다음과 같습니다:
$$\underset{\theta}{\arg\max}\ P(y\vert x; \theta).$$
다만 $[0,1]$ 안의 값들을 여러 차례 곱하면 값이 매우 빠르게 작아지기 때문에 이런 현상을 방지하기 위해 log-likelihood를 사용하게 되는 것입니다. log의 성질 덕에 곱하기 연산이 더하기로 바뀌게 됩니다.

Linear regression


Gaussian 분포의 log-likelihood를 최대화 해보겠습니다. $x$와 $\theta$가 함께 $\mu$를 만든 다는 것을 기억하세요; $\theta^T x=\mu$.

\begin{align*} \log{P(y\vert x; \theta)} &= \log{\prod\limits_{i=1}^{m}P(y^{(i)}\vert x^{(i)}; \theta)}\\ &= \sum\limits_{i=1}^{m}\log{P(y^{(i)}\vert x^{(i)}; \theta)}\\ &= \sum\limits_{i=1}^{m}\log{\frac{1}{\sqrt{2\pi}\sigma}\exp{\bigg(-\frac{(y^{(i)} - \theta^Tx^{(i)})^2}{2\sigma^2}\bigg)}}\\ &= \sum\limits_{i=1}^{m}\log{\frac{1}{\sqrt{2\pi}\sigma}} + \sum\limits_{i=1}^{m}\log\Bigg(\exp{\bigg(-\frac{(y^{(i)} - \theta^Tx^{(i)})^2}{2\sigma^2}\bigg)}\Bigg)\\ &= m\log{\frac{1}{\sqrt{2\pi}\sigma}} - \frac{1}{2\sigma^2}\sum\limits_{i=1}^{m}(y^{(i)} - \theta^Tx^{(i)})^2\\ &= C_1 - C_2\sum\limits_{i=1}^{m}(y^{(i)} - \theta^Tx^{(i)})^2\\ \end{align*}
따라서 데이터와 $\theta$에 대해 log-likelihood를 최대화 하는 것은 관측된 $y$ 값과 우리가 예측한 값 사이의 negative mean squared error를 최대화 하는 것과 동치입니다. 

다만 대다수의 최적화 루틴들이 최소화를 하는 방향으로 설계되어 있으므로 편의를 위해 최소화로 바꾸기만 할 뿐이죠.

> Minimizing the negative log-likelihood of our data with respect to θ is equivalent to minimizing the mean squared error between the observed y and our prediction thereof.

Logistic regression


Bionomial distribution에 대해 위와 똑같은 방식으로 적용해봅시다.

Negative log-likelihood:
\begin{align*} -\log{P(y\vert x; \theta)} &= -\log{\prod\limits_{i = 1}^m(\phi^{(i)})^{y^{(i)}}(1 - \phi^{(i)})^{1 - y^{(i)}}}\\ &= -\sum\limits_{i = 1}^m\log{\bigg((\phi^{(i)})^{y^{(i)}}(1 - \phi^{(i)})^{1 - y^{(i)}}\bigg)}\\ &= -\sum\limits_{i = 1}^my^{(i)}\log{(\phi^{(i)})} + (1 - y^{(i)})\log{(1 - \phi^{(i)})}\\ \end{align*}
따라서 데이터와 $\theta$에 대해 negative log-likelihood를 최소화 하는 것은 관측된 $y$ 값과 우리가 예측한 값 사이의 binary cross-entropy (i.e. binary log loss)를 최소화 하는 것과 동치입니다.

> Minimizing the negative log-likelihood of our data with respect to θ is equivalent to minimizing the binary cross-entropy (i.e. binary log loss) between the observed y and our prediction of the probability thereof.

Multinomial distribution


Negative log-likelihood:
\begin{align*} -\log{P(y\vert x; \theta)} &= -\log\prod\limits_{i=1}^{m}\prod\limits_{k=1}^{K}\pi_k^{y_k}\\ &= -\sum\limits_{i=1}^{m}\sum\limits_{k=1}^{K}y_k\log\pi_k\\ \end{align*}
따라서 데이터와 $\theta$에 대해 negative log-likelihood를 최소화 하는 것은 관측된 $y$ 값과 우리가 예측한 값 사이의 categorical cross-entropy (i.e. multi-class log loss)를 최소화 하는 것과 동치입니다.

> Minimizing the negative log-likelihood of our data with respect to θ is equivalent to minimizing the categorical cross-entropy (i.e. multi-class log loss) between the observed y and our prediction of the probability distribution thereof.

Cross-entropy


전에 확률 분포에 내재한 불확실성을 정량화하기 위해 entropy를 정의했던 것과 같이, 하나의 분포로부터 다른 분포의 사건을 예측할 때 내재한 불확실성을 정량화한 것이 바로 cross-entropy입니다. 
p = {'red': .25, 'green': .45, 'blue':, .3}
q = {'red': .35, 'green': .4, 'blue':, .25}
$$(p, q) = -\sum_i p_i\log(q_i)$$

KL-Divergence


비슷한 방식으로 Kullback-Leibler Divergence도 역시 $q$를 사용하여 $p$를 근사할 때 추가적으로 생기는 불확실성을 정량화합니다.
$$D_{KL}(p, q) = H(p, q) - H(p)$$
이를 기계학습 모델들에서 잘 사용하지 않는 이유는 실제 분포 $p$를 알아야지만 계산이 가능하기 때문이죠. 보통은 $p$를 모르고 있기 때문에 사용을 할 수 없습니다 (애시당초 true $p$를 알고 싶어서 모델을 세우는 것인데 이렇게 되면 주객전도지요 ㅎㅎ).

Maximum a posteriori estimation


$\theta$가 MLE를 바탕으로 estimate될 때는 별다른 제약을 걸지 않았었습니다. 좀 더 구체적으로 얘기하자면, $\theta$가 어떤 실수 값이 나오든 상관이 없었죠 ($0, 10, -20, 2.37\times10^{36}$).

실제로는 이런 가정은 좀 비현실적이기도 하고 군더더기인 부분이기도 합니다. 보통은 $\theta$ (weights)가 유한범위 안에서 값을 갖기를 바라죠. 따라서 이를 위해 $\theta$에 prior 를 두곤 합니다. MLE가 $\underset{\theta}{\arg\max}\ P(y|x;\theta)$일 때, maximum a posteriori estimate (MAP)는 $\underset{\theta}{\arg\max}\ P(y\vert x; \theta)P(\theta)$를 계산하게 됩니다.

앞서와 마찬가지로 log를 씌운 다음 prior와 함께 joint likelihood를 풀면:
\begin{align*}
\theta_{MAP}
&= \underset{\theta}{\arg\max}\ \log \prod\limits_{i=1}^{m} P(y^{(i)}\vert x^{(i)}; \theta)P(\theta)\\
&= \underset{\theta}{\arg\max}\ \sum\limits_{i=1}^{m} \log{P(y^{(i)}\vert x^{(i)}; \theta)} + \log{P(\theta)}\\
\end{align*}
왼쪽 항은 앞서 다뤘던 것과 같고 남은 log prior 부분만 살펴보면 되겠군요.

$\theta$의 모든 항이 continuous-valued 실수값이므로 평균 0과 분산 $V$를 갖는 Gaussian 분포를 할당해보겠습니다.
$$\theta \sim \mathcal{N}(0, V)$$
\begin{align*}
\log{P(\theta\vert 0, V)}
&= \log\Bigg(\frac{1}{\sqrt{2\pi}V}\exp{\bigg(-\frac{(\theta - 0)^2}{2V^2}\bigg)}\Bigg)\\
&= \log{C_1} -\frac{\theta^2}{2V^2}\\
&= \log{C_1} - C_2\theta^2\\
\end{align*}
우리의 목표는 log-likelihood와 함께 위의 항을 같이 $\theta$에 대하여 최대화하는 것입니다. $\theta$를 포함하지 않는 항을 정리하고 나면 다음과 같고:
\begin{align*}
\log{C_1} - C_2\theta^2
&\propto - C_2\theta^2\\
&\propto C\Vert \theta\Vert_{2}^{2}\\
\end{align*}
이것이 바로 L2 regularization라는 것을 아실 수 있습니다. 게다가 $\theta$에 대해 prior distribution을 바꾸면 또다른 regularization이 가능해집니다! 예를 들면 Laplace prior는 L1 regularization을 하는 것과 동치이지요.

따라서 정리해보면, 기계학습에서 weights를 regularize한다고 함은 "no weight becomes too large" 하겠다는 것입니다. 즉 $y$를 예측할 때 너무 큰 영향을 미치지 못하게 만드는 것이죠. 통계적인 관점에서도 똑같이 이런 prior 항이 주어진 범위 내에서 값이 나오도록 제한하는 역할을 한다고 말할 수 있습니다. 이 범위가 scaling constant $C$로 표현되고 prior distribution 자체를 매계변수화합니다. 예를 들어 L2 regularization에서는 이 scaling constant가 Gaussian의 분산을 정하게 됩니다.

Going fully Bayesian


예측 모델의 주요 목표는 다음 분포를 계산하는 것입니다:
$$P(y\vert x, D) = \int P(y\vert x, D, \theta)P(\theta\vert x, D)d\theta$$
각 항을 설명해보자면:

  • $P(y|x,D)$: 학습 데이터 $D=((x^{(i)},y^{(i)}),\cdots,(x^{(m)},y^{(m)}))$와 새로운 관측값 $x$가 주어졌을 때, response $y$의 값에 대한 분포를 계산하는 것을 뜻합니다. 
    • 기계학습에서는 보통 해당 분포의 expected 값을 고르게 됩니다 (i.e. a single value, or point estimate).
  • $P(y|x,D,\theta)$: 학습 데이터 $D$, 새로운 관측값 $x$, 임의의 가능한 $\theta$ 값이 주어졌을때 (굳이 optimal이 아니더라도) $y$를  계산하는 것을 뜻합니다. 
    • 보통 주어진 모델에 대한 함수로 나타내지고 linear regression의 경우 $y=\theta^T x$와 같이 나타낼 수 있겠습니다.
  • $P(\theta|x,D)$: 학습 데이터 $D$와 새로운 관측값 $x$가 주어졌을 때 우리의 데이터를 설명할 수 있는 $\theta$ 값에 대한 분포를 계산하는 것을 뜻합니다.
    • 여기서 x는 아무런 역할을 하지 않습니다. 그저 적분을 할 때 수식적 표현이 맞도록 들어가 있을 뿐입니다. 
    • 기계학습에서는 MLE 혹은 MAP estimate을 고르게 됩니다 (i.e. a single value, or point estimate).
모든 것이 완벽하다면,

  • $\theta$에 대한 full distribution 을 계산하고,
  • 이 분포의 값들과 새로운 관측값 $x$를 가지고 $y$를 계산할 수 있습니다. 
    • NB: 여기서 $\theta$가 weights이므로 10-feature linear regression에서는 10개의 원소를 갖는 벡터가 됩니다. 신경망에서는 수백만이 되겠지요.
  • 이로부터 가능한 모든 response $y$에 대한 full distribution을 얻을 수 있습니다.


아쉽지만 복잡한 시스템들에서는 함수 형태가 계산이 쉽지 않으며 weights의 원소 개수가 매우 많기 때문에 위와 같은 계산이 불가능해집니다. 따라서 fully Bayesian modeling에서는 이런 분포들을 보통 근사를 하여 사용하지요. 전통적인 기계학습에서는 a single value (point estimate)를 할당하구요. 솔직히 썩 마음에 차지는 않지요.

Summary


이번 시리즈물이 기계학습 모델들을 이해하는데 유용한 글이었길 바랍니다. 이런 알고리즘들에 대한 보다 깊은 이해는 사실상 완전히 새로운 것은 없다는 점과 이런 알고리즘들은 보다 나은 방향으로 발전시킬 수 있는 비전을 보여주지요.

긴 글 읽어주셔서 감사합니다. 이제 수영장에서 나와서 타월 하나 집고서 import sklearn하러 떠나봅시다.
drink and towel

다음 읽을거리





2018년 2월 5일 월요일

Minimizing the Negative Log-Likelihood, in Korean (2)

* This is the Korean translation of the original post by will wolf under his permission. You can find the English version at his blog: here. 저자의 허락을 득하고 번역하여 옮깁니다. 

저번 글에 이어서 output 함수들이 왜 그런 형태로 나오는지 알아보도록 하겠습니다. 잠시 복습을 하고 넘어가시죠!

Functional form


이 글에서 다루고 있는 세 모델들은 각각 서로 다른 함수를 바탕으로 예측을 하는데요:  각각 identity function (i.e. no-op), sigmoid function, and softmax function. Keras로 output layer를 만들어보면 명확합니다:
output = Dense(1)(input)
output = Dense(1, activation='sigmoid')(input)
output = Dense(3, activation='softmax')(input)
이 단락에서는,
  • Gaussian, binomial 그리고 multinomial distributions가 같은 functional form으로 나타낼 수 있다는 것을 보이겠습니다. 
  • 이 common functional form에서 세 모델들의 output function (identity, sigmoid, softmax)가 자연스럽게 유도된다는 것을 보이겠습니다. 

마치 다음 그림과 같이 생각할 수 있겠네요. 세 가지 분포가 들어가서 세 가지 output functions이 나오는 것이죠. (그림이 이상한데? -_-; 뭐 아무튼 하나의 functional form으로 설명이 가능해서 저렇게 표현할 수 있다고 생각하면 될 듯합니다.)


bottleneck

여기서 병목에 해당하는 개념은 확률 분포의 "exponential family"가 되겠습니다.

Exponential family distributions

In probability and statistics, an exponential family is a set of probability distributions of a certain form, specified below. This special form is chosen for mathematical convenience, on account of some useful algebraic properties, as well as for generality, as exponential families are in a sense very natural sets of distributions to consider.
- 위키피디아
저(글쓴이)는 위의 설명을 그리 좋아하지 않습니다. 매우 모호하다는 점에서 특히 더 그렇습니다. 여기서 진실은 exponential functions이 우리가 잘 알고 사용하기 좋아하는 고전적인 activation과 loss functions을 하나의 틀에서 유도하는데 매우 좋은 도구라는 점입니다. 저는 "mathematical convenience, on account of some useful algebraic properties, etc." 부분에 좀 더 집중해서 "certain form"이라는 것이 괴랄한 이유로 만들어진 것이 아니란 점을 얘기하고자 합니다.

Exponential family에 속하는 분포는 다음과 같은 형태로 나타낼 수 있습니다:
$$P(y; \eta) = b(y)\exp(\eta^T T(y) - a(\eta))$$ 여기서
  • $\eta$는 분포의 canonical parameter입니다 (We will hereby work with the single-canonical-parameter exponential family form).
  • $T(y)$는 sufficient statistic입니다. (많은 경우 $T(y)=y$입니다.)
  • $a(\eta)$는 log partition function으로써 분포를 정규화하는데 쓰입니다. (더 깊은 논의는 다음 포스팅에서 보실 수 있습니다: Deriving the Softmax from First Principles.)

따라서 $T,a,b$를 정하면 분포의 family (or set)가 정해지고 이는 $\eta$로 parameterized 됩니다. 우리가 $\eta$를 바꿀 때마다 해당 familiy 안의 다른 분포를 만들 수 있겠죠. 이는 $Pr(heads)=0.6$인 동전이 $Pr(heads)=0.7$인 동전과는 다른 분포를 갖는 것으로 설명할 수 있습니다.

어때요, 참 쉽죠?

그럼 하나씩 살펴볼까요?

Gaussian distribution


편의를 위해 여기서는 단일 매계변수 형태를 다루고 있기 때문에 $\sigma^2$가 $1$로 알려져있다고 가정해보겠습니다.
$$\begin{align*}
P(y\vert \mu, \sigma^2)
&= \frac{1}{\sqrt{2\pi\sigma^2}}\exp{\bigg(-\frac{(y - \mu)^2}{2\sigma^2}\bigg)}\\
&= \frac{1}{\sqrt{2\pi}}\exp{\bigg(-\frac{(y - \mu)^2}{2}\bigg)}\\
&= \frac{1}{\sqrt{2\pi}}\exp{\bigg(-\frac{1}{2}(y^2 - 2\mu y + \mu^2)\bigg)}\\
&= \frac{1}{\sqrt{2\pi}}\exp{\bigg(-\frac{1}{2}y^2\bigg)} \cdot \exp{\bigg(\mu y - \frac{1}{2}\mu^2\bigg)}\\
\end{align*}$$ 여기서,
  • $\eta=\mu$ 
  • $T(y)=y$
  • $a(\eta) = \frac{1}{2}\mu^2$
  • $b(y) = \frac{1}{\sqrt{2\pi}}\exp{(-\frac{1}{2}y^2)}$

라고 해보겠습니다.

마지막으로 $a(\eta)$는 다음과 같습니다:
\begin{align*}
a(\eta)
&= \frac{1}{2}\mu^2\\
&= \frac{1}{2}\eta^2
\end{align*}

Binomial distribution


이항 분포에 대해 앞서 글에서 정의한 적이 있었죠? 여기서는 좀 더 단순하게 나타내서 이항 분포가 실제로 exponential familiy에 속한다는 것을 보일 것입니다. 여기서 $\phi$는 true class를 관측할 활률입니다. 즉, $Pr(cat) = 0.7 \implies \phi = 0.3$
\begin{align*}
P(y\vert \phi)
&= \phi^y(1-\phi)^{1-y}\\
&= \exp\bigg(\log\bigg(\phi^y(1-\phi)^{1-y}\bigg)\bigg)\\
&= \exp\bigg(y\log{\phi} + \log(1-\phi) - y\log(1-\phi)\bigg)\\
&= \exp\bigg(\log\bigg(\frac{\phi}{1-\phi}\bigg)y + \log(1-\phi)\bigg) \\
\end{align*}
여기서,
  • $\eta = \log\bigg(\frac{\phi}{1-\phi}\bigg)$ 
  • $T(y)=y$
  • $a(\eta) = -\log(1-\phi)$
  • $b(y) = 1$

입니다. (어? 여기서 $\phi$가 $\eta$에 대한 sigmoid 함수라는 걸 눈치채신 분?)

마지막으로 분포의 매계변수 $\eta$에 대해 $a(\eta)$를 나타내면:
$$\eta = \log\bigg(\frac{\phi}{1-\phi}\bigg) \implies \phi = \frac{1}{1 + e^{-\eta}}$$
\begin{align*}
a(\eta)
&= -\log(1-\phi)\\
&= -\log\bigg(1-\frac{1}{1 + e^{-\eta}}\bigg)\\
&= -\log\bigg(\frac{1}{1 + e^{\eta}}\bigg)\\
&= \log(1 + e^{\eta}).\\
\end{align*}


Multinomial distribution


이항 분포처럼 다항 분포를 좀 더 단순한 형태로 표현해보겠습니다. $\pi$가 $K$ classes의 class 확률들의 벡터라 할 때, (여기서 $k$가 각 class들을 의미합니다.)
$$P(y\vert \pi) = \prod\limits_{k=1}^{K}\pi_k^{y_k}$$
복잡하게 보일 수 있지만 사실 저 수식이 의미하는 바는 $Pr(y=k)$가 class $k$에 대한 확률이라는 뜻입니다. 예를 들어,
p = {'rain': .14, 'snow': .37, 'sleet': .03, 'hail': .46}
일 때, 다음과 같이 계산하면 된다는 말이죠:
\begin{align*}
\Pr(y = \text{snow} = [0, 1, 0, 0])
&= (.14^0 * .37^1 * .03^0 * .46^0)\\
&= .37\\
\end{align*}
다시 exponential family 형태로 돌아가서 확장해보면:
\begin{align*}
P(y\vert \pi)
&= \prod\limits_{k=1}^{K}\pi_k^{y_k}\\
&= \exp\bigg(\sum\limits_{k=1}^{K}y_k\log{\pi_k}\bigg)\\
&= \exp\bigg(\sum\limits_{k=1}^{K-1}y_k\log{\pi_k} + \bigg(1 - \sum\limits_{k=1}^{K-1}y_k\bigg)\log\bigg(1 - \sum\limits_{k=1}^{K-1}\pi_k\bigg)\bigg)\\
&= \exp\bigg(\sum\limits_{k=1}^{K-1}y_k\log{\pi_k} - \bigg(\sum\limits_{k=1}^{K-1}y_k\bigg) \log(\pi_K) + \log(\pi_K)), \quad \text{where}\ \pi_K = 1 - \sum\limits_{k=1}^{K-1}\pi_k\\
&= \exp\bigg(\sum\limits_{k=1}^{K-1}\log\bigg(\frac{\pi_k}{\pi_K}\bigg) y_k + \log(\pi_K)\bigg)
\end{align*}
여기서,
  • $\eta = \log\bigg(\frac{\pi_k}{\pi_K}\bigg)$ 
  • $T(y)=y$
  • $a(\eta) = -\log(\pi_K)$
  • $b(y) = 1$

마지막으로,
\begin{align*}
\eta_k
  &= \log\bigg(\frac{\pi_k}{\pi_K}\bigg) \implies\\
\frac{\pi_k}{\pi_K}
  &= e^{\eta_k} \implies\\
\sum\limits_{k=1}^K \frac{\pi_k}{\pi_K}
  &= \sum\limits_{k=1}^K e^{\eta_k} \implies\\
\frac{1}{\pi_K}\sum\limits_{k=1}^K \pi_k
  &= \sum\limits_{k=1}^K e^{\eta_k} \implies\\
\frac{1}{\pi_K} \cdot 1
  &= \sum\limits_{k=1}^K e^{\eta_k} \implies\\
\pi_K
  &= \frac{1}{\sum\limits_{k=1}^K e^{\eta_k}}
\end{align*}
이고, 두 번째 줄에 마지막 결론을 껴넣어주면:
\begin{align*}
\frac{\pi_k}{\frac{1}{\sum\limits_{k=1}^K e^{\eta_k}}}
  &= e^{\eta_k}\ \implies\\
\pi_k
  &= \frac{e^{\eta_k}}{\sum\limits_{k=1}^K e^{\eta_k}}
\end{align*}
(짜잔! $\pi_k$가 $\eta_k$에 대한 softmax function이 나오네요!)

마지막으로 $a(\eta)$를 정리하면 아래와 같습니다:
\begin{align*}
\frac{\pi_k}{\frac{1}{\sum\limits_{k=1}^K e^{\eta_k}}}
  &= e^{\eta_k}\ \implies\\
\pi_k
  &= \frac{e^{\eta_k}}{\sum\limits_{k=1}^K e^{\eta_k}}
\end{align*}
\begin{align*}
a(\eta)
&= -\log(\pi_K)\\
&= \log(\pi_K^{-1})\\
&= \log\Bigg(\frac{\sum\limits_{k=1}^K e^{\eta_k}}{e^{\eta_K}}\Bigg)\\
&= \log\Bigg(\sum\limits_{k=1}^K e^{\eta_k}\Bigg).\\
\end{align*}

* (편집자 주) 수학을 따라 오다가 길을 잃은 분들을 위해 각 모델에서 우리가 관심있는 response variable들을 $\eta$에 대해 하나로 모아 정리해보면 아래와 같습니다: 
Linear regression (Gaussian distribution): $\mu = \eta$

Logistic regression (Binomial distribution): $\phi = \frac{1}{1 + e^{-\eta}}$

Softmax regression (Multinomial distribution): $\pi_k = \frac{e^{\eta_k}}{\sum\limits_{k=1}^K e^{\eta_k}}$

Generalized linear models


각 모델은 output으로 response variable을 뱉습니다. 이 response variable들이 어떤 (exponential family) 분포를 따라 퍼져있겠죠. 그러나 이 분포의 canonical parameter 즉 우리가 넣는 값은 관측마다 달라질 것입니다.

cat or dog를 예측하는 logistic regression 모델을 생각해보겠습니다. 우리가 고양이 그림을 넣으면 주어진 분포에 따라 "고양이"라는 값이 나올 것입니다.
$$P(\text{outcome}) =
\begin{cases}
1 - \phi & \text{outcome = cat}\\
\phi & \text{outcome = dog}\\
\end{cases}$$
우리가 개 그림을 넣으면 마찬가지로 같은 분포에 따라 "개"가 튀어나오겠죠.

당연하지만 $\phi$ 값은 각각의 경우마다 항상 달라야합니다. 앞선 경우에 대해서는  모델의 $\phi$ 값이 작아서 $1-\phi \approx 1$의 확률로 고양이를 뱉어내야겠지만 뒤의 경우에 대해서는 $\phi$ 값이 커서 "개"라는 출력이 $\phi \approx 1$의 확률로 나올 수 있도록 해야겠죠.

* (편집자 주) 이 부분이 헷갈리신다면 정상입니다. 뭐 이렇게 어렵게 써두었는지... 그냥 $\phi$가 canonical parameter $\eta$를 변수로 가지는 값이라고 생각하시면 됩니다. 예를 들어 신경망같은 parametric 개/고양이 판별기 모델에 고양이 혹은 개 그림을 (즉 다른 input들을) 넣으면 나올 output probability가 그때그때 다르죠? 이 얘기를 하려는 겁니다. 

그러면 각 input에 대해 다음을 생각해보겠습니다:

  • $y_i \sim \mathcal{N}(\mu_i, \sigma^2)$일 때, Linear regression에서 $\mu_i$란? 
  • $y_i \sim \text{Binomial}(\phi_i, 1)$일 때, logistic regression에서 $\phi_i$란?
  • $y_i \sim \text{Multinomial}(\pi_i, 1)$일 때, softmax regression에서 $\pi_i$란?

여기서 $i$라는 인덱스가 새로 붙은 것이 보이시죠. 이 $i$ 덕에 위에서 설명하고자 한 dynamic이 좀 더 명백해집니다. 즉, 주어진 모델에서 각 입력에 따라 해당하는 canonical parameter가 정해지고 이 녀석이 response variable의 분포에 영향을 미치게 됩니다. 예를 들면 logistic regression 모델에서 고양이 그림을 보게 되면 $\phi_i\approx0$이 되도록 해야겠다는 말을 좀 더 복잡하게 한 것입니다.

그럼 10-feature input $x$에서 이런 canonical parameter로 어떻게 보내면 될까요? 가장 간단하게 linear combination을 생각해볼 수 있습니다:
$$\eta = \theta^Tx$$ * (편집자 주) Keras code에 Dense layer 하나 붙은 모델인 것만 보셔도 짐작하실 수 있습니다. 


Linear regression


$\eta = \theta^Tx=\mu_i.$ 이것이 바로 우리가 정규 분포를 만들 때 필요한 변수입니다.
> The identity function (i.e a no-op) gives us the mean of the response variable. This mean is required by the normal distribution, which dictates the outcomes of the continuous-valued target $y$.

Logistic regression


$\eta = \theta^Tx = \log\bigg(\frac{\phi_i}{1-\phi_i}\bigg).$ $\phi_i$에 대해 문제를 풀어야 하겠습니다. $\phi_i = \frac{1}{1 + e^{-\eta}}$였던 것 기억하시죠?
> The sigmoid function gives us the probability that the response variable takes on the positive class. This probability is required by the binomial distribution, which dictates the outcomes of the binary target $y$.

결국 $\phi_i$라는 함수가 하는 녀석은 우리가 앞서 소개했던 내일의 날씨 예측하는 날씨 분포가 하는 일과 같습니다.
p = {'rain': .14, 'snow': .37, 'sleet': .03, 'hail': .46}
* (편집자 주) 그러니까 날씨 분포의 경우 마치 lookup table처럼 각 input $x$에 대해 딱 내뱉는 확률 값이 정해져있는 일대일 대응 함수인데, $\phi_i$의 경우는 canonical parameter $\eta=\theta^Tx$로 표현되는 함수라는 말입니다. 

Softmax regression


$\eta = \theta^Tx = \log\bigg(\frac{\pi_k}{\pi_K}\bigg).$ $\pi_i$는 벡터이기 때문에 $\pi_i$에 대해 풀기 위해서 각 $\pi_{k,i}$에 대해 문제를 풀어야합니다.
이 역시도 위에서 했었죠: $\pi_{k, i} = \frac{e^{\eta_k}}{\sum\limits_{k=1}^K e^{\eta_k}}.$ 바로 softmax function입니다.
> The softmax function gives us the probability that the response variable takes on each of the possible classes. This probability mass function is required by the multinomial distribution, which dictates the outcomes of the multi-class target $y$.

좋습니다 이제 다 살펴봤네요. 흠 그런데 왜 하필 linear model, $\eta = \theta^Tx$이어야 했을까요? 앤드류 응 교수님 말을 차용하자면 이것은 "모델 디자인" 혹은 "선택"의 문제입니다. 여기서 선형 조합이 자주 사용되는 이유를 굳이 꼽자면:
  • 아마도 선형 조합(linear combination)이 canonical parameter에 대한 각 feature에 영향을 줄 수 있는 가장 쉬운 방법일 것이기 때문이다. 
  • 선형 조합이 단순히 $x$뿐만 아니라 $x$에 대한 함수에 대해서도 $\eta$에 대해 선형으로 변화한다고 하면 좀 더 복잡한 형태를 만들 수 있다. 즉, 우리는 모델을 $\eta = \theta^T\Phi(x)$와 같이 쓸 수 있고, 여기서 $Phi$는 우리의 feature에 대한 복잡한 변형(transformation)을 주는 operator를 의미한다. 이 부분이 선형 조합의 단순함을 조금은 덜하게 만들어준다고 할 수 있다. 

Loss function


이제 지금까지 각 response variable이 어떤 식으로 만들어지는지 살펴봤습니다. 그리고 분포들의 parameters가 각 input에 대해 어떻게 계산되는지도 보았죠. 그러면 뭐가 남았을까요? 맞습니다. 이제 어떻게 하면 어떤 parameters가 좋은지 정량화할 수 있을지가 궁금하실겁니다? (음? ㅋㅋ)

자! 이 부분도 매우매우 재미있지만 이번에도 역시 글이 매우 길어졌고 제 글 체력도 다하였기에 다음 글에서 이어가도록 하겠습니다.

그러면! 다음 글에서 뵙겠습니다. (To be continued)

다음 읽을거리





Minimizing the Negative Log-Likelihood, in Korean (1)

* This is the Korean translation of the original post by will wolf under his permission. You can find the English version at his blog: here. 저자의 허락을 득하고 번역하여 옮깁니다. 

우리가 자주 쓰는 loss function들이 어떻게 나오게 되었는지, 예들 들자면 cross-entropy error와 Euclidean error는 어디서 유래한 것인지를 알려주는 좋은 글이 있어 공부할 겸 번역을 해보고자 합니다. 최대한 원 저자의 글에 가깝게 번역하려 했으며 번역을 할 때 필연적으로 생기는 어색한 표현을 피하기 위해 제가 먼저 내용을 다 소화한 이후 의역을 하였습니다. 이 외에 제가 좀 더 자세히 덧붙여 설명을 하고 싶은 부분들은 추가하되 (* 편집자 주, 빨간색)으로 명시해두겠습니다. (* 편집자 주) 2017년 6월에 시작한 글을 이제야 끝내다니... ㅎㅎ밀린 숙제하는 느낌이네요;; 졸업하니 정말 좋다!!!ㅋㅋㅋ

Minimizing the Negative Log-Likelihood, in Korean (:p)


저(글쓴이)는 Kaggle에서부터 기계학습에 대한 공부를 시작했습니다.
"Kaggle에는 데이터도 있고 모델 (즉, estimator) 그리고 loss function to optimize가 있어서 공부하기가 좋았고 여기(Kaggle)에서 많은 것을 배울 수 있었습니다."
그 중 몇 가지를 꼽아보자면, "regression model은 continuous-valued real numbers를 예측하는데 쓰이고, classification model들은 '빨강' '초록' '파랑' 등을 예측하는데 쓰인다는 것", "보통 regression에서는 mean absolute error를 쓰며 classification에서는 cross-entropy loss를 사용한다는 것", "loss 함수들을 줄이기 위해 stochastic gradient descent를 사용한다는 것" 등을 자연스래 배웠고, 마지막으로 이런 model들을 fit하고 싶다면 그저 sklearn 라이브러리를 사용하면 된다는 것도 알게 되었습니다. 

(최소한 기술적인 측면에서는) 이 정도만 잘 알아도 데이터 사이언티스트로써 혹은 취업을 위해서도 충분했습니다. 산업 현장에서는 이런 off-the-shelf algorithm만으로도 회사의 이익을 매우 쉽게 끌어올릴 수 있지요.
"그래 이 정도면 충분해, 자동차 경주에서 이기고 있는 선수가 굳이 자동차가 어떻게 만들어지는지까지 알 필요는 없잖아?"
"scikit-learn fit and predict," 하는 것이 익숙해졌을 무렵 저는 통계를 슬슬 공부하기 시작했습니다. 두 가지 분야가 서로 겹치는 것이 많다는 것을 알고는 있었지만, 여전히 뭔가를 분석할 때는 두 분야를 서로 다른 평행한 sub-fields로 적용하곤 했습니다. 그러니까 classification model을 만들 때는 scikit-learn을 사용하고 signup counts를 추측(infer)할 때는 Poisson distribution and MCMC를 사용하는 식으로 말이죠. 

하지만 교과서 공부, 논문 읽기, 소스 코드 읽기 및 쓰기, 블로그 작성 등 기계 학습에 대해 깊이 파고 들면서 내가 한 일들을 묘사하는데 사용되는 몇몇 용어들이 생각보다 이해하기 어렵다는 것을 알게 되었습니다. 예를 들자면 categorical cross-entropy loss가 무엇인지, 어떤 일을 하며 어떤 식으로 정의되는지는 이해했지만 도대체 "왜 이런 녀석들을 negative log-likelihood라 부르는 것인가?"와 같은 의문들이 생기기 시작했습니다.

시간이 지나 이제는 위 질문에 대해 적어도 두 가지 정도는 알게 되었습니다:

  1. 우리가 "기계 학습"이라 부르는 기술들(classification and regression models)은 거의 대부분 통계를 기반으로 하고 있다. 때문에 용어들이 두 분야에서 혼용되고 있다.
  2. 대부분의 용어가 새로 만들어진 것이 아니다. 

이 글에서는 제가 깨달은 사실을 바탕으로 우리가 잘 알고 있고, 자주 사용하며, 어떻게 사용하는지 알고 있는 세가지 모델들이 수학적으로 어떤 역할을 하는 것인지 설명하고자 합니다. 기본적으로 독자들이 기계학습과 통계학 분야의 개념들에 대해 익숙하다는 가정 하에 글을 쓸 것이며 두 분야 사이의 연관성에 대해 더욱 깊은 이해를 위해 서서히 파고들 생각입니다. 수학이 들어가긴 하지만 딱 필요한만큼만 사용할 것이고 유도의 대부분은 결과없이 건너 뛸 수도 있습니다.

어떤 predictive model을 제품화할 때는, import sklearn으로 다른 사람이 만들어 둔 모델을 사용하는 것이 최고의 방법이자 보통 우리가 알고 있는 방식입니다. 그렇기에 이 글은 여기서 시작해서 결국에는 다시 이 지점으로 돌아올 것입니다. 다만 이전과 다른 점은 그 밑바닥을 잘 알고 사용할 수 있겠습니다. (글쓴이는 이 과정을 마치 수영장에서 다이빙 하고, 밑바닥을 찍고, 다시 표면으로 올라오는 모습과 비슷하게 생각했는지 같은 은유를 수차례 사용합니다.) Lemma들은 굵은 글씨체로 작성되어 있습니다.

먼저 우리가 앞으로 다룰 세 개의 주요 모델들을 만나보시겠습니다. 편의를 위해 코드는 Keras로 통일합니다.

Linear regression with mean squared error

input = Input(shape=(10,))
output = Dense(1)(input)

model = Model(input, output)
model.compile(optimizer=_, loss='mean_squared_error')

Logistic regression with binary cross-entropy loss

input = Input(shape=(10,))
output = Dense(1, activation='sigmoid')(input)

model = Model(input, output)
model.compile(optimizer=_, loss='binary_crossentropy')

Softmax regression with categorical cross-entropy loss

input = Input(shape=(10,))
output = Dense(3, activation='softmax')(input)

model = Model(input, output)
model.compile(optimizer=_, loss='categorical_crossentropy')

다음으로 response variable, functional form, loss function, loss function + regularization term 이렇게 네 가지 주요 요소들이 있는데요 앞으로 세 가지 모델들에 대해 각 요소가 어떤 통계적인 의미를 지니는지 알아보도록 하겠습니다 (수영장 밑바닥에서 한 계단씩 올라가겠습니다).

잠깐! 완전히 잠수하기 전에 준비운동부터 해야겠죠? 몇 가지 중요한 개념들에 대해 정의하고 넘어가겠습니다.

Random variable


저(글쓴이)는 random variable을 "여러가지 다른 값들을 가질 수 있는 것"이라고 정의합니다.

  • "The tenure of despotic rulers in Central Africa" is a random variable. It could take on values of 25.73 years, 14.12 years, 8.99 years, ad infinitum; it could not take on values of 1.12 million years, nor -5 years.
  • "The height of the next person to leave the supermarket" is a random variable.
  • "The color of shirt I wear on Mondays" is a random variable. (Incidentally, this one only has ~3 distinct values.)


Probability distribution


확률 분포란 random variable이 갖는 값을 관측할 likelihood에 대한 일종의 lookup table이라 할 수 있습니다. 주어진 variable이 {비, 분, 진눈깨비, 우박} 중 하나의 값을 가진다고 할 때, 다음과 같이 probability distribution으로 나타낼 수 있습니다:
p = {'rain': .14, 'snow': .37, 'sleet': .03, 'hail': .46}
당연하지만, 모든 값의 합은 1이어야 하지요.

  • 확률 질량 함수는 이산 값을 갖는 random variable 확률 분포다. 
  • 확률 밀도 함수는 연속 값을 갖는 random variable의 확률 분포를 주는 함수다. 
  • 여기서 "주는"이라고 표현한 까닭은 이 함수 스스로는 lookup table이 아니기 때문이다. 즉 값이 [0,1] 범주 안에서 주어진 random variable에 대해 $Pr(X=0.01), Pr(X=0.001),Pr(X=0.0001),~etc.$를 정의할 수 없다. 
    • 대신 일정 범위  안에서 어떤 값을 관측할 확률을 알려줄 수 있는 함수를 하나 정의하여 사용할 수 있다: e.g. $Pr(0.01<X<0.4)$
    • 이 것이 확률 밀도 함수이며 $Pr(0\leq X \leq 1)=1$을 만족한다. 

Entropy


엔트로피는 주어진 결과에 도달할 수 있는 방법의 가짓수를 정량화 해줍니다. 8명의 친구들이 두 대의 택시를 나눠타고 브로드웨이 쇼를 보러 가는 것을 상상해보죠. 다음과 같이 두 가지의 시나리오를 생각해보겠습니다:
  • 네 명씩 택시를 탄다:
# fill the first, then the second
assignment_1 = [1, 1, 1, 1, 2, 2, 2, 2]

# alternate assignments
assignment_2 = [1, 2, 1, 2, 1, 2, 1, 2]

# alternate assignments in batches of two
assignment_3 = [1, 1, 2, 2, 1, 1, 2, 2]

# etc.
  • 모든 친구들이 하나의 택시에 어떻게든 우겨 탄다:
assignment_1 = [1, 1, 1, 1, 1, 1, 1, 1]
두 번째 경우보다 첫 번째 경우가 가능한 경우의 수가 많기 때문에 첫 번째 결과(outcome)가 더 높은 엔트로피 값을 갖게 됩니다.

More explicitly,


엔트로피를 확률 분포에 대해 계산을 해보면 다음과 같습니다:
$$H(p)=-\sum_{i=1}^n p_i \log p_i$$
이 때,
  • 총 서로 다른 n개의 이벤트가 존재한다. 
  • 각 이벤트 $i$는 $p_i$의 확률을 갖는다. 

엔트로피는 가능한 이벤트들에 대한 weighted-average log probability이고, (이는 수식에서 더 명백히 알 수 있는데) 분포에 내재한 불확실성을 측정하는 방법이라 할 수 있습니다. 즉, 어떤 이벤트에 대해 엔트로피가 높다는 것은 해당 결과값을 얻을 것이라는 믿음에 대한 확실성이 덜하다는 것을 뜻하죠.

위에서 언급한 확률 분포에 대해 엔트로피를 계산해보겠습니다.
p = {'rain': .14, 'snow': .37, 'sleet': .03, 'hail': .46}

def entropy(prob_dist):
    return -sum([ p*log(p) for p in prob_dist.values() ])

In [1]: entropy(p)
Out[1]: 1.1055291211185652
비교를 위해 두 개의 분포를 더 만들어서 각각의 엔트로피들을 계산해보겠습니다.
p_2 = {'rain': .01, 'snow': .37, 'sleet': .03, 'hail': .59}

p_3 = {'rain': .01, 'snow': .01, 'sleet': .03, 'hail': .95}

In [2]: entropy(p_2)
Out[2]: 0.8304250977453105

In [3]: entropy(p_3)
Out[3]: 0.2460287703075343
첫 번째 분포에서 우리는 내일 날씨가 어떨 지에 대해 가장 확신이 없습니다. 이에 맞게 엔트로피도 가장 높습니다. 세 번째 분포의 경우 내일의 날씨가 우박일 것이라는 것에 가장 확신을 가질 수 있을 것이고 엔트로피도 역시 작은 것을 볼 수 있습니다.

마지막으로 택시 예화에서도 마찬가지로 오직 한 가지 경우만 가능한 분포에 비해 여러 갈래로 이벤트가 생길 수 있는 분포에 대해 엔트로피 값이 낮다는 것을 알 수 있습니다.

이제 준비운동을 마쳤으니 수영장에 들어가야겠지요. 그럼 가장 바닥부터 찍고 다시 수면으로 올라가보겠습니다.

Response variable


크게 볼 때 우리가 다룰 모델은 다음과 같이 생겼다고 할 수 있습니다. 즉, 아래 그림에서 입력을 받아 출력을 하는 다이아몬드에 해당합니다:

simple input/output model

모델들은 예측해야 하는 response variable 즉 $y$의 종류에 따라 바뀌게 되는데요
  • Linear regression은 연속된 실수 값을 예측. temperature라고 하자. 
  • Logistic regression은 이진 값을 예측. cat or dog라고 하자. 
  • Softmax regression은 multi-class label을 예측. red or green or blue라고 하자. 
각 모델에서 response variable은 서로 다른 값들을 가질 수 있습니다. 이들이 바로 random variables입니다. 그렇다면 각각의 random variable은 어떤 확률 분포를 갖을까요?
  • temperature는 true mean $\mu\in(-\infty,\infty)$와 true variance $\sigma^2\in(-\infty,\infty)$를 갖는다. 
  • cat or dog는 고양이 혹은 강아지를 값으로 값는다. 공평한 동전 던지기가 언제나 $Pr(Head)=0.5$이듯이 각 결과에 대한 likelihood는 시간에 따라 변하지 않는다. 
  • red or green or blue는 빨강, 초록, 파랑 중 하나의 값을 갖는다. 마치 공평한 육면체 주사위가 그렇듯이 시간에 따라 likelihood는 바뀌지 않는다. 
이런 가정들은 사실 너무 당연해서 좀 너무 진부하기까지 하지만 앞으로 얘기할 때 중요하게 사용되니 기억해둡시다.

Maximum entropy distributions


"Uber의 연간 수익"이라는 연속 값 random variable을 생각해보겠습니다. 마치 temperature와 같이 이 random variable 역시 true mean $\mu\in(-\infty,\infty)$와 true variance $\sigma^2\in(-\infty,\infty)$를 갖습니다. 당연하지만 두 경우에 대한 평균과 분산은 서로 다르겠죠. 다음과 같이 가상으로 10개의 값들을 관측했다고 해보겠습니다:
ubertemperature
-100-50
-805
-2056
565
1562
-1063
2260
1278
70100
100-43
이를 그려보면 다음과 같습니다:
temperature random variable
uber random variable
우리는 각 random variable에 대해 실제 확률 분포가 어찌 생겼는지는 모릅니다. 전반적 "형태"도 모르고 그 형태를 제어하는 parameters도 모릅니다. 이럴 때는 어떻게 모델을 정해야할까요? 사실 통계학의 정수가 바로 여기에(미지의 값들을 추측하는 것) 있습니다.

자, 초기 모델을 정하기 위해 다음의 두 가지를 염두에 두어야합니다:

  • 최대한 보수적이어야 합니다. 우리는 "Uber의 연간 수익"에 대해 고작 10개의 값만을 보았을 뿐입니다. 아직 관측되지 않았다고 해서 다음 스무 개의 값들이 $[-60,-50]$ 사이의 범위에서 나올 수도 있다는 사실을 간과하고 싶지는 않겠죠.
  • 각각에 대하여 동일한 가정(continuous)을 했기 때문에 두 random variables 모두에 대하여 같은 확률 분포 "모양"을 가정해야합니다. 

이에 따라 매우 진부하지만 위에서 정의한 제약 조건들을 만족하는 가장 보수적인 분포를 사용하겠습니다. 이 것이 바로 maximum entropy distribution입니다.

* (편집자 주) 그냥 이렇게 넘어가면 사실 왜 maximum entropy distribution을 사용해야하는지 잘 와닿지 않을 수 있으니 제가 첨언을 좀 해보겠습니다. 

통계나 정보 이론에서 maximum entropy probability distribution은 이름이 의미하듯 분포가 갖는 엔트로피 값이 해당 class의 확률 분포들이 가질 수 있는 최대 엔트로피 값과 최소한 같거나 큽니다. 


무슨 말인고 하니, 만약 우리가 어떤 모델을 세울 때 해당 데이터에 대해 알고 있는 정보가 적다면 잘못된 선험적 정보를 부지불식간에 모델에 넣지 않도록 주의를 기울여야 한다는 것입니다. (maximum entropy의 원리에 따라) 모델을 정할 때 해당 데이터가 어떤 class에 속한다는 정보 외에 분포에 대한 어떠한 정보도 없을 때는 가장 기본적으로 최소한의 정보만을 사용하여(largest entropy) 분포를 정해야할 것입니다. 


바로 여기에 해당하는 분포가 maximum entropy distribution인 것이죠. 이 외에도 많은 physical systems이 시간이 지나면서 점차 maximal entropy configuration을 향하기 때문에서라도 maximum entropy distribution으로 초기 모델을 정하는 것이 여러 모로 장점이 있습니다.

temperature(continuous-valued distribution)에 대한 maximum entropy distribution은 Gaussian 분포입니다. 가우시안 분포의 확률 밀도 함수는 다음과 같죠:
$$P(y\vert \mu, \sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2}}\exp{\bigg(-\frac{(y - \mu)^2}{2\sigma^2}\bigg)}$$
cat or dog에 대한 maximum entropy distribution은 binomial 분포입니다. 이항 분포의 확률 밀도 함수는 (for a single observation) 다음과 같습니다:
$$P(\text{outcome}) =
$\begin{cases}
1 - \phi & \text{outcome = cat}\\
\phi & \text{outcome = dog}\\
\end{cases}$$ (여기서 positive event에 대한 확률을 $\phi$로 표기하였습니다.)

마지막으로 red or green or blue에 대한 maximum entropy distribution은 multinomial distribution입니다. 다항 분포의 확률 밀도 함수는 다음과 같습니다:
$$P(\text{outcome}) =
\begin{cases}
\phi_{\text{red}} & \text{outcome = red}\\
\phi_{\text{green}} & \text{outcome = green}\\
1 - \phi_{\text{red}} - \phi_{\text{green}} & \text{outcome = blue}\\
\end{cases}$$
이렇게 각 모델에 대한 "maximun entropy distribution"가 위와 같이 유도된다는 것을 은근슬쩍 구렁이 담넘어 가듯이 지나갔지만 사실 이 부분은 Lagrange multipliers로 매우 명료하게 설명하는 것이 가능합니다. 이 부분은 해당 글의 범위를 넘어서거니와 이 글의 목적을 명확히 하는데 오히려 방해가 될 소지가 있기에 글쓴이가 의도적으로 내용을 생략하였습니다.

* (편집자 주) 실제로도 매우 쉽습니다. 다음에 기회가 되면 포스팅을 하도록 하겠습니다. 예를 들어 가우시안 분포는 전체 실수 선 $x\in(-\infty, \infty)$를 모두 포괄하되 유한한 평균과 분산을 갖는 모든 확률 분포에 대한 maximum entropy distribution입니다. 이렇게 maximum entropy distribution을 유도하다보면 가우시안 분포의 적분식이 왜 그렇게 생겼는지 알 수 있습니다. 재밌겠죠!

마지막으로 "Uber의 연간 수입"과 temperature 값들의 실제 분포가 가우시안으로 표현될 수 있다는 가정을 사용하긴 하였으나 사실 각각에 대해 약간씩 다른 가우시안입니다. 이는 각 random variable이 서로 다른 true mean과 variance를 갖기 때문입니다. 이 값들은 각 가우시안 분포들이 더 키가 크거나 옆으로 퍼지거나 혹은 좌우로 shift되는 정도를 다르게 조정하게 됩니다.


Functional form


이 글에서 다루고 있는 세 모델들은 각각 서로 다른 함수를 바탕으로 예측을 하는데요:  각각 identity function (i.e. no-op), sigmoid function, and softmax function. Keras로 output layer를 만들어보면 명확합니다:
output = Dense(1)(input)
output = Dense(1, activation='sigmoid')(input)
output = Dense(3, activation='softmax')(input)
이 단락에서는,
  • Gaussian, binomial 그리고 multinomial distributions가 같은 functional form으로 나타낼 수 있다는 것을 보이겠습니다. 
  • 이 common functional form에서 세 모델들의 output function (identity, sigmoid, softmax)가 자연스럽게 유도된다는 것을 보이겠습니다. 

마치 다음 그림과 같이 생각할 수 있겠네요. 세 가지 분포가 들어가서 세 가지 output functions이 나오는 것이죠. (그림이 이상한데? -_-; 뭐 아무튼 하나의 functional form으로 설명이 가능해서 저렇게 표현할 수 있다고 생각하면 될 듯합니다.)


bottleneck

여기서 병목에 해당하는 개념은 확률 분포의 "exponential family"가 되겠습니다.

자! 이 부분이 사실 매우매우 재미있는 부분이지만 아쉽게도 글이 매우 길어지기도 했고 글을 하루에 쓸 수 있는 양이 있으니(..orz) 다음 글에서 이어가도록 하겠습니다. (드라마도 아니고....준비 운동하다 시간이 다 갔네요..ㅋㅋ 얼른 돌아오겠습니다. )

그러면! 다음 글에서 뵙겠습니다. (To be continued)

다음 읽을거리