Skip to content

Instantly share code, notes, and snippets.

@QuadFlask
Created September 28, 2018 09:03
Show Gist options
  • Save QuadFlask/d74be1be5b1ede2945cd2f09fc4e5a09 to your computer and use it in GitHub Desktop.
Save QuadFlask/d74be1be5b1ede2945cd2f09fc4e5a09 to your computer and use it in GitHub Desktop.

수치 미분 Numerical Differentitaion link

f(x) = ax^n f`(x) = anx^(n-1) = df/dx (x) // 구조적으로 미분하는 해석적 방법

하지만 컴터엔 무한소가 없기때문에 수치 미분을 함

df/dx (x) = ( f(x + dx) - f(x) ) / dx // forward differentiation

var x = 1;
var dx = 1e-5;

var f = x=> x * x;
var df = f(x + dx) - f(x);
var dfdx = df / dx;

함수가 어떻게 생겼는지 몰라도 이런식으로 수치 미분을 함. 하지만 함수가 복잡하거나 dx 가 충분히 작지 않으면 오차가 크다. 이렇게 구한 미분을 어디에 쓰지? -> 어떤 지점에서의 함수 값과 미분값을 알 때 x 가 조금 더 나아갔을 때의 값을 추측할 수 있음 -> interpolation / extrapolation

근사시키기

f(x + dxt) =~ f(x) + df/dx (x) * dxt

var dxt = 0.2;

var fdtx = f(x) + dfdx * dxt; 
// =~ 1.4, f(x + dxt) = 1.44 얼추 비슷하다!

원하는 아웃풋을 얻기 위해 어떤 인풋을 넣어야 할까?

dxt를 찾기 위해서

f(x+dxt) = f target

dxt = ( f target - f(x) ) / dfdx (x)

var ft = 1.44;
var dxtp = (ft - f(x)) / dfdx; 
// dxtp = 0.219
// 아까 0.2 가 목표값인데 얼추 비슷하다!

해석적 미분 방법과 함께

이미 도함수를 알 수 있을 땐 수치미분 대신 도함수를 그냥 사용하면 보다 정확하게 값을 추측할 수 있다. 보통 딥러닝에선 activation 함수로는 미분된 함수를 알 수 있기 때문에 효율적임 또한 이 개념이 gradient descent method 에 사용됨

경사하강법 Gradient Descent Method link

input x -> [ function ] -> output y

y target 을 얻기 위한 input x 값은?

함수가 얼마나 틀렸는지 정해야 함

E = 1/2 * ( yt - y )^2

E == 0 이면 원하는 결과를 달성했다 를 판별할 수 있음 (아마도 최소) // 모든곳에서 0 이 되어버리면 오버피팅이라고 함

y = ax + b

E = 1/2 ( yt - ax - b)^2

a 또는 b 가 변해야 함

E 가 2차함수니까 최소점이 되는 a, b 를 구해야함

이렇게 에러함수가 2차함수이고 우리가 원하는 지점이 최소점 -> 시작한 지점에서 에러를 줄여주는쪽으로 가야함 -> 미분을 하면 경사가 0 이되는 지점을 찾는다 -> 경사가 하강된당

a updated = a - ar * dE/da // ar: learning rate

최적화

minimize E

a updated = a - ar * dE/da

b updated = b - ar * de/db

E가 충분히 작을 때까지 반복

E = 1/2 ( yt - ax - b)^2

dE/da = (yt - ax - b) * -x // a 에 대해서 미분
      = (yt - y) * -x
      
dE/db = (yt - ax - b) * -1 // b 에 대해서 미분
      = (yt - y) * -1
var a=0,b=0;
var f = (a,x,b) => a*x + b;

var yt = 1;
var x = 0;
var alpha = 0.01;

for (var i=1000;i-->0;) {
   error = yt - f(a,x,b);
   
   console.log(`square error: ${0.5*error*error}`);
   
   var ea = error * -x;
   var eb = error * -1;
   
   a -= alpha * ea;
   b -= alpha * eb;
}

console.log(`a: ${a}, b: ${b}, error: ${yt-f(a,x,b)}`);

constraint 가 여러개 일경우

var numConst = 3;
var yt = [1, 1.5, 2];
var x = [0, 0.5, 1];
var alpha = 0.01;
var a = 0, b = 0;
var f = (a,x,b) => a*x + b;

for (var i=1000; i-->0;) {
    var sqrErrorSum = 0;
    var eaSum = 0, ebSum = 0;
    for (var c=0; c<numConst; c++) {
        var error = yt[c] - f(a, x[c], b);
        var ea = error * -x[c];
        var eb = error * -1;
        sqrErrorSum += error * error;
        eaSum += ea;
        ebSum += eb;
    }
    
    a -= alpha * eaSum / numConst;
    b -= alpha * ebSum / numConst;
    
    console.log(`Square error: ${0.5 * sqrErrorSum} when a:${a}, b:${b}`);
}

for (var i=0; i<numConst; i++)
   console.log(`a: ${a}, b: ${b}, error: ${yt[i]-f(a,x[i],b)}`);

결과 a: 0.9123957710439071, b: 1.0503135492522502, error: -0.006511434774203684 얼추 x + 1 이랑 같아짐

굳이 모든 constraint 에 대해서 할 필요 없이 랜덤하게 정하도록 하면 최적화 할 수 있다

Stochastic GDM

var numConst = 3;
var yt = [1, 1.5, 2];
var x = [0, 0.5, 1];
var alpha = 0.01;
var a = 0, b = 0;
var f = (a,x,b) => a*x + b;

for (var i=1000; i-->0;) {
    var c = ~~(numConst * Math.random()); // 랜덤을 썼지만 데이터에 따라서 적절하게 주면 좋다

    var error = yt[c] - f(a, x[c], b);
    var ea = error * -x[c];
    var eb = error * -1;
   
    a -= alpha * ea;
    b -= alpha * eb;
    
    console.log(`Square error: ${0.5 * error*error} when a:${a}, b:${b}`);
}

for (var i=0; i<numConst; i++)
   console.log(`a: ${a}, b: ${b}, error: ${yt[i]-f(a,x[i],b)}`);

결과 a: 0.9167923973982887, b: 1.0454330682483828, error: -0.0038292669475270547

연쇄 미분 Chain rule link

back-propagation 이해에 도움

Chained Functions

함수의 조합일 경우

input x -> [ [ g(x) ] -> [ f(g) ] ] -> output y = f(g(x))

편미분 Partial Differentiation

f(x) = ax + b

걍 미분: df/dx(x) = a

x 가 유일한 변수일 경우

편미분 :

df/dx(x,a,b) = a
df/da(x,a,b) = x 
df/db(x,a,b) = 1

변수가(x, a, b) 여러개일 경우

Chain rule

f(x) = f(g(x))

df/dx = df(g)/dg * dg(x)/dx

Gradient Descent Optimiztion

y = f(g(x))

f(x) = af * x + bf
g(x) = ag * x + bg

eaf1 = af0 - ar * dE/daf
ebf1 = bf0 - ar * dE/dbf
eag1 = ag0 - ar * dE/dag
ebg1 = bg0 - ar * dE/dbg

Differentiation with Chain Rule

dy/dx = df(g)/dg * dg/dx = af * ag

dy/daf = df/daf = g(x)
dy/dbf = df/dbf = 1
dy/dag = df(g)/dg * dg(x)/dag = af * x
dy/dbg = df(g)/dg * dg(x)/dbf = af * 1

Differentiation Squared Error Function

dE/daf = -(yt - y) * dy/daf = -(yt - y) * df(g)/daf = -(yt - y) * g(x)
... (각각 `-(yt - y)`를 곱해주는 형태)
var MAX = 1;
var rand = () => Math.random() * MAX;
var f = (a,x,b)=> a * x + b;
var g = (a,x,b)=> a * x + b;
var yt = 1;
var x = 0;
var af=rand(), bf=rand(), ag=rand(), bg=rand();
var alpha = 0.01;

for (var i=0;i<500;i++) {
   var error = yt - f(af, g(ag, x, bg), bf);
   var sqError = 0.5 * error * error;
   
   var eaf = -error * g(ag, x, bg);
   var ebf = -error * 1;
   var eag = -error * af * x;
   var ebg = -error * af * 1;
   
   af -= alpha * eaf;
   bf -= alpha * ebf;
   ag -= alpha * eag;
   bg -= alpha * ebg;
   
   console.log(`error: ${sqError}`);
}

console.log(`${af} ${bf} ${ag} ${bg} ------ ${f(af, g(ag, x, bg), bf)}`);

결과 error: 1.115465481992649e-12 1.0865808935532866 0.34940286962120654 0.9937056196788403 0.5987549371928094 ------ 0.9999985442956114

뉴런 하나 만들기 + Back Propagation

class Neuron {
   constructor(w=2, b=1) {
      this.w = w; // weight 인풋이 한개일 경우. 여러개면 배열로
      this.b = b; // bias
      this.input = 0; // for back-propagation 
      this.output = 0; // for back-propagation 
   }
   
   getAct(x) {
       return x;
       // ReLU: return Math.max(x,0);
   }
   
   getActGrad(x) {
       return 1;
   }
   
   feedForward(input) {
       this.input = input;
       const sigma = this.w * input + this.b;
       this.output = this.getAct(sigma);
       return this.output;
   }
   
   propBackward(target) {
       var alpha = 0.1 // learning rate
       var grad = (this.output - target) * this.getActGrad(this.output);
       this.w -= alpha * grad * this.input;
       this.b -= alpha * grad * 1;
   }
}

var neuron = new Neuron();

for (var i=0;i<100;i++) {
   neuron.feedForward(1);
   console.log(`i:${neuron.input} o:${neuron.output} w:${neuron.w} b:${neuron.b}`);
   neuron.propBackward(4);
}

FCNN

Multiple input

sigma = w0 * x0 + w1 * x1 + ... + wn * b
= [w0 w1 w2 ... wn] * [x0 
                       x1 
                       x2 
                       ... 
                       b]

b 도 가중치를 곱하는 이유는 매트릭스로 하면 식이 간단해져서 b도 가중치를 곱한다. 대신 wn 이나 b 를 1로 두기도 함.

Multiple nuerons

[ sigma0      [ w00 w01 w02 w03     [ x0
  sigma1   =    w10 w11 w12 w13   *   x1
  sigma2 ]      w20 w21 w22 w23 ]     x2
                                      x3 ]
                                      
sigma = W * x

F-Prop of �Multiple Layers

y = f1(sig1) = f1(w1 * f0(sig0) + w1b * b)

Fully Connected Layers

input x0   sigma00 | f00  sigma10 | f10
input x1   sigma01 | f01  sigma10 | f11
input x2   sigma02 | f02  sigma10 | f12

input        hidden        output 
layer        layer         layer

Forward Propagation

[ sigma00 [ w000 w001 w002 w003 [ x0 sigma01 = w010 w011 w012 w013 * x1 sigma02 ] w020 w021 w022 w023 ] x2 b ]

Array.prototype.sum = function() { return this.reduce((r,a)=> r+a, 0)}
var scalaProd = (W,X)=> W.map((w,i)=> w*X[i]).sum();

Machine learning basics

  1. supervised learning
Z = F(X)

point mapping

back propagation

perceptron: input * w -> z

ReLU;

Good at And/Or problem but XOR -> Add hidden layer

back propagation

x1  -(w11)-  y1 
   (w12,w21)  z
x2  -(w22)-  y2 
```
cost function 을 w로 미분




2. unsupervised learning
```
P(X,Z)
```
energy landscape

볼츠만 분포

볼츠만 머신

S^n, n={1....M}

Data distribution = P(S) = 1/M sum d(S - S^n)

Model distribution = Q(S) = e^(-E(S)) / Z
E(S) = - sum(Wij*Sj*Sj)
Z = sum(e^-E(S))


Kullback-Leibler divergence

D(P||Q) = sum(P(S)*log(P(S)/Q(S)))





3. Information flow
```
H[P(X), P(Z|X)]
```
shannon entropy
두 사람이 있을 때 누가 고수인가? -> 질문 1개 필요
H(Y) = -sum(P(Y) log P(X))








# Restricted Boltzmann Machine

S = Kb ln W


Hopfield NN (HNN)






# CNN 

feature extraction layer + classification layer
[ CNN ]                       [ FC ]

ReLU

Pooling layer; Max Pooling; dimension reduction + rotation/skew... invariant -> data augmentation






#  GAN

Two type of Deep learning

Discriminative  : 데이터를 서로 다른 클래스로 분류 
Generative : 데이터 분포 학습, 이를 기반으로 데이터 재생성


GAN : 
Discriminator: 입력을 가짜와 진짜로 분류
Generator: 가짜 데이터 생성





# Reinforcement Learning

supervised, unsupervised, pattern recognition

Sequential decision making and control problem

AlphaGo - DeepMind


- Markov Decision process
- Dynamic programing
- Monte-Carlo
- Temporal Difference



## Markov Decision Process

> 미래 상태가 현재의 상태만 주어지면 과거의 역사와는 무관하게 결정되는 성질을 가지게 되는 확률 과정

Markov Process <- Action

```
   a0    a1
s0 -> s1 -> s2
```

`(S, A, P, r, R)`

S: 모든 상태 집합
A: 모든 액션 집합
P: s에서 a행동을 할때 s’으로 갈 확률
r: discount factor; [0 <= r <= 1] 보상이 시간에 따라 r배 만큼 줄어든다
R: 리워드; 얻을 수 있는 모든 보상의 평균

Gt = sum(t)(rRt)


## Policy

s 상태에서 a행동을 할 확률
Our goal in Reinforcement learning is to choose policy so as to maximize the expected value of the total payoff

## Value Function : 상태와 행동의 가치를 매겨주는 함수 

State-value function: 상태의 가치 `V(s) = R[Gt|St = s]`
Action-value function: 액션의 가치 `q(s,a) = E[Gt|St = s, At = a]`: 여기의 `q` 가 나중에 나오는 Deep-Q Learning 의 `Q`임

## Bellman Equation: 현재 상태와 다음상태의 value function 사이의 관계식

Monte-Carlo; 직접 움직여서????
Monte-Carlo Control: 현 상태에서 최고의 value만 가지고 판단할경우 local optimum에 빠질 수 있어서 다른 상태로 갈 확률을 정함



























Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment