ML basics - Linear Models for Classification

28 minute read

선형분류의 목표와 방법들Permalink

분류(classification)의 목표

  • 입력벡터 xK개의 가능한 클래스 중에서 하나의 클래스로 할당하는 것

분류를 위한 결정이론

  • 확률적 모델 (probabilistic model)
    • 생성모델 (generative model): p(x|Ck)p(Ck)를 모델링한다음 베이즈 정리를 사용해서 클래스의 사후 확률 p(Ck|x)를 구한다. 또는 결합확률 p(x,Ck)을 직접 모델링할 수도 있다.
    • 식별모델 (discriminative model): p(Ck|x)를 직접적으로 모델링한다.
  • 판별함수 (discriminant function): 입력 x을 클래스로 할당하는 판별함수(discriminant function)를 찾는다. 확률값은 계산하지 않는다.

판별함수 (Discriminant functions)Permalink

입력 x을 클래스로 할당하는 판별함수(discriminant function)를 찾고자 한다. 여기서는 그러한 함수 중 선형함수만을 다룰 것이다. 두 개의 클래스

선형판별함수는 다음과 같다.

y(x)=wTx+w0

- w: 가중치 벡터 (weight vector)
- w0: 바이어스 (bias)

y(x)0 인 경우 이를 C1으로 판별하고 아닌 경우 C2으로 판별한다.

결정 경계 (decision boundary)

- y(x)=0
- D1차원의 hyperplane (xD차원의 입력벡터일 때)

y(x)=0을 만족시키는 x의 집합을 결정 경계라고 함.

결정 경계면 위의 임의의 두 점 xAxB

- y(xA)=y(xB)=0
- wT(xAxB)=0 => w는 결정 경계면에 수직

임의의 두 점 xAxB에 대해서 위의 식이 성립하기 때문에, Decision Boundary에 있는 모든 두 개의 점에 대해서 벡터 w는 결정 경게면에 수직임.

원점에서 결정경계면까지의 거리

벡터 w를 원점에서 결정 경계면에 대한 사영(projection)이라고 하자.

w의 단위벡터 (ww)에 r을 곱했을때 projection vector (w)가 됨. 이 r를 구하면 결정경계와 원점의 거리가 됨.

projection vector (w)가 결정경계 위에 있기 때문에 y(w)=0가 됨.

wTw은 l2 norm의 제곱 (w22)이다.

 rww=w y(w)=0 wTw+w0=0 wTwwr+w0=0 wr+w0=0 r=w0w

따라서 w0은 결정 경계면의 위치를 결정한다.

- w0<0이면 결정 경계면은 원점으로부터 w가 향하는 방향으로 멀어져있다.
- w0>0이면 결정 경계면은 원점으로부터 w의 반대 방향으로 멀어져있다.

여기서 중요한 부분은 결정 경계의 위치가 어디에 있느냐임. 헷갈릴 수도 있지만. bias 값이 결정경계면의 위치를 결정하는 파라미터라는 것임.

w-and-decision-boundary

예제: y(x1,x2)=x1+x21

또한 y(x)값은 x와 결정 경계면 사이의 부호화된 거리와 비례한다.

xx이 벡터는 w와 방향이 같지만 길이는 r인 단위벡터임. 이것을 다시 써보면 xx=rww라는 말임.

x=x+rww 여기에 wT를 곱하고 bias인 w0을 더해줌.

wTx+w0=wTx+w0+rwTww

x이 결정경계 위에 있기 때문에 x+w0 이 부분이 0이 됨. 또한 wTwww이 됨. 왼쪽에 있는 항은 y(x)이 됨.

따라서 y(x)=rw이 됨. r 곱하기 w의 l2 norm.

다시 정리하면, r=y(x)w이 되는 것임.

임의의 한 점 x의 결정 경계면에 대한 사영을 x이라고 하자.

x=x+rww r=y(x)w

좀 전에는 bias에 의해 결정경계면의 위치가 결정되었다면, 이번에는 y(x)에 의해 x의 위치가 결정됨.

- y(x)>0이면 x는 결정 경계면을 기준으로 w가 향하는 방향에 있다.
- y(x)<0이면 x는 결정 경계면을 기준으로 w가 향하는 방향에 있다.
- y(x)의 절대값이 클 수록 더 멀리 떨어져 있다.

가짜입력(dummy input) x0=1을 이용해서 수식을 단순화

dummy input을 사용했다는 의미로 tilde 심볼을 사용함.

- w~=(w0,w)
- x~=(x0,x)
- y(x)=w~Tx~

geometry-of-a-linear-discriminant-function

다수의 클래스Permalink

yk(x)=wkTx+wk0

각각의 클래스 k 마다 weight vector인 wk를 학습해야 함.

k=1,,K

위와 같은 판별함수는 jk일 때 yk(x)>yj(x)를 만족하면 x를 클래스 Ck로 판별하게 된다.

분류를 위한 최소제곱법 (Least squares for classification)Permalink

그렇다면 파라미터 w를 어떻게 학습할 수 있을까? 간단하게 하는 법은 최소제곱법. 선형회귀에서는 목표값이 실수값으로 주어졌기 때문에, 자연스럽게 될 수 있지만, 분류에서는 실수값이긴 하지만, 만약에 2개의 클래스라면 0 or 1 으로 실수값의 목표값으로 변환시키는 방식으로 함.

결론적으로는 분류에는 별로 좋지 않은 방식이다.

yk(x)=wkTx+wk0 k=1,,K

아래와 같이 행렬 W~을 사용하여 간편하게 나타낼 수 있다.

y(x)=W~Tx~

  W~=[|w~k|]인데, K=3인 경우, y1(x)=w~1Tx~, y2(x)=w~2Tx~, y3(x)=w~3Tx~ 이 각각의 값들은 scalar값인데 이 것을 하나의 표현할 것임.

y(x)=[w~1Tx~w~2Tx~w~3Tx~]=[w~1Tw~2Tw~3T]x~=W~Tx~ 이런식으로 표현되는 것임.

W~k번째 열은 w~k=(wk0,wkT)T이다.

제곱합 에러 함수Permalink

학습데이터 {xn,Tn}, n=1,,N, n번째 행이 TnT인 행렬 T, n번째 행이 x~nT인 행렬 X~이 주어졌을 때 제곱합 에러함수(sum-of-squared error function)은

ED(W~)=12tr{(X~W~T)T(X~W~T)}

유의할점은 K>2 일 경우 \widetilde{\boldsymbol{W}}가 행렬이라는 점이다. 각각의 열이 하나의 클래스에 대응함.

선형대수에서 했던 PCA와 유사함

다른식으로 정리하면, ED(W~)=12X~W~F2: 행렬과 행렬의 차이에 Frobenius norm을 제곱한 것.(식을 간편하게 하기 위해 1/2 곱해줌) 이것이 ED(W~)=12tr{(X~W~T)T(X~W~T)} 이 것과 동일함.

https://marquis08.github.io/devcourse2/linearalgebra/mathjax/ML-basics-Linear-Algebra/#%EB%8C%80%EA%B0%81%ED%95%A9-trace

제곱합 에러를 생각할때, 행렬의 Frobenius norm을 최소화 시킨다라는 것을 생각.

로 표현할 수 있다.

아래와 같이 유도할 수 있다. Design Matrix

X~=[x~nT],  W~=[|w~k|],  T=[TnT]

T=[TnT]는 각각의 행은 K개의 값들을 가진 벡터임.

ED(W~) =12n=1Nk=1K(x~nTw~kTnk)2 =12n=1N(x~nTW~TnT)(x~nTW~TnT)T =12n=1Ntr{(x~nTW~TnT)(x~nTW~TnT)T} =12n=1Ntr{(x~nTW~TnT)T(x~nTW~TnT)} =12tr{n=1N(x~nTW~TnT)T(x~nTW~TnT)} =12tr{(x~W~T)T(x~W~T)}

마지막 과정

이 부분도 PCA 할대 했던 것임.

A=XWT=[xnTWTnT]ATA=[|(xnTWTnT)T|][xnTWTnT]=n=1N(xnTWTnT)T(xnTWTnT)

W~에 대한 ED(W~)의 최솟값을 구하면

W~=(X~TX~)1X~TT=X~T

X~ X의 pseudo inverse에 목표값 행렬을 곱한 것이 에러함수를 최소화 시키는 W임.

따라서 판별함수는 다음과 같다.

y(x)=W~Tx~=TT(X~)Tx~
  • 분류를 위한 최소제곱법의 문제들
    • 극단치에 민감하다.
    • 목표값의 확률분포에 대한 잘못된 가정에 기초해 있다.

보라색선이 최소제곱법을 사용했을 때의 선형함수, 초록색이 로지스틱을 사용한 선형함수

목표값이 가우시안 분포를 따를 때, 최소제곱법이 쓰여질 수 있음. 분류의 경우 사실 목표값의 확률분포는 가우시안 분포를 따르지 않음. 목표값이 이산적인 값이기 때문에.

problems-of-least-squares-1
problems-of-least-squares-2

퍼셉트론 알고리즘 (The perceptron algorithm)Permalink

input x 대신에 기저함수 ϕ(x)를 사용하는 것.

w에 관한 선형함수를 f()라는 함수를 통해서 output을 구함.

이러한 함수 f()를 활성함수 (Activation Function)이라고 부름.

분류문제를 위해서는 함수의 출력값이 임의의 범위에 있는 것이 아니라, 유한한 개수의 값을 가져야 하기 때문에, 일정한 범위내에 있게 만들기 위해 Activation function을 사용하는 것임.

퍼셉트론 같은 경우 계단형 활성함수를 사용함.

y(x)=f(wTϕ(x))

여기서 f는 활성 함수(activation fucntion)로 퍼셉트론은 아래와 같은 계단형 함수를 사용한다.

f(a)={+1, a01, a<0

여기서 ϕ0(x)=1이다.

에러함수

EP(w)=nMwTϕntn

t{1,1} 이 두가지 값만 가진다고 가정.

최소제곱법을 사용할 때에는 {0,1}로 가정했지만, 퍼셉트론 에서는 {-1,1}, C1=1,C2=1 이런식으로 할당함.

이렇게 주어졌을 때, 찾고자 하는 w는 어떤 성질을 가지냐면,

tn=+1wTϕn>0tn=1wTϕn<0

위의 두가지 경우를 보면, 이상적인 상황에서는 wTϕntn>0 이러한 형태가 됨. target값이 +1, -1 이던간에 0보다 커야함.

만약에 이것을 만족하지 않으면 wTϕntn>0은 0보다 작게 됨.

에러함수를 보게 되면 EP(w)=nMwTϕntn, 에러가 발생했다는 의미는 wTϕntn 이 값이 음이 된다는 의미. 에러가 발생했다면 양의 에러값이 나오게 되고 이 양의 에러값을 최소화 하는 것이 우리의 목표임.

M은 잘못 분류된 데이터들의 집합

Stochastic gradient descent의 적용

w(τ+1)=w(τ)ηEp(w)=w(τ)+ηϕntn

ηEp(w) 이 부분은 위의 에러함수에 의해서 w에 관한 부분이기 때문에 ϕntn만 남게 되고, 앞에 마이너스가 있기 때문에, 결국 +ηϕntn가 되는 것임.

업데이트가 어떻게 적용되는 가

가장 이상적인 것은 (2,2)에 있는 그래프임. 검은선이 decision boundary이고 arrow가 벡터 w 임. 우리가 원하는 것은 w가 가리키는 방향에 빨간점이 위치해 있는 것이고, w의 반대 쪽에 파란점 들이 있는 것임.

업데이트 할 때, 에러가 오분류된 점들에 대해서만 적용이 됨. (위에서 언급된 부분: M은 잘못 분류된 데이터들의 집합)

예를 들어 아래 그림에서 (1,1)을 보면, 초록색 원으로 둘러싸인 오분류된 점에 의해서 파라미터 w가 어떻게 업데이트 되는지를 보자.

η=1,tn=1이라고 가정할 때, 입력값 ϕn을 더해주는 것임. 아래를 향하고 있는 w에다가 입력값 ϕn을 더해주는 효과가 있는 것임. 그 결과로 벡터가 합성이 되면서 (1,2)의 모양으로 w가 바뀐 것임.

다시 (2,1)의 그림에서 초록색 원으로 둘러싸인 오분류된 점을 선택해서 업데이트를 한다면 (2,2)의 w의 형태로 업데이트가 됨.

위 업데이트가 실행될 때 잘못 분류된 샘플에 미치는 영향

w(τ+1)Tϕntn=w(τ)Tϕntn(ϕntn)Tϕntn<w(τ)Tϕntn

w(τ+1)Tϕntn은 위에서본 에러부분임. (ϕntn)Tϕntn 이 부분은 dot product이고 이 것은 양수이기 때문에, 업데이트 후에는 에러가 줄어든 것을 의미. w(τ)Tϕntn(ϕntn)Tϕntn<w(τ)Tϕntn 이 식의 업데이트 후(τ+1) 에러가 줄어들었다는 의미

업데이트 할 때마다 그 점에 있어서는 에러가 준다는 점.

affects-of-misclassified-samples-1 affects-of-misclassified-samples-2 affects-of-misclassified-samples-3

두가지 방법 판별함수 방법들은 output을 출력하지만, 그것의 확률은 계산해주지 않기 때문에 한계가 있음. 제곱합보다는 퍼셉트론이 좋은 알고리즘이라고 볼 수 있음.

퍼셉트론 방법이 뉴럴모델의 기초가 된 것임.

확률 모델Permalink

생성모델과 식별모델

확률적 생성 모델 (Probabilistic Generative Models)Permalink

판별함수 방법에서는 에러함수를 설정하고 그 에러함수를 최소화시키기 위해 최적의 파라미터를 찾는 것이 목표였음. 확률 모델은 데이터의 분포를 모델링 하면서 분류문제를 푼다.

이제 분류문제를 확률적 관점에서 살펴보고자 한다. 선형회귀와 마찬가지로 확률적 모델은 통합적인 관점을 제공해준다. 예를 들어 데이터의 분포에 관해 어떤 가정을 두게 되면 앞에서 살펴본 선형적인 결정경계(linear decision boundary)가 그 결과로 유도되는 것을 보게 될 것이다.

p(x|Ck)p(Ck)를 모델링한다음 베이즈 정리를 사용해서 클래스의 사후 확률 p(Ck|x)를 구한다. 이전의 판별함수 방법에서는 어떤 에러함수를 최소화시키기 위한 최적의 파라미터를 찾는 것이 목적이라면 확률적 모델은 데이터의 분포(클래스를 포함한)를 모델링하면서 분류문제를 결과적으로 풀게 된다.

p(C1|x)=p(x|C1)p(C1)p(x|C1)p(C1)+p(x|C2)p(C2)=11+exp(a)=σ(a)

11+exp(a)=σ(a) a에 대한 시그모이드 함수.

시그모이드 함수:
a=0exp(a)=1σ(a)=0.5
aexp(a)σ(a)1
aexp(a)σ(a)0

a=lnp(x|C1)p(C1)p(x|C2)p(C2) σ(a)=11+exp(a)

a가 특정한 함수형태, 예를 들어 선형함수 형태를 가지게 될 떄, 이런 모델을 generalized linear model 이라고 부른다.
왜?

logistic-sigmod-function

Sigmoid & Logistic FunctionPermalink

Logistic Function: f(x)=L1+ek(xx0)

where

  • x0, the x value of the sigmoid’s midpoint;
  • L, the curve’s maximum value;
  • k, the logistic growth rate or steepness of the curve.

The sigmoid function is a special case of the Logistic function when L=1,k=1,x0=0.

  • L is the maximum value the function can take. ek(xx0) is always greater or equal than 0, so the maximum point is achieved when it it 0, and is at L/1.
  • x0 controls where on the x axis the growth should the, because if you put x0 in the function, x0x0 cancel out and e0=1, so you end up with f(x0)=L/2, the midpoint of the growth.
  • the parameter k controls how steep the change from the minimum to the maximum value is.

Logistic sigmoid의 성질 및 역함수Permalink

- σ(a)=1σ(a): 대칭적인 성질
- a=ln(σ1σ):역함수는 로그형태로 주어짐

1σ(a) 여기서 sigma를 delta라고 읽을 수 있음.

K>2인 경우

p(Ck|x)=p(x|Ck)p(Ck)jp(x|Cj)p(Cj)=exp(ak)jexp(aj) ak=p(x|Ck)p(Ck)

ak 가 이렇게 정의된다는 것을 기억하자. 클래스 k에 대한 조건부 확률 곱하기 클래스 k의 확률

연속적 입력 (continous inputs)Permalink

데이터의 분포에 대한 가정을 두게되면, 그 결과로 선형적인 결정 경계가 만들어짐.

p(x|Ck)가 가우시안 분포를 따르고 모든 클래스에 대해 공분산이 동일하다고 가정하자.

p(x|Ck)=1(2π)D/2|Σ|1/2exp{12(xμμk)TΣ1(xμμk)}

공분산이 동일하다고 가정했기 때문에 k라는 subscript가 없다.

두 개의 클래스인 경우Permalink

p(C1|x)=σ(a)

a를 전개하면(k=2일 경우임)

a =lnp(x|C1)p(C1)p(x|C2)p(C2) =12(xμμ1)TΣ1(xμμ1)+12(xμμ2)TΣ1(xμμ2)+lnp(C1)p(C2) ={(μμ1Tμμ2T)Σ1}x12μμ1TΣ1μμ1+12μμ2TΣ1μμ2+lnp(C1)p(C2)

로그를 취하면 지수부만 남게됨, 따라서 클래스 1에 대한 이차형식과 클래스 2에 대한 이차형식 두 부분만 남게됨.

12(xμμ1)T, 12(xμμ2) 여기 부호를 보면 μ1에 대해서는 마이너스 인데, μ1에 대해서는 플러스임.

그리고, 이차형식에서 x 관련된 부분은 공분산이 동일하게 때문에 서로 cancel out.

따라서 ax에 관한 선형식으로 다음과 같이 정리할 수 있다.

p(C1|x)=σ(wTx+w0) w =Σ1(μμ1μμ2)w0 =12μμ1TΣ1μμ1+12μμ2TΣ1μμ2+lnp(C1)p(C2)

위의 식 {(μμ1Tμμ2T)Σ1}x12μμ1TΣ1μμ1+12μμ2TΣ1μμ2+lnp(C1)p(C2)을 선형식으로 바꾸면,

w =Σ1(μμ1μμ2)w0 =12μμ1TΣ1μμ1+12μμ2TΣ1μμ2+lnp(C1)p(C2) 이러한 형태가 되는 것임.

p(C1|x)=σ(wTx+w0) 식을보면, 시그모이드 함수를 거치지만 x에 관한 선형식의 형태로 표현이 됨.

결국에 확률이 가지는 decision boundary는 결국 x에 관한 선형식에 의해서 결정됨.

K개의 클래스인 경우Permalink

ak=lnp(x|Ck)p(Ck), p(Ck|x)=exp(ak)jexp(aj)

위의 정의와 가우시안분포를 활용하면,

ak=ln(1(2π)D/21|Σ|1/2)12(xμμk)TΣ1(xμμk)+lnp(Ck)=ln(1(2π)D/21|Σ|1/2)12xTΣ1x+μkTΣ1x12μkTΣ1μk+lnp(Ck)

이것을 다시 x에 대한 조건부 확률인 p(Ck|x)에 대입을 해보면,

p(Ck|x)=exp(ak)jexp(aj)=exp{ln(1(2π)D/21|Σ|1/2)12xTΣ1x}exp{μkTΣ1x12μkTΣ1μk+lnp(Ck)}jexp(aj)

이 형태를 보면, exp{ln(1(2π)D/21|Σ|1/2)12xTΣ1x}exp{μkTΣ1x12μkTΣ1μk+lnp(Ck)} 이 부분은 분모에도 각각의 있는 aj에 대해서도 나타나는 동일한 부분이 될 것임. 왜냐면, 모든 클래스에 대해서 공분산이 동일하기 때문에, exp{ln(1(2π)D/21|Σ|1/2)12xTΣ1x} 이 부분을 분자, 분모에 다 나눠주면 cancel out되고, 남는 부분은 exp{μkTΣ1x12μkTΣ1μk+lnp(Ck)} 이 것임. 남은 부분은 x에 대한 일차형식만 살아남게 됨.

K개의 클래스일 경우에도, 2개의 클래스의 경우와 마찬가지로, Decision Boundary는 x에 대한 선형식으로 나타남을 볼 수 있음.
이렇게 선형식으로 나타나는 이유가 공분산 (Σ)를 모든 클래스에 대해 동일하다고 가정했기 때문에, 이러한 선형 Decision Boundary가 나타남.
만약 모든 클래스들이 공분산을 공유하지 않는다면, 이처럼 선형이 아니라 이차형식이 됨을 알 수 있음.

wk=Σ1μμk wk0=12μμkTΣ1μμk+lnp(Ck)

최대우도해 (Maximum likelihood solution)Permalink

이제 MLE를 통해 모델 파라미터들을 구해보자. 두 개의 클래스인 경우를 살펴본다.

데이터

- {xn,tn}, n=1,,N.
- tn=1은 클래스 C1tn=0은 클래스 C2를 나타낸다고 하자.

파라미터들

- p(C1)=π라고 두면, 구해야 할 파라미터들은 μμ1, μμ2, Σ, π이다.

우도식 유도

- tn=1이면

p(xn,C1)=p(C1)p(xn|C1)=πN(xn|μ1,Σ)

- tn=0이면

p(xn,C2)=p(C2)p(xn|C2)=(1π)N(xn|μ2,Σ)

따라서 우도함수는

p(t|π,μμ1,μμ2,Σ)=n=1N[πN(xn|μμ1,Σ)]tn[(1π)N(xn|μμ2,Σ)]1tn t=(t1,,tN)T

tn이 0이면 뒷부분이, tn이 1이면 앞부분만 남기 때문에 베르누이 분포와 유사한 형태임.

t는 N개의 목표값.

ML - π 구하기Permalink

위에서 p(C1)=π이라고 정의했음.

n=1N[πN(xn|μμ1,Σ)]tn[(1π)N(xn|μμ2,Σ)]1tn에 로그를 씌우기 때문에, 합의 형태로 나온다.
로그를 씌우면 n=1N[tn(lnπ+lnN(xn|μμ1,Σ))+(1tn)(ln(1π)+lnN(xn|μμ2,Σ))] 이렇게 나옴.
위의 식에서 π 관련항들만 모으면 아래의 식이 됨.

로그우도함수에서 π 관련항들만 모으면

n=1N{tnlnπ+(1tn)ln(1π)}

이 식을 π에 관해 미분하고 0으로 놓고 풀면

π에 관해 미분하면, n=1N{tnπ+(1tn)(1π)(1)} 이렇게 됨.
0으로 놓고 풀면,
n=1N{tnπ+(1tn)(1π)(1)}=0n=1Ntnπ=n=1N(1tn)(1π)1πn=1Ntn=11πn=1N(1tn)
n=1Ntn 이 값을 N1 (관측한 목표값들 중에서 클래스 1이 나타난 횟수) 으로 정의하고, N2 는 전체 관측 횟수 N에서 N1을 뺀 값이라고 정의하면
1πN1=11πN2이다. 이식을 π로 표현하면 아래와 같이 됨.

π=1Nn=1Ntn=N1N=N1N1+N2

이 ML 솔루션은 빈도주의적 입장에서 실제로 전체 관측한 횟수 중에서 C1이 나타난 빈도수를 계산한 결과와 동일함.

N1C1에 속하는 샘플의 수이고 N2C2에 속하는 샘플의 수이다.

ML - μμ1, μμ2 구하기Permalink

μμ1 관련항들

μμ1 관련에 관련된 부분은 위의 로그우도함수 (n=1N[tn(lnπ+lnN(xn|μμ1,Σ))+]) 에서 N(xn|μμ1,Σ) 이 부분임. 여기에 앞에 있는 n=1NtnlnN(xn|μμ1,Σ) 이 부분만 가져온 것이 아래의 식임.

n=1NtnlnN(xn|μμ1,Σ)=12n=1Ntn(xnμμ1)TΣ1(xnμμ1)+const

n=1NtnlnN(xn|μμ1,Σ)을 가우시안 함수를 사용해서 전개하면 위의이차형식이 나옴.

이 식을 μμ1에 관해 미분하고 0으로 놓고 풀면

μμ1에 관해 미분하면, 12n=1Ntn(xnTΣ1xn2xnTΣ1μ1+μ1TΣ1μ1)

μμ1에 관한 항만 놔두면,
12n=1Ntn(2xnTΣ1μ1+μ1TΣ1μ1)

이 식만 미분을 하면 됨.
행렬미분에서 xbTx=b 이 성질을 활용해서 , 2xnTΣ1μ1 이 식을 μ1에 대해서 미분하면,
transpose한 값만 남게 되므로, 2Σ1xn이 됨. (Σ는 대칭행렬이기 때문에 tranpose해도 그대로임)

뒷항인 μ1TΣ1μ1 이 이차형식을 행렬미분의 성질 (xxTAx=2Ax)을 활용해서 미분하게 되면, 2Σ1μ1이 됨.

따라서, μμ1에 관해 미분후에는, 12n=1Ntn(2Σ1xn+2Σ1μ1) 이 식이 나옴.

다시 정리하면, n=1Ntn(Σ1xnΣ1μ1) 최종적으로 이 식이 도출됨.

이것을 0으로 놓고 풀면,
n=1Ntnxn=n=1Ntnμ1

앞에서 n=1NtnN1으로 정의한 것을 사용하면,
n=1Ntnxn=N1μ1

μμ1=1N1n=1Ntnxn 이 됨.

행렬미분 성질: https://marquis08.github.io/devcourse2/linearalgebra/mathjax/ML-basics-Linear-Algebra/#%EC%A4%91%EC%9A%94%ED%95%9C-%EA%B3%B5%EC%8B%9D%EB%93%A4

μμ1=1N1n=1Ntnxn

유사하게

μμ2=1N2n=1N(1tn)xn

ML - Σ 구하기Permalink

앞에서한 가우시안 분포에서 최대우도해를 찾은 것들을 활용할 것임.
우도식에서 Σ와 관련된 부분을 찾아봄.

ML Solution=n=1N[πN(xn|μμ1,Σ)]tn[(1π)N(xn|μμ2,Σ)]1tn 여기서 각 [] 안에 Σ와 관련된 부분이 있음.
이 것을 정리하면 아래와 같이 총 4가지 항이 나타남.

 12n=1Ntnln|Σ|12n=1Ntn(xnμμ1)TΣ1(xnμμ1) 12n=1N(1tn)ln|Σ|12n=1N(1tn)(xnμμ2)TΣ1(xnμμ2) =N2ln|Σ|N2tr(Σ1S)

12n=1Ntnln|Σ|12n=1N(1tn)ln|Σ|은 cancel out되고, 남는 부분인 12n=1Nln|Σ|N2ln|Σ|이 됨.

나머지 항들은 2개의 이차형식 12n=1Ntn(xnμμ1)TΣ1(xnμμ1)12n=1N(1tn)(xnμμ2)TΣ1(xnμμ2)이 있음.
이차형식의 식을 보면, 양쪽 모두 N개의 합이 있음. 2N개 만큼의 합이 있음. 이것을 다르게 표현하면, N개의 합으로 표현이 가능함. 각각의 N에 대해서 둘중의 하나만 살아남고 나머지는 0이 됨. 실제로 남게 되는 항의 개수는 위의 2개의 이차형식 중에서 살아남는 항은 N개가 됨. 이 N개 중에서 N_1만큼의 클래스 1에 관련된 항들, N_2만큼의 클래스 2에 관련된 항들이 남게 될 것임. 결국에는 N개의 합으로 표현될 수 있음. 아래 S를 N개의 합으로 표현한 것임.

S1, S2 를 보면, 각각 C1, C2로 표현 됨. 결국 N개의 합으로 표현이 가능함. 그렇게 하게되면 앞에서 사용한, 가우시안 분포의 최대우도를 구할때 공분산 행렬(ΣML)을 보면,
l(Λ)=N2ln|Λ|12n=1Ntr((xnμ)(xnμ)TΛ)=N2ln|Λ|12tr(SΛ)
N2ln|Λ| 여기에서, Λ 대신에 Σ를 사용하면 마이너스가 없어지고 동일한 식임.
뒤의 식 12tr(SΛN을 곱하고 tr안에다 1N을 넣으면 S=N1NS1+N2NS2와 동일하다는 것을 알 수 있음.

S =N1NS1+N2NS2S1 =1N1nC1(xnμμ1)(xnμμ1)TS2 =1N2nC2(xnμμ2)(xnμμ2)T

가우시안 분포의 최대우도를 구하는 방법을 그대로 쓰면 결국은

Σ=S

복습 - 가우시안 분포의 최대우도 (Maximum Likelihood for the Gaussian)Permalink

https://marquis08.github.io/devcourse2/probabilitydistributions/mathjax/ML-basics-Probability-Distributions-2/#ml---%EA%B3%B5%EB%B6%84%EC%82%B0

다음으로 우도를 최대화하는 공분산행렬 ΣML을 찾아보자.

l(Λ)=N2ln|Λ|12n=1Ntr((xnμ)(xnμ)TΛ)=N2ln|Λ|12tr(SΛ) S=i=1N(xnμ)(xnμ)T l(Λ)Λ=N2(Λ1)T12ST=0 (ΛML1)=ΣML=1NS ΣML=1Ni=1N(xnμ)(xnμ)T

위의 식 유도를 위해 아래의 기본적인 선형대수 결과를 사용하였다.

  • |A1|=l/|A|
  • xTAx=tr(xTAx)=tr(xxTA)
  • tr(A)+tr(B)=tr(A+B)
  • Atr(BA)=BT
  • Aln|A|=(A1)T

입력이 이산값일 경우 (Discrete features)Permalink

각 특성 xi가 0과 1중 하나의 값만을 가질 수 있는 경우

클래스가 주어졌을 때 특성들이 조건부독립(conditional independence)이라는 가정을 할 경우 문제는 단순화된다. 이것을 naive Bayes가정이라고 한다. 이 때 p(x|Ck)는 다음과 같이 분해된다.

Ck가 주어졌을 때, 아래처럼 쉽게 분해(Decompose)가 됨.
μki=p(xi|Ck)

p(x|Ck)=i=1Dμkixi(1μki)1xi

따라서,

ak(x)=lnp(x|Ck)p(Ck) ak(x)=i=1D{xilnμki+(1xi)ln(1μki)}+lnp(Ck)

위의 식은 x에 관해서 linear한 식이 됨.
입력값이 이산값일 경우에도 조건부독립(conditional independence)이라는 가정을 할 경우 Decision Boundary가 여전히 선형이 된다는 것을 알 수 있음.

확률적 식별 모델 (Probabilistic Discriminative Models)Permalink

앞의 생성모델에서는 p(Ck|x)x의 선형함수가 logistic sigmoid 또는 softmax를 통과하는 식으로 표현되는 것을 보았다. 즉, K=2인 경우

p(C1|x)=σ(wTx+w0)

그리고 파라미터들 ww0를 구하기 위해서 확률분포들 p(x|Ck), p(Ck)의 파라미터들을 MLE로 구했다.

파라미터의 개수가 비교적 많기 때문에 효율적인 방법은 아래와 같음.

대안적인 방법은 p(Ck|x)x에 관한 함수로 파라미터화 시키고 이 파라미터들을 직접 MLE를 통해 구하는 것이다.

이제부터는 입력벡터 x대신 비선형 기저함수(basis function)ϕ(x)를 사용할 것이다.

이런식으로 x가 주어졌을 때 클래스의 확률을 x에 관한 함수로 파라미터화 시킨것으로 가정하고 이 파리미터를 바로 구하는 방법이 확률적 식별 모델임.
대표적 방법이 로지스틱 회귀임.

로지스틱 회귀 (Logistic regression)Permalink

x대신 ϕ를 사용할 것임. ϕ을 입력 벡터라고 생각하면 됨.

클래스 C1의 사후확률은 특성벡터 ϕ의 선형함수가 logistic sigmoid를 통과하는 함수로 아래와 같이 표현된다.

p(C1|ϕ)=y(ϕ)=σ(wTϕ) σ(a)=11+exp(a) p(C2|ϕ)=1p(C1|ϕ)

ϕM 차원이라면 구해야 할 파라미터(w)의 개수는 M개이다. 생성모델에서는 M(M+5)/2+1개의 파라미터를 구해야 한다.

특히, 공분산 행렬에 나타나는 파라미터들을 구해야 하는데 M에 대해서 quadratic.
로지스틱 회귀에서는 M의 liear개수의 파라미터만 구해도 됨.

최대우도해 Permalink

- 데이터셋: {ϕn,tn}, n=1,,N
- tn{0,1}
- t=(t1,,tN)T
- ϕn=ϕ(xn)
- yn=p(C1|ϕn)

우도함수는

p(T|w)=n=1Nyntn(1yn)1tn

베르누이 분포의 형태와 동일함.
예를 들어, 주어진 목표값 벡터가 다음과 같다고 할 때, t=(1,0,1)T

우도함수는
p(t|w)=(y11(1y1)0)×(y20(1y2)1)×(y31(1y3)0)=p(C1|ϕ1)×p(C2|ϕ2)×p(C1|ϕ3)
이 식을 compact하게 표현한 것이 위의 우도함수 식임.

음의 로그 우도 (the negative logarithm of the likelihood)

Likelihood를 Maximize하는 것이 아니라 음의 로그우도를 minimize하는 식으로 풀게 되는 것임.

E(w)=lnp(T|w)=n=1N{tnlnyn+(1tn)ln(1yn)}

tn은 타겟값이고 yn은 예측한 값임.
tnlnyn+(1tn)ln(1yn) 이런식으로 표현된 것이 Cross Entropy Error Function이라고 부름.

Cross Entropy는 정보이론(Information Theory)에서 나온 것임.

yn=σ(an), an=wTϕn

이것을 크로스 엔트로피 에러함수(cross entropy error function)라고 부른다.

Cross entropy의 일반적인 정의

두 개의 확률분포 p,q가 주어졌을 때, 로그 q의 기댓값으로 정의함.

H(p,q)=Ep[lnq]

이산확률변수의 경우

H(p,q)=xp(x)lnq(x)

두 개의 확률분포가 가까울 수록 Cross entropy가 최소화됨.

일반적으로 Cross entropy가 최소화될 때 두 확률분포의 차이가 최소화된다. 따라서 에러함수 E(w)를 최소화시키는 것을

- 우도를 최대화시키는 것 (우도함수를 최대화 시키다보면 에러함수를 최소화시켜야 한다는 것을 알게됨)
- 모델의 예측값(의 분포)과 목표변수(의 분포)의 차이를 최소화시키는 것

두 가지의 관점에서 이해할 수 있다.

앞에서 최소제곱법이 효과적이지 못했던 이유는, 목표값의 분포가 가우시안을 따르지 않았기 때문임.

에러함수의 w에 대한 gradient를 구해보자.

에러함수(E(w))는 모든 데이터에 대한 에러를 합한 것임.
식을 간단하게 하기 위해서 하나의 데이터에 대한 에러를 알아볼 것임.
에러함수가 파라미터 w와 어떤 관계를 가지고 있는지를 생각해보자.

yn=σ(an) an는 파라미터 w에 대한 선형함수 였음. (음의 로그 우도 참고)
an=wTϕn
yn, an을 에러식에 대입하면 w에 관련된 식임을 알 수 있음.

도식적으로 표현하면,
error-function-figure
함수 En(w)w에 관해서 미분을 하려고 할때, chain rule을 쓰면됨.
클래스가 2개인 경우에는 wan, En(w)사이의 관계가 오직 anyn을 통해서만 지나가기 때문에,
아래 처럼 chain rule을 쓰면 됨.

En(w)ynynanan를 보면,
먼저, an: anw에 관해서 미분하고,

그 다음, ynan: ynan에 관해서 미분

마지막으로, En(w)yn: En(w)yn에 관해서 미분

En(w)yn: En(w)={tnlnyn+(1tn)ln(1yn)}yn에 미분한 결과는 {1tn1yntnyn} 이렇게 되고,

En(w)yn: yn=σ(an) 으로 로지스틱 시그모이드 함수의 미분은 yn(1yn) 이런식으로 계산이 됨.

an: an=wTϕn은 선형식이기 때문에 ϕn이 됨.

이 식을 정리하면 아래식의 결과인 (yntn)ϕn이 됨.

따라서 전체 에러의 w에 대한 미분은 E(w)=n=1N(yntn)ϕn임.

En(w)={tnlnyn+(1tn)ln(1yn)}

라고 정의하면

E(w)=n=1NEn(w) En(w) =En(w)ynynanan ={1tn1yntnyn}yn(1yn)ϕn =(yntn)ϕn

따라서

E(w)=n=1N(yntn)ϕn

다중클래스 로지스틱 회귀 (Multiclass logistic regression)Permalink

지수함수를 사용함.

p(Ck|ϕ)=yk(ϕ)=exp(ak)jexp(aj) ak=wkTϕ

우도함수Permalink

2개의 클래스일 때의 우도함수: p(T|w)=n=1Nyntn(1yn)1tn

특성벡터 ϕn를 위한 목표벡터 tn는 클래스에 해당하는 하나의 원소만 1이고 나머지는 0인 1-of-K 인코딩 방법으로 표현된다.

실제로 데이터에 클래스 k가 주어져있는지에 따라서 결정이 됨. 클래스의 해당 값이 1이면 하나의 확률값만 남게 됨.
T=[100001] (각각의 행이 하나의 데이터)
p(C1|ϕ1)=1임 첫번째 행의 값 (ϕ1에서의 subscript는 index를 의미함)
p(C3|ϕ2)=1.

y를 사용해서 표현한다면, \(y_{nk}^{t_{nk}\)에서 첫번째 supscript(n)는 데이터 인덱스, 두번째 subscript(k)는 클래스 인덱스
p(C1|ϕ1)=y11, p(C3|ϕ2)=y23

p(T|w1,w2,w3)=(y111y120y130)(y210y220y231)

(y111y120y130)(y210y220y231) 이 부분은 n=1Nk=1Kynktnk 이 식을 그대로 따라 적은 것임.
위의 행렬에서 보인 것처럼 y11=p(C1|ϕ1), y23=p(C3|ϕ2)
따라서, ynk=p(Ck|ϕn) 임.

p(T|w1,...wK)=n=1Nk=1Kp(Ck|ϕn)tnk=n=1Nk=1Kynktnk

ynk=yk(ϕn), Ttnk를 원소로 가지고 있는 크기가 N×K인 행렬

T는 크기가 N×K인 행렬임을 기억해야함.

음의 로그 우도

E(w1,...,wK)=lnp(T|w1,...,wK)=n=1Nk=1Ktnkln(ynk)

구해야할 파라미터 w의 개수는 k개의 벡터임. 각각의 w의 벡터들의 최소값을 찾아야 하는데, wj에 대한 gradient를 구해서, 최적의 해를 구하고, j의 값이 1일때부터 k일때까지를 구하면, 최적의 파라미터들을 다 찾는 것이 됨.

wj에 대한 gradient를 구한다. 먼저 하나의 샘플 ϕn에 대한 에러

En(w1,,wK)=k=1Ktnkln(ynk)

를 정의하면

wjE(w1,...,wK)=n=1NwjEn(w1,...,wK)

다음 함수들 사이의 관계를 주목하라.

- Enwj의 관계는 오직 anj에만 의존한다(ank,kjwj의 함수가 아니다).
- Enyn1,,ynK의 함수이다.
- ynkan1,,anK의 함수이다.

multiclass-error-figure

p(Ck|ϕ)=yk(ϕ)=exp(ak)jexp(aj) 이렇게 소프트 맥스 함수형식으로 표현되어 있는데, 분자에는 exp(ak)가 있는데, 분모에는 모든 a의 변수들이 더해져 있음. 그래서 yk(ϕ)=p(Ck|ϕn)는 단지 ak의 관한 함수가 아니라 모든 a에 관한 함수임.

각각의 yn1y~nk의 변수가 a와 관련이 있음을 의미함.
그림에서 w의 차원은 M임을 기억해야 함.

에러함수를 w로 미분할 때 어떻게 chain rule을 쓸것인가를 결정하기 위해 도식화해봄.
그림에서 보면, wj는 반드시 an만을 통과해야 에러함수에 도달이 가능함. an에 도달한 후로는 에러함수로 가기 위해서는 K개의 길이 존재함. 이것이 chain rule을 결정함.

wjEn =Enanjanjwj =Enanjϕn =k=1K(Enynkynkanj)ϕn =ϕnk=1K{tnkynkynk(Ikjynj)} =ϕnk=1Ktnk(ynjIkj) =ϕn(ynjk=1Ktnkk=1KtnkIkj) =ϕn(ynjtnj)

위 식을 전개 👇
Enwj에 관해서 미분할 것임. wjM차원의 벡터임을 잊지말자.

Enanjanjwj

wjanj를 통해서만 En에 관계를 가질 수 있음. 따라서 anj에 대해서 chain rule을 적용한 것임.
anjwj = ϕn과 같음을 그림에서도 확인함. 왜냐면 anj=wjTϕn이기 때문.

anjEn의 관계는 K개의 yn변수를 통해서 가기 때문에 이 경로에 대한 합을 다 적어줘야함.(chain rule)

k=1K(Enynkynkanj)

이렇게 표현할 수 있음.

ϕn는 수식앞으로 보내고 나머지 부분을 다시 정리하면,

Enynk

이 부분은 간단함. En(w1,,wK)=k=1Ktnkln(ynk) 이 식에서 ynk에 대해서 미분하면 단순히 1ynk이 곱해지는 것임.
따라서,

tnkynk
ynkanj

이 부분은 2가지의 경우로 나눠서 생각하면 됨.

(1). kj

ynkanj

이렇게 미분할 때, ya의 관계는 yk(ϕ)=exp(ak)jexp(aj) 이런 식의 함수관계임.
풀어서 써보면 이러한 형태임로 바꿔줄 수 있음(k대신 l을 사용).

ynk=exp(ank)lexp(anl)=exp(ank)×{exp(an1)++exp(anl)}1

이제,
kj인 경우 ynkanj 에서 분자와 분모는 서로 다른 변수임. 분자부분을 미분할 때 상수처럼 취급함.
따라서,
exp(ank)×{exp(an1)++exp(anl)}1에서 anj가 나타나는 부분은 분모 {exp(an1)++exp(anl)}1의 하나의 항으로 나타남.

미분을 하면,

ynkanj=exp(ank){lexp(anl)}2exp(anj)=exp(ank)lexp(anl)×(exp(anj)lexp(anl))=ynk×(ynj)

(2). k=j

ynkanj=exp(anj)lexp(anl)exp(anj)2{lexp(anl)}2=exp(anj)lexp(anl)(1exp(anj)lexp(anl))=ynk×(1ynj) by ynk=exp(ank)lexp(anl), k=jynk=ynj

ynk=exp(ank)×{exp(an1)++exp(anl)}1 이기 때문에, 이것을 anj에 대해 미분하는데,

두 함수의 곱이 있을 때, 함수 f(x)g(x)가 곱해져 있을때 그것을 미분을 하면, f(x)를 미분한 것에 g(x)를 곱하고 + f(x)곱하기 g(x)를 미분한 것으로 계산됨.(Appendix 참조)

따라서, f(x)exp(ank)anj에 대해서 미분하면, k=j이고 지수함수이기 때문에 exp(anj)가 그대로 내려오고(f(x)) g(x){exp(an1)++exp(anl)}1 을 그대로 곱해주게 되면,

exp(anj)lexp(anl)

이 결과가 됨.
g(x){exp(an1)++exp(anl)}1anj에 대해서 미분하고, f(x)=exp(ank)를 그대로 곱해주면,

exp(anj)2{lexp(anl)}2

이 결과가 나옴.

위 의 2가지 경우를 하나의 식으로 나타내면,

ynk(Ikjynj)

단위행렬(Ikj)를 사용해서 표현이 가능함. {kj0k=j1}

{tnkynkynk(Ikjynj)}

이 식을 정리하면 tnk(ynjIkj) 가 됨.
ϕnk=1Ktnk(ynjIkj) 을 풀어서 곱으로 나누어주면 (ynjk=1Ktnkk=1KtnkIkj) 이 됨.
ynjk=1Ktnk에서 ynjk값과 상관없이 때문에 밖으로 나옴.
남은 부분인 k=1Ktnk은 하나의 데이터데 대해서 그때의 타겟 벡터의 원소들을 다 합한 것과 같고 이 값은 결국 1임 (목표값은 하나의 데이터에 대해 반드시 1개의 클래스만 1이 될 수 있기 때문에).
k=1KtnkIkj 이 경우도, 결국 j번째 원소만 남고 나머지는 전부 0이 되기 때문에 tnj만 남게 됨.

최종적으로 하나의 데이터 기저함수를 사용한 ϕn에 대해서 에러를 구해서, 그 에러에 wj에 대한 gradient()는 ϕn(ynjtnj)가 되는 것임.

과정은 복잡했지만, 결과로 나온 gradient는 생각보다 단순한 형태..

ϕn(ynjtnj): ϕn은 입력벡터이고, 예측값(ynj)과 타겟값(tnj)의 차이를 곱해서 이루어지게 됨.

따라서

wjE(w1,...,wK)=n=1N(ynjtnj)ϕn

행렬로 표현하면, 더 간단하게 표현이 가능함.
ΦT(yt): Φ는 Design Matrix
ΦT=[|  ϕ1|  ]
ΦT라는 열벡터로 표현된 행렬에 벡터 (yt)를 곱하는 형태임.

위의 합의 형태를 행렬로 간단하게 표현이 가능함.

실습Permalink

Gradient Descent (batch)Permalink

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
import seaborn as sns

X, t = make_classification(n_samples=500, n_features=2, n_redundant=0, n_informative=1,
                             n_clusters_per_class=1, random_state=14)

t = t[:,np.newaxis]

sns.set_style('white')
sns.scatterplot(X[:,0],X[:,1],hue=t.reshape(-1));

def sigmoid(x):
    return 1 / (1 + np.exp(-x))



def compute_cost(X, t, w):
    N = len(t)
    h = sigmoid(X @ w)
    epsilon = 1e-5
    cost = (1/N)*(((-t).T @ np.log(h + epsilon))-((1-t).T @ np.log(1-h + epsilon)))
    return cost

compute cost
E(w)=lnp(T|w)=n=1N{tnlnyn+(1tn)ln(1yn)}와 동일한 함수임.
코드에서는 1N을 곱하는 형태로 적용한 것임.
1N을 곱하는 것이 numerical하게 안정적임. N값이 크게 되면 gradient가 크기 때문에 gradient값이 한꺼번에 많이 움직이는 상황이 발생하기 때문. 1N 해주면 안정적으로 optimization이 가능함.
h = sigmoid(X @ w): h는 벡터임 broadcasting 되면서, 시그모이드 함수에 들어가는 벡터의 각각의 원소에 대해서 대응하는 로지스틱 시그모이드 함수 값을 원소로 가지게 됨.
epsilon = 1e-5: 로그 값은 안정적으로 구하기 위해서 더해줌.
yn이 코드에서는 h + epsilon인 것임.

def gradient_descent(X, t, w, learning_rate, iterations):
    N = len(t)
    cost_history = np.zeros((iterations,1))

    for i in range(iterations):
        w = w - (learning_rate/N) * (X.T @ (sigmoid(X @ w) - t))
        cost_history[i] = compute_cost(X, t, w)

    return (cost_history, w)

파라미터 w = w - learning_rate*gradient 임.
앞에서 x라는 원래의 인풋을 쓰기도 했고 기저함수 ϕ를 쓰기도 했지만, 위 코드에서는 기저함수를 통과하지 않은 원래의 x를 사용했음.
x도 Design Matrix라고 부를 수 있음.

gradient 식과 비교해봄. gradient
E(w)=n=1N(yntn)ϕn=ΦT(yt): Φ는 Design Matrix
ΦT=[|  ϕ1|  ]
여기선 Design Matrix가 x 이기 때문에, xT× (sigmoid(X @ w) = y)-t 의 형태가 되는 것임.

def predict(X, w):
    return np.round(sigmoid(X @ w))

0 or 1로 출력하도록 만들어줌.

N = len(t)

X = np.hstack((np.ones((N,1)),X))
M = np.size(X,1)
w = np.zeros((M,1))

iterations = 1000
learning_rate = 0.01

initial_cost = compute_cost(X, t, w)

print("Initial Cost is: {} \n".format(initial_cost))

(cost_history, w_optimal) = gradient_descent(X, t, w, learning_rate, iterations)

print("Optimal Parameters are: \n", w_optimal, "\n")

plt.figure()
sns.set_style('white')
plt.plot(range(len(cost_history)), cost_history, 'r')
plt.title("Convergence Graph of Cost Function")
plt.xlabel("Number of Iterations")
plt.ylabel("Cost")
plt.show()

Dummy input을 사용하기 위해 X = np.hstack((np.ones((N,1)),X)) 1을 열로 하나 추가한 것임.

Dummy input을 사용하는 이유?

(cost_history, w_optimal) = gradient_descent(X, t, w, learning_rate, iterations)
여기서 전체 데이터 (X)를 한꺼번에 gradient를 업데이트를 하는 것이기 때문에 batch 업데이트라고 부름.
딥러닝에서 주로 사용하는 batch는 사실 mini-batch를 줄여서 하는 말임.
여기서는 전체 데이터를 다 사용해서 업데이트 한다는 의미임.

(cost_history, w_optimal)
여기서 optimal은 진짜 optimal이 아니라 최종적으로 얻어지는 W임 (충분히 학습하면 최종적으로 나오는 W가 optimal이라는 가정하에 붙인 것임)

AccuracyPermalink

y_pred = predict(X, w_optimal)
score = float(sum(y_pred == t))/ float(len(t))

print(score)

Draw a decision boundaryPermalink

slope = -(w_optimal[1] / w_optimal[2])
intercept = -(w[0] / w_optimal[2])

sns.set_style('white')
sns.scatterplot(X[:,1],X[:,2],hue=t.reshape(-1));

ax = plt.gca()
ax.autoscale(False)
x_vals = np.array(ax.get_xlim())
y_vals = intercept + (slope * x_vals)
plt.plot(x_vals, y_vals, c="k");

Stochastic Gradient DescentPermalink

파라미터를 업데이트 할때 데이터 전체를 사용하는 것이 아니라 데이터 하나 만을 사용하는 방법.

def sgd(X, t, w, learning_rate, iterations):
    N = len(t)
    cost_history = np.zeros((iterations,1))

    for i in range(iterations):
        i = i % N # 처음 위치로 
        w = w - learning_rate * (X[i, np.newaxis].T * (sigmoid(X[i] @ w) - t[i]))
        cost_history[i] = compute_cost(X[i], t[i], w)

    return (cost_history, w)

batch(전체): w = w - (learning_rate/N) * (X.T @ (sigmoid(X @ w) - t))
sgd: w = w - learning_rate * (X[i, np.newaxis].T * (sigmoid(X[i] @ w) - t[i]))
i-th 데이터만 사용해서 업데이트
batch로 했을 때는 iterations = 1000으로 전체 데이터를 1000번 읽은 효과
sgd에서 iterations = 1000으로 하면, 읽은 샘플의 개수가 1000개인 것임.

X, t = make_classification(n_samples=500, n_features=2, n_redundant=0, n_informative=1,
                             n_clusters_per_class=1, random_state=14)

t = t[:,np.newaxis]

N = len(t)

X = np.hstack((np.ones((N,1)),X))
M = np.size(X,1)
w = np.zeros((M,1))

iterations = 2000
learning_rate = 0.01

initial_cost = compute_cost(X, t, w)

print("Initial Cost is: {} \n".format(initial_cost))

(cost_history, w_optimal) = sgd(X, t, w, learning_rate, iterations)

print("Optimal Parameters are: \n", w_optimal, "\n")

plt.figure()
sns.set_style('white')
plt.plot(range(len(cost_history)), cost_history, 'r')
plt.title("Convergence Graph of Cost Function")
plt.xlabel("Number of Iterations")
plt.ylabel("Cost")
plt.show()

AccuracyPermalink

y_pred = predict(X, w_optimal)
score = float(sum(y_pred == t))/ float(len(t))

print(score)

Mini-batch Gradient DescentPermalink

배치 사이즈를 조절해서 함.

def batch_gd(X, t, w, learning_rate, iterations, batch_size):
    N = len(t)
    cost_history = np.zeros((iterations,1))
    shuffled_indices = np.random.permutation(N)
    X_shuffled = X[shuffled_indices]
    t_shuffled = t[shuffled_indices]

    for i in range(iterations):
        i = i % N # 태초마을
        X_batch = X_shuffled[i:i+batch_size]
        t_batch = t_shuffled[i:i+batch_size]
        # batch가 epoch 경계를 넘어가는 경우, 앞 부분으로 채워줌 
        if X_batch.shape[0] < batch_size:
            X_batch = np.vstack((X_batch, X_shuffled[:(batch_size - X_batch.shape[0])]))
            t_batch = np.vstack((t_batch, t_shuffled[:(batch_size - t_batch.shape[0])]))
        w = w - (learning_rate/batch_size) * (X_batch.T @ (sigmoid(X_batch @ w) - t_batch))
        cost_history[i] = compute_cost(X_batch, t_batch, w)

    return (cost_history, w)

데이터를 shuffle 해줌.(배치 사이즈 만큼 읽기 때문에 특정 batch에서의 영향을 줄이기 위해)
if X_batch.shape[0] < batch_size: 이것은 pytorch에서 dataloader(droplast=True)로 사용하면 에러없이 가능함.

X, t = make_classification(n_samples=500, n_features=2, n_redundant=0, n_informative=1,
                             n_clusters_per_class=1, random_state=14)

t = t[:,np.newaxis]

N = len(t)

X = np.hstack((np.ones((N,1)),X))
M = np.size(X,1)
w = np.zeros((M,1))

iterations = 1000
learning_rate = 0.01

initial_cost = compute_cost(X, t, w)

print("Initial Cost is: {} \n".format(initial_cost))

(cost_history, w_optimal) = batch_gd(X, t, w, learning_rate, iterations, 32)

print("Optimal Parameters are: \n", w_optimal, "\n")

plt.figure()
sns.set_style('white')
plt.plot(range(len(cost_history)), cost_history, 'r')
plt.title("Convergence Graph of Cost Function")
plt.xlabel("Number of Iterations")
plt.ylabel("Cost")
plt.show()

AccuracyPermalink

y_pred = predict(X, w_optimal)
score = float(sum(y_pred == t))/ float(len(t))

print(score)

딥러닝에서는 mini-batch를 보통사용함.
SGD 같은 경우 민감하게 반응하기 때문에.

AppendixPermalink

Derivative of the product of two functions Permalink

f(x)=g(x)h(x)f(x)=g(x)h(x)+g(x)h(x)

MathJaxPermalink

left align:

 A=AAAA AAAAA=A AAA=AA
$$\begin{align} &\ A = AAAA \\ &\ A = A \\ &\  A = AA \end{align}$$

escape unordered list
- cov[xa]=Σaa:

\- $$cov[\boldsymbol{x}_{a}] = \Sigma_{aa}$$ 

\setminus
{A}{B}:

$$\{A\}\setminus\{B\}$$

adjustable parenthesis
(content):

$$\left( content \right)$$

Matrix with parenthesis (a11a12a1na21a22a2nam1am2amn):

$$\pmatrix{a_{11} & a_{12} & \ldots & a_{1n} \cr a_{21} & a_{22} & \ldots & a_{2n} \cr \vdots & \vdots & \ddots & \vdots \cr a_{m1} & a_{m2} & \ldots & a_{mn} }$$

ReferencesPermalink

Pattern Recognition and Machine Learning: https://www.microsoft.com/en-us/research/uploads/prod/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf
Sigmoid & Logistics function: https://stats.stackexchange.com/questions/204484/what-are-the-differences-between-logistic-function-and-sigmoid-function/204485
Generalized Linear Model and Logistic: https://sebastianraschka.com/faq/docs/logistic_regression_linear.html

Leave a comment