레이블이 machine learning인 게시물을 표시합니다. 모든 게시물 표시
레이블이 machine learning인 게시물을 표시합니다. 모든 게시물 표시

[컴][머신러닝] 파이토치(Pytorch)에 대한 간략한 설명

What if pytorch / pytorch / desc / 파이토치 설명 / 파이토치 차이점. / Machine learning / ML / 머신러닝 / 기계학습

파이토치에 대한 간략한 설명

  • 파이토치는 문턱이 낮다
  • 파이토치는 공식 문서가 잘 만들어져 있다.
  • 자체 운영 포럼이 있다.
  • 연산 그래프 설정에서도 장점
    • 파이토치는 ‘Define by Run’ 방식, 텐서플로우가 ‘Define and Run’ 방식
    • ‘Define and Run’ 프레임워크에서는 연산 그래프를 먼저 정의하고 값을 넣어 결과를 얻는다. ‘Define by Run’ 프레임워크는 연산 그래프가 정의되는 동시에 연산이 이루어진다.(인용)
    • 텐서플로우 2.0의 ‘즉시실행(Eager execution)’ 모드와 비슷하다.

파이토치 tutorial

  1. 영문: Welcome to PyTorch Tutorials — PyTorch Tutorials 1.4.0 documentation
  2. 한글: 파이토치(PyTorch) 튜토리얼에 오신 것을 환영합니다 — PyTorch Tutorials 1.3.1 documentation

Reference

  1. 블로그ㅣ머신러닝에 관심있다면?··· 이제는 파이토치다 - CIO Korea
  2. 블로그 | 파이토치로 딥러닝해야 하는 5가지 이유 - CIO Korea, 2020-02-27

[컴][머신러닝] Recurrent Neural Networks 예제

ML / machine learning


Recurrent Neural Networks, RNN


관련글 :  The Unreasonable Effectiveness of Recurrent Neural Networks


원본 소스 : https://gist.github.com/karpathy/d4dee566867f8291f086

python 3 버전

# encoding=utf8

"""
Minimal character-level Vanilla RNN model. Written by Andrej Karpathy (@karpathy)
BSD License
"""
import numpy as np
import codecs

# data I/O
with codecs.open('input.txt', 'r', encoding='utf-8') as fp:
    data = fp.read()
    # data = open('input.txt', 'r').read() # should be simple plain text file
    chars = list(set(data))
    data_size, vocab_size = len(data), len(chars)
    print ('data has %d characters, %d unique.' % (data_size, vocab_size))
    char_to_ix = { ch:i for i,ch in enumerate(chars) }
    ix_to_char = { i:ch for i,ch in enumerate(chars) }

    # hyperparameters
    hidden_size = 100 # size of hidden layer of neurons
    seq_length = 25 # number of steps to unroll the RNN for
    learning_rate = 1e-1

    # model parameters
    Wxh = np.random.randn(hidden_size, vocab_size)*0.01 # input to hidden
    Whh = np.random.randn(hidden_size, hidden_size)*0.01 # hidden to hidden
    Why = np.random.randn(vocab_size, hidden_size)*0.01 # hidden to output
    bh = np.zeros((hidden_size, 1)) # hidden bias
    by = np.zeros((vocab_size, 1)) # output bias

    def lossFun(inputs, targets, hprev):
      """
      inputs,targets are both list of integers.
      hprev is Hx1 array of initial hidden state
      returns the loss, gradients on model parameters, and last hidden state
      """
      xs, hs, ys, ps = {}, {}, {}, {}
      hs[-1] = np.copy(hprev)
      loss = 0
      # forward pass
      for t in range(len(inputs)):
        xs[t] = np.zeros((vocab_size,1)) # encode in 1-of-k representation
        xs[t][inputs[t]] = 1
        hs[t] = np.tanh(np.dot(Wxh, xs[t]) + np.dot(Whh, hs[t-1]) + bh) # hidden state
        ys[t] = np.dot(Why, hs[t]) + by # unnormalized log probabilities for next chars
        ps[t] = np.exp(ys[t]) / np.sum(np.exp(ys[t])) # probabilities for next chars
        loss += -np.log(ps[t][targets[t],0]) # softmax (cross-entropy loss)
      # backward pass: compute gradients going backwards
      dWxh, dWhh, dWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
      dbh, dby = np.zeros_like(bh), np.zeros_like(by)
      dhnext = np.zeros_like(hs[0])
      for t in reversed(range(len(inputs))):
        dy = np.copy(ps[t])
        dy[targets[t]] -= 1 # backprop into y. see http://cs231n.github.io/neural-networks-case-study/#grad if confused here
        dWhy += np.dot(dy, hs[t].T)
        dby += dy
        dh = np.dot(Why.T, dy) + dhnext # backprop into h
        dhraw = (1 - hs[t] * hs[t]) * dh # backprop through tanh nonlinearity
        dbh += dhraw
        dWxh += np.dot(dhraw, xs[t].T)
        dWhh += np.dot(dhraw, hs[t-1].T)
        dhnext = np.dot(Whh.T, dhraw)
      for dparam in [dWxh, dWhh, dWhy, dbh, dby]:
        np.clip(dparam, -5, 5, out=dparam) # clip to mitigate exploding gradients
      return loss, dWxh, dWhh, dWhy, dbh, dby, hs[len(inputs)-1]

    def sample(h, seed_ix, n):
      """ 
      sample a sequence of integers from the model 
      h is memory state, seed_ix is seed letter for first time step
      """
      x = np.zeros((vocab_size, 1))
      x[seed_ix] = 1
      ixes = []
      for t in range(n):
        h = np.tanh(np.dot(Wxh, x) + np.dot(Whh, h) + bh)
        y = np.dot(Why, h) + by
        p = np.exp(y) / np.sum(np.exp(y))
        ix = np.random.choice(range(vocab_size), p=p.ravel())
        x = np.zeros((vocab_size, 1))
        x[ix] = 1
        ixes.append(ix)
      return ixes

    n, p = 0, 0
    mWxh, mWhh, mWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
    mbh, mby = np.zeros_like(bh), np.zeros_like(by) # memory variables for Adagrad
    smooth_loss = -np.log(1.0/vocab_size)*seq_length # loss at iteration 0
    while True:
      # prepare inputs (we're sweeping from left to right in steps seq_length long)
      if p+seq_length+1 >= len(data) or n == 0: 
        hprev = np.zeros((hidden_size,1)) # reset RNN memory
        p = 0 # go from start of data
      inputs = [char_to_ix[ch] for ch in data[p:p+seq_length]]
      targets = [char_to_ix[ch] for ch in data[p+1:p+seq_length+1]]

      # sample from the model now and then
      if n % 100 == 0:
        sample_ix = sample(hprev, inputs[0], 200)
        txt = ''.join(ix_to_char[ix] for ix in sample_ix)
        print ('----\n %s \n----' % (txt, ))

      # forward seq_length characters through the net and fetch gradient
      loss, dWxh, dWhh, dWhy, dbh, dby, hprev = lossFun(inputs, targets, hprev)
      smooth_loss = smooth_loss * 0.999 + loss * 0.001
      if n % 100 == 0: print ('iter %d, loss: %f' % (n, smooth_loss)) # print progress
      
      # perform parameter update with Adagrad
      for param, dparam, mem in zip([Wxh, Whh, Why, bh, by], 
                                    [dWxh, dWhh, dWhy, dbh, dby], 
                                    [mWxh, mWhh, mWhy, mbh, mby]):
        mem += dparam * dparam
        param += -learning_rate * dparam / np.sqrt(mem + 1e-8) # adagrad update

      p += seq_length # move data pointer
      n += 1 # iteration counter 
fdsfds


결과

무한 loop 이라, 적정한 시점에 알아서 멈추면 된다.

아래 결과는 대략 12시간 정도를 돌렸다. 컴퓨터 스펙은 아래와 같다.

  • CPU:  i7-6700, 3.40GHz
  • RAM: 16GB
----
 beahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nela haeiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol e iohahenasen
----
iter 9309400, loss: 0.000086
----
 e nh a taei.rairrhelardr naioa aneaa ayio pe e bhnte ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cds
----
iter 9309500, loss: 0.000086
----
 jCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cds
----
iter 9309600, loss: 0.000086
----
 negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr
----
iter 9309700, loss: 0.000086
----
 aI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr neli ae e angnI hyho gben
----
iter 9309800, loss: 0.000086
----
 gehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nela dr iohecgrpiahe.
Ddelnss.eelaishaner” cot AA
----
iter 9309900, loss: 0.000086
----
 piahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol e iohahenasenese hbea bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a t
----
iter 9310000, loss: 0.000086
----
 er” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nela hamnaI ayio pe e h’e btentmuhgnhi beahe
Ddabealohe bee amoi bcgdltt. gey heho grpiahe.
Ddeln
----
iter 9310100, loss: 0.000086
----
 bih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol gyio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae
----
iter 9310200, loss: 0.000086
----
 beahngy
amo k ns aeo?cdse nh a taei.rairrhelardr ntlhnegnns. e
amo k ns aeh?cdse nh a taei.rairrhelardr nol e iohehengrpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeah
----
iter 9310300, loss: 0.000086
----
 e nh a taei.rairrhelardr nol’e btentmuhgehi gcdslatha arenbggcodaeta tehr he ni.rhelaney gehnha e ar i ho  bee amote ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol nyio chge heiohecgr
----
iter 9310400, loss: 0.000086
----
 jCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cds
----
iter 9310500, loss: 0.000086
----
 negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr
----
iter 9310600, loss: 0.000086
----
 aI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nelardae abeahngy
amo k
----
iter 9310700, loss: 0.000086
----
 gehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr ntl negnk t hi rsnse nhk br ne” a naeiarairr elirs
----
iter 9310800, loss: 0.000086
----
 piahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nelardaenabeahngelareierhi. aif edElobe negrcih gey gey heho grpiahe.
Ddel
----



[컴][머신러닝] Machine Learning





대략적인 이해를 위해서 여기를 읽어보자.

Machine Learning

machine learning 에서 결론은 어떤 input 들에 대한 model(방정식)을 구하는 것이라고 보면 될 듯 하다. 즉 어떤 input 이 어떤 방정식(모델)을 따른다면, 우리는 새로운 input 이 들어왔을 때 이 input 에 대한 output 이 어떻게 나올지 알 수 있다.

이 어떤 방정식(모델) 이 앞으로 이야기할 hypothesis function 이 된다.

  • Supervised Learning[ref. 1] : data set 이 있고, 이 input 에 대해 어떤 output 이 나오는가 나와야 하는지를 알고 싶을때 사용할 수 있다.
    이 알고리즘은 input 과 output 에 상관관계가 있다고 생각하는 것이다. labeled data 를 가지고 작업한다고 생각하면 된다.
    문제는 다음 2가지로 나눌 수 있다.
    • regression problem : 결과값이 continuous 한 값으로 나오는 문제들, 예를 들어 "집크기와 가격에 대한 data 가 있을 때, 크기가 X 만한 집의 가격은?" 등의 문제가 regression problem 이 될 수 있다.
      결과 값으로 정수처럼 딱 나눠지는(discrete) 한 결과를 찾기보다는 실수 값을 찾는 문제일 가능성이 크다. continuous 값을 찾아야 하니까. 물론 그렇다고 정수를 결과값을 찾는 문제라고 해서 모두다 classification problem 은 아니다.
    • classification problem : 결과값이 discrete 한 값일 때 쓴다. 예를 들어 "집크기가 X 만한 집이 있다면 이 집의 가격은 Y 보다 큰가, 작은가?" 라는 문제는 크다, 작다 의 2가지 결과값중 하나가 output 이 되기 때문에 이녀석은 classification problem 이 된다.
  • Unsupervised Learning[ref. 2]
    • clustering algorithm
      어떤 dataset 에 대해서 grouping 을 알아서 해준다.
    • non-clustering algorithm : cocktail party alogorithm
      여러개가 섞여서 혼란스러운 상황에서 어떤 구조를 찾아준다. 목소리 2개가 섞여 있는 파일에서, 음성을 분리해 내는 등의 일을 한다.
    • octave : machine learning prototype 을 만들기 좋은 tool / Download

Training set
m = training example 의 개수
x = input / feature 라고 부름
y = output / target variable 이라 부름


hypothesis function

우리가 training set 을 통해서 알아낸 "예측 모형(model)" 을 hypothesis function 이라고 부른다.
  • function h : X → Y (h maps from x's` to y's)
이것을 좀 더 직관적으로 생각해보면, 우리는 주어진 어떤 값들(traning set) 을 좌표안에 찍고, 이 점들을 대체로 만족하는 "식"(hypothesis function)을 구하는 것이다.(식은 결국 그 점들을 전부 아우르는 그래프를 그려낼 것이다.)

우리가 이 "식"을 구하면 우리는 training set 이외의 위치의 값도 알 수 있고, 이것으로 예측을 하는 것이다.

그리고 이 hypothesis function 에서 우리가 구해야 하는 것은 θ 이다. 즉 식이 성립하기 위한 '상수' 를 찾아야 한다.(ref. 9 에서 θ 를 '가중치' 라고 이야기한다. ref. 9의 설명이 필자는 이해하기 쉬웠다.)

일단 여기서는 꼭 1차 방정식만을 이야기하는 것이 아니다 x 가 x2 을 뜻할 수도 있다.

예를 들어 아파트값을 구하기 위해 우리가 사용하는 변수가 '평수', "단지크기" 라고 한다면, 과연 "평수"가 아파트값에 미치는 영향이 클지, "단지크기" 가 아파트값에 미치는 영향이 큰지에 따라 가중치를 달리 할 것이다.

  • 아파트 값 = ("평수"x θ1) x ("단지크기" x θ2)



Univariate linear regression

여기서 우리는 이 함수(hypothesis function)가 일차방정식이라고 하자.(즉 어떤 input 과 output 과의 관계가 '일차방정식' 의 모양과 비슷하다고 보면 된다.)

그래서 우리는 y= θ+ θ1x 라는 방정식에서 θ 의 값을 찾아 낼 것이다. 여기서 이 θ 값은 어떤 값이어야 하는가?

당연히 이 θ 값을 넣어서 만든 h(x) 의 y 값이 실제 값과  가장 잘 맞는 θ 값이어야 한다.

from: ref. 2

이렇게 x 가 한개인 hypothesis function 을 단일변량 선형회귀 (Linear regression with one variable / Univariate linear regression) 라고 한다.
  • Linear regression model : hθ(x) = θ0 + θ1x

linear regression 의 목적은 cost function J(θ) 를 최소화 하는 것이다. 즉, 우리가 만든 hypothesis function 과 실제값과의 괴리를 최소화 하는 것이다.





Cost Function

이것을 이용해서 우리가 만든 hypothesis function 이 얼마나 실제값에 잘 맞는지 여부를 알아낼 수 있다.
from: ref. 3
위의 J(theta0, theta1) 이 cost function 이다. 이 함수를 "Squared error function", 또는 "Mean squared error" 라고 부른다.

이 함수를 잘 보면 결국 "예측값 - 실제값" 의 평균을 구하는 것이다. 즉 "우리가 예측한 것이 실제 값들에서 얼마나 멀어져 있는가?" 에 대한 값을 구하는 것이다.

이 cost function 의 최소값이 "괴리"가 가장 적다는 뜻이되고, 결국 predict model 이 정교하다는 것을 이야기 하기에, 우리는 cost function 의 최소값을 찾아야 한다.

hθ(x) 방정식이 y= θ1x 처럼 변수가 1개라면 위의 cost function 은  변수가 2개(θ0, θ1)인 2차방정식(x2)이 된다. 그러면 그래프의 모양은 아래처럼 될 것이다. (J(θ1),  θ1)



그리고 hθ(x) 방정식이 y= θ+ θ1x처럼 변수가 2개(θ0, θ1)라면 위의 cost function 은  변수가 3개인 2차방정식이 된다. 그러면 아래와 같은 모양이 된다.(J(θ1),  θ, θ1)
from: ref. 4

여기서  J(θ0 , θ1) 의 최소값을 선택하면, 우리는 training set 에 가장 가까운 hθ(x) 를 찾게 되는 것이다.


최소값을 찾는데에 도움을 주는 알고리즘


  • Gradient Decent Alogorithm
  • Normal Equation



Gradient Decent Algorithm

그럼 우리는 cost function 의 최소값을 찾아야 하는데, 이걸 찾게 도와주는 알고리즘중 하나가 Gradient Decent Algorithm 이다. 이 Gradient Decent Algorithm 이 Machine learning 알고리즘이다.

Gradient Decent Algorithm 이 있는데, 이녀석의 공식은 아래와 같은 식을 수렴이 될때까지 반복하는 것이다.
위 공식을 수렴(convergence)이 될 때까지 반복
α(alpha): learning rate


이 녀석의 계산은 아래처럼 해야 한다. 즉, θ0 를 계산한 후 그 값을 가지고 θ1 를 계산하는 것이 아니라, θ0 , θ1를 동시에 계산한 후에, 이 값을 update 한다.

이 공식을 풀어서 이야기 해보면, 현재 우리가 가진 hypothesis function, hθ(x) 가 있고, 이 녀석은 θ0 , θ1으로 이뤄져 있는데, 이 θ0 , θ1값을 바꿔가면서 가장 적합한 hθ(x) 를 찾아야 한다.

이 때 가장 적합한 hθ(x)를 찾는 것은 cost function 의 값이 가장 적은 값을 찾는 것이다. 그래서 Gradient Decent 알고리즘의 식은 θ값을 cost function 과 관계있게 만들어 준다.

특정 θ0 , θ1값에서의 cost value 가 있고, 이 cost value 에서의 기울기를 구한다. 이 기울기의 값도 중요하지만, 이 기울기로 방향을 정하게 된다. 이렇게 구한 기울기 방향으로 현재의 θ값을 움직여 나가는 것이다.(그것이 식에서는 현재 θ값에 값을 - 하는 것으로 표현된다.)

그래서 α(alpha) 가 learning rate 라 불린다. α(alpha) 가 크다면 최소값에 빠르게 접근할 수 있고, α(alpha) 가 작다면 느리게 접근하게 된다. 하지만 α(alpha) 가 너무 크면 움직이는 간격이 너무 커서 최소값을 지나쳐 버리고 다시 diverge 될 수 도 있다.


Multivariate Linear Regression

여러개의 변수 Multiple features

2개 이상의 변수가 있는 경우를 보자. 이것도 linear regression 이지만 변수가 여러개인 linear regression 이다. 그래서 multivariate linear regression (다변량 선형회귀)이라 부른다.

이전의 h 함수는 1개의 변수 x 가 있었다.
hθ(x) = θ+ θ1x

이 변수 하나가 대상의 특징(feature) 이라고 보면 된다.
hθ(x) = θ+ θ1x1 + θ2x2 + θ3x3 ... + θnxn

hθ(x) = θ0x0 + θ1x1 + θ2x2 + θ3x3 ... + θnxn


Gradient Descent for multiple variables

아래 모습처럼 feature 수만큼(x1, x2..) 의 식이 있고, 이것이 하나의 iteration 이 된다.




이 feature scaling 은 feature 즉 x0, x1, x2 .. 값들의 범위를(input value의 범위) 조절하는 것이다.(scaling) 이것은

Gradient Descent 를 좀 더 효율적으로 사용하기 위해 필요하다.


Gradient Descent 를 이용해서 우리는 hypothesis function 에 쓸 적절한 θ 값을 얻을 수 있다. 이 때 θ의 범위가 크면 descend 가 천천히 이루어진다. 그리고 x1, x2, ..(input value) 의 범위가 다르면 θ의 진동이 커진다. 그래서 최소값을 구하는데에 오랜 시간이 걸린다.

이때 θ의 범위를 줄이고, x1, x2 의 범위를 비슷하게 맞춰주면 적은 수의 연산으로 빠르게 최소값을 찾을 수 있다.(이부분에 대한 설명은 Gradient Descent in Practice I - Feature Scaling - Coursera 을 참고하자.)

standadization

이 θ의 범위를 줄이고, 변수 x1, x2, ... 의 범위를 비슷하게 하기 위해 x0, x1, x2 의 값들을 표준화, 정상화(normalization) 을 해준다. normalization 에 대한 이야기는 아래 경로를 참고하자.


Learning rate

gradient decent 에서 learning rate 값인 α를 구하는 법을 보자.

위 공식을 수렴(convergence)이 될 때까지 반복
α(alpha): learning rate
위에서 이야기 했지만, α가 너무 크면 수렴이 되지 않고, 너무 작으면 계산이 오래걸린다.
그래서 이 값을 정할 때는 대략적으로 값을 대입해서 아래처럼 그래프를 그려보면서 값이 제대로 수렴하는지를 확인해서 가장 적절한 α값을 선택한다.
from. ref. 6

Polynomial Regression

linear regression 의 그래프는 직선이다. 즉, input data 들이 대략적으로 한줄로 표현될 수 있다는 이야기다. 이때의 식이 다음과 같다.
  • hθ(x) = θ0x0 + θ1x1 + θ2x2 + θ3x3 ... + θnxn

하지만 data 속성이 꼭 linear 하지 않을 수 있다. 이때 polynomial regression 이 가능하다.
  • hθ(x) = θ0 + θ1x1 + θ2x12 ---->  θ0 + θ1x1 + θ2x2 (where x2 = x12 ) 
  • hθ(x) = θ0 + θ1x1 + θ2x12 + θ3x13



Octave 에서 구현한 Gradient Descent





Normal Equation[ref. 7]

Gradient Descent 알고리즘 처럼 J 값(cost function, 우리의 모델이 실제 data 와 얼마나 멀어져있나.) 을 최소화 하는 방법중 하나이다.

우리가 2차방정식에서 최소값 또는 최대값을 구할때 미분을 이용하듯이, vector 에 대해서도 편미분을 통해 구할 수 있다. 그런데 이것을 선형대수를 이용하는 것이다.(?)[ref. 7]
  • θ=(XTX)-1XTy
X, y 에 대해서는 아래 그림을 참고하자.
from : ref. 7


Gradient Descent Normal Equation
Need to choose alpha(learning rate) No need to choose alpha
Needs many iterations No need to iterate
O (kn2) O (n3), need to calculate inverse of XTX
Works well when n is large Slow if n is very large

  • n x n 행렬의 역행렬을 구하는데에는 대체로 O (n3) 이 소요된다.
  • 대체로 feature 의 개수 n 이 10,000 이하라면, 요즘 컴퓨터에서 사용할 만 하다고 한다.

Gradient Descent 알고리즘과 차이점

Gradient Descent 알고리즘은 여러번 수행을 해서 J(θ) 의 최소값을 찾는 방법이라면, Normal Equation 은 계산을 통해 한번에 최소값을 찾는 방법이다.


XTX 의 inverse matrix 가 없다면(not invertable)?

XTX is noninvertible 인 경우는 아래와 같은 이유일 수 있다.
  • 일단 redundant 한 feature 가 없는지 살펴보고, 있다면, 지운다.
    • 만약 집값의 feature 중에, "평수" 가 있고, "m2" 가 같이 있다면, 이것은 지운다.
  • 너무 많은 feature 를 사용하는 경우 라면 (m <= n) (m: the number of example)
  • feature 를 몇개 삭제하던지, regularization 이라는 방법을 이용한다.



References

  1. Supervised Learning | Coursera,
  2. Unsupervised Learning - Stanford University | Coursera
  3. Cost Function - Intuition I | Coursera
  4. Cost Function - Intuition II - Stanford University | Coursera
  5. Gradient Descent For Linear Regression - Stanford University | Coursera
  6. Gradient Descent in Practice I - Feature Scaling - Stanford University | Coursera
  7. Normal Equation | Coursera
  8. Machine Learning
  9. 기계 학습(Machine Learning, 머신 러닝)은 즐겁다! Part 1 – Jongdae Lim – Medium

[컴][링크] Deep learning 자료

딥러닝 읽을 자료 / 딥러닝 파악하기



README   SanghyukChun's Blog




Deep-Learning-Papers-Reading-Roadmap

deep learning 을 위한 자료들이다. 처음에 어떤 자료를 읽어야 할지 막막한 사람들을 위해 songrotek 이라는 분이 정리해놨다. 참고로 영문자료다.



Deeplearning.net Reading list

Etc

[컴] scikit-learning 에서 naive Bayer 사용하기



설치

virtualenv / Tcl error 

예전 버전의 virtualenv 인 경우 tcl library 를 못찾는 error 가 나올 수 있다.(확실히 언제 버전부터 tcl 을 copy 하는 code 가 들어갔는지는 모르겠다. ref. 7 를 참고하자.)

여하튼 일단 virtualenv 를 최신버전으로 사용하자.
pip install virtualenv --upgrade

그리고 혹시나 현재 상태에서 사용하고 싶다면, 자신의 virtualenv 의 activate.bat 에 아래 code 를 추가하자.
set "TCL_LIBRARY=C:\Python27\tcl\tcl8.5"
set "TK_LIBRARY=C:\Python27\tcl\tk8.5"



package 설치

아래처럼 package 를 설치한다.

pip install scikit-learn
pip install numpy-1.11.0+mkl-cp34-cp34m-win_amd64.whl
pip install scipy-0.17.1-cp27-cp27m-win_amd64.whl
pip install matplotlib-1.5.1-cp27-none-win_amd64.whl


windows 에서 numpy 설치

ref. 4에 나와 있는 것처럼 ref. 1 의 pre-built 된 많은 binary 들이 numpy-1.10+mkl 을 필요로 한다.
Python Extension Packages for Windows - NumPy 에서 numpy-1.11.0+mkl-cp34-cp34m-win_amd64.whl 를 설치한다.

D:\mine\naiveBayes>pip install numpy-1.11.0+mkl-cp34-cp34m-win_amd64.whl

참고로, pip install numpy 를 하면, pre-built scipy 를 사용할 때 아래와 같은 error 가 발생한다.[ref. 5]
...
File "C:\Python27\lib\site-packages\scipy\__init__.py", line 61, in <module>
    from numpy._distributor_init import NUMPY_MKL  # requires numpy+mkl
ImportError: cannot import name NUMPY_MKL


windows 에서 scipy 설치

Python Extension Packages for Windows - Christoph Gohlke 에서 scipy whrl 을 download 하고, 아래처럼 설치한다. 참고로 내 python 은 python 2.7 이여서 cp27 이다.

D:\mine\naiveBayes>pip install scipy-0.17.1-cp27-cp27m-win_amd64.whl


linux 에서 Matplotlib 설치

설치할 때 build 를 위해 library 가 몇개 더 필요하다. 아래 글을 참고하자.
library 를 설치하고도 freetype header file 을 인식하지 못할 수 있다. 이때는 symbolic link 를 만들어 주면 된다.
  • sudo apt-get install libpng-dev libjpeg8-dev libfreetype6-dev
  • ln -s /usr/include/freetype2/ft2build.h /usr/include/  (참고)


사용

큰 data 처리하기

ref. 3 에 큰 data 에 대한 이야기가 있다.
컴퓨터 한대에서 사용가능한 RAM 용량의 20% 가 넘는 크기의 data 를 large data 라고 할 수 있다. 해결방법은 아래 2가지가 가능하다.
  1. data set 의 일부만(subset) 가지고 data 를 분석한다. 흔히 알고 있는 streaming data 를 처리하는 것이다.
  2. cloud 같은 것을 이용해서 더 큰 RAM 용량을 얻는다.

out-of-core

이중에 scikit-learn 에서  제공하는 out-of-core processing을 살펴 보자. ref. 4 에 따르면 scikit-learn  은 작은 크기의 data (smaller data) 에 최적화 되어 있다고 한다. scikit-learn 팀은 streaming data 를 처리할 수 있도록 시도하고 있다고 한다.[ref. 3]

그래서 scikit-learn 에서는 fit 대신에 사용할 수 있는 partial fit 을 제공한다.


이게 큰 data 를 여러개의 작은 조각으로 나눠서 작은 조각들을 처리해 나가는 것이다. 이를 통해서 모든 data 가 RAM 에 load 될 필요가 없어서 큰 data 를 처리할 수 있다.



pickle/unpickle

trained 된 model 을 저장해 놓을 수 있다. 이러면 매순간 predict 할 때마다 다시 train 하지 않아도 된다. 이것을 python 에서 pickle 이라 표현하는데, 이것을 위해 joblib.dump 와 joblib.load 를 제공한다. 이 녀석은 model 을 file 로 저장할 수 있게 해준다.

이 pickled 된 file 은 문제가 발생할 여지가 있다. 그래서 아래 2가지를 지키라고 한다.
  1. 절대 믿을 수 없는 data 를 unpickle 하지 마라
  2. 특정 버전의 scikit-learn 에서 save 된 Model 들은 다른 버전에서 load 되지 않을 수 있다.
pickle/unpickle 에 대한 자세한 이야기는 아래 동영상에서 확인할 수 있다.



Source code





See Also




Reference

  1. Python Extension Packages for Windows - Christoph Gohlke
  2. http://stackoverflow.com/a/37281256
  3. Riding on Large Data with Scikit-learn | Open Data Science
  4. We make the software, you make the robots - O'Reilly Radar
  5. Out-of-core classification of text documents — scikit-learn 0.17.1 documentation
  6. 6. Strategies to scale computationally: bigger data — scikit-learn 0.17.1 documentation
  7. Tcl doesn't work inside a virtualenv on Windows · Issue #93 · pypa/virtualenv · GitHub


[컴][머신러닝] Strategies to scale computationally: bigger data





아래는 6. Strategies to scale computationally: bigger data — scikit-learn 0.17.1 documentation 의 내용을 번역했다.



6.1. Scaling with instances using out-of-core learning


Out-of-core learning 은 RAM 용량보다 더 큰 data 를 통해 learn 할 때 사용하는 기술이다. 대략적으로 아래같은 기술을 사용한다.

  1. instance를 stream 으로 만드는 것
  2. 이 instance 에서 feature 들을 추출(extract) 하는 것
  3. incremental algorithm(점진적인 알고리즘)

6.1.1 Sreaming instances

기본적으로 file들, database, network stream 에서 instance 들을 만들어내는 reader 들일 것이다. 그러나 자세한 이야기는 이 문서의 범위를 넘어간다.

6.1.2. Extracting features

scikit-learn 에 feature 추출을 하는 부분은 구현되어 있다. 하지만 "data 에 대한 vectorization 작업하는 위치"와  "feature 나 값들의 집합이 미리 알려져 있지 않은 부분"에 대해서는 작업을 해줘야 한다.


만약 application 관점에서 data 에 대해 여러개의 pass 들을 만드는 것이 합리적이면 stateful vectorizer 를 사용하는 것은 가능하다.
그렇지 않으면 stateless feature extractor 를 사용해야 하는데 이것이 어렵다. 요즘 선호되는 방식은 hashing trick 이라 불리는 것이다.
scikit-learn 에 구현되어 있는데,

  • sklearn.feature_extraction.FeatureHasher 는 python dicts 들로 이뤄진 list 로 표현된 categorical 변수들의 data set 에 사용할 수 있고,
  • sklearn.feature_extraction.text.HashingVectorizer 는 text documents 에 사용할 수 있다.

6.1.3. Incremental learning

모든 알고리즘이 전체를 파악하지 않고서는 배울 수 없다.
partial_fit API 을 구현한 모든 estimator 들은 후보자들이다.(아래 리스트 참조)

instance 들의 mini-batch 로 부터 점차적으로 배우는 능력(때때로 이것을 online learning 이라 부른다.) 은 out-of-core learning 에서 중요한 부분이다. 알다시피 어떤 주어진 시간에도 메인메모리에 오직 instance 들의 작은 부분만 있는 것만을 보장하기 때문이다.

relevancy 와 메모리 footprint 의 균형을 맞추는 적절한 mini-batch 의 size 를 선택하는 것은 약간의 조율 작업을 필요로할 수 있다.

estimator 리스트

  • Classification
    • sklearn.naive_bayes.MultinomialNB
    • sklearn.naive_bayes.BernoulliNB
    • sklearn.linear_model.Perceptron
    • sklearn.linear_model.SGDClassifier
    • sklearn.linear_model.PassiveAggressiveClassifier
  • Regression
    • sklearn.linear_model.SGDRegressor
    • sklearn.linear_model.PassiveAggressiveRegressor
  • Clustering
    • sklearn.cluster.MiniBatchKMeans
  • Decomposition / feature Extraction
    • sklearn.decomposition.MiniBatchDictionaryLearning
    • sklearn.decomposition.IncrementalPCA
    • sklearn.cluster.MiniBatchKMeans

리스트중에 classification 에 대해서, 약간 언급해야 할 중요한 것은 비록 stateless feature extraction routine 이 새롭거나 보이지 않는 속성(attribute)들을 다룰 수 있을 수 있지만,
점진적인 learner , 그 자체는 새롭거나 보이지 않는 target 들의 class 들을 다룰 수 없을 것이다.
이 경우에 우리는 모든 가능한 class 들을 처음 partial_fit 을 호출할 때 classes parameter 를 통해서 넘겨줄 수 있다.
(역자: stateless feature extraction 으로 새로운 feature 들을 뽑아내는 것은 문제가 없지만, 이 feature 를 어떤 class 로 분류해야 하는데, 이 때 새로운 class 를 알아서 learner 가 만들 수는 없다. 그러므로 이를 위해서 partial_fit 을 처음 call 할 때 classes= 를 통해서 모든 가능한 class 들을 넣어줘야 한다.)

6.1.3. Incremental learning

적절한 알고리즘을 선택할 때 고려해야 할 다른 부분은 모든 알고리즘들이 시간이 지남에 따라 각각의 예제에 대한 중요도가 변한다.

다시말하면, Perception 은 여전히 나쁘게 labeled 된 예제들에 민감하다. 심지어 많은 예제를 처리한 이후에도 그렇다. 반면에 SGD* and PassiveAggressive* family 들이 이런 요소에 좀 덜 민감하다.

반대로, 이후에는 또한 "너무 다름" 에 대해 중요도를 덜 부여하는 경향이 있다. 그렇지만, 시간이 지남에 따라 learning rate 가 감소할 때 stream 의 뒷부분에 적절하게 labeled 된 예제들이 있을때는 그렇지 않다.(해석이 불분명)

[컴][머신러닝] Feature extraction



4.2. Feature extraction — scikit-learn 0.17.1 documentation 의 글 중 일부를 번역해 놓는다.



Feature extraction

Feature extraction 은 text 또는 image 같은 임의의 data(arbitrary data) 를 machine learning 에 쓸수있는 "숫자와 관련된 feature 들(numerical features)"로 변환하는 특징을 갖는다. [ref. 1]


Text feature extraction

The Bag of Words representation

text content 에서 numerical feature 를 추출하기 위해 scikit-learn 에서 다음 3개의 utility 를 제공한다.

  • tokenizing : 이건 문자열을 token 들로 쪼개는 것이다.
  • counting : 각 문서(document) 의 토큰이 몇번 나왔는지를 세는 것
  • normalizing and weighting with diminishing importance tokens that occur in the majority of samples / documents.
tokenizing, counting, nomalizing 을 하는 이 특정 전략을 bag of words 라 한다.

이 전략에서 feature 와 sample 의 정의는 아래와 같다.

  • feature : 여기서 feature 는 "각각의 token의 발생 빈도" 이다.
  • sample : 모든 token 의 빈도들을 갖고 있는 vector 는 다변수의 sample 로 여겨진다.
참고로, text documents 더미를 numerical feature vector 들로 변환하는 것을 vectorization 이라 한다.


"Bag of words" 표현(representation) 또는 "Bag of n-grams" 표현 이라 얘기한다.
여기서 document 는 word 의 occurrence로만 표현된다. 단어의 상대적인 위치 정보는 무시한다.


...

Limitations of the Bag of Words representation

자세한 이야기는 link 를 이용하자. 대략적으로 Bag of words representation 의 한계를 이야기하면, 같은 의미의 단어인데,

  • 철자가 틀렸거나,
  • 복수형등으로 조금 변형된 상태

에서도 다른 단어로 처리하게 되는 것이다. 이런 요소로 classification 의 정확도가 떨어진다. 이런 것을 극복하기 위해 "n-grams" 를 사용하게 된다.

이건 단어 하나를 그대로 하나의 token 으로 인식해서 판별하는 것(n-gam 0)이 아니라, 그것을 여러개의 combination 을 만든다. 예를 들어,
"A T T C A" 라는 문장이 있다면, 이것을 unigram(n-gram 0) 으로 분할 하면,
A, T, T, C, A
로 나눠서 검사를 하는데, bigram(n-gram 1) 로 분할하면,
AT, TT, TC, CA
로 나눠서 이것들을 검사하게 된다.

이렇게 n-gram 을 vectorizer 의 parameter 로 지정해 줄 수 있다. 자세한 것은 link 를 참고하자.



Vectorizing a large text corpus with the hashing trick

이제까지 언급한 vectorization 방법들(CounterVectorizer, TfidfVectorizer 등등) 은 메모리 안에서 token 들을 "정수 feature의 인덱스"에 mapping 했다. 근데 이게 큰 dataset 을 처리할 때 문제가 있다.
  • 더 큰 크기의 문서를 다루면, 많은 더 많은 단어들이 사용되고 이게 또 메모리를 더 많이 사용하게 된다.
  • fitting 은 원본 dataset 에 비례하는 크기의 중간 데이터 구조에 대한 메모리 할당을 필요로 한다.
  • word-mapping 을 만드는 것은 dataset 를 전부 읽는 과정이 필요하다. 그래서 text classifier 를 특히 온라인 등의 환경에 맞우는 것은 불가능하다.
  • 큰 vocabulary_ 를 가지고 vectorizers 를 pickling 과 un-pickling 하는 것은 매우 느릴 수 있다.(일반적으로 같은 크기의 NumPy array 같은 flat data structures 를 pickling / un-pickling 하는 것보다 훨씬 느리다.)
  • vocabulary_ 속성은 공유되는 state 로 하고 "잘 만들어진 동기화 장벽(synchronization barrier)"를 이용해서 vectorization 작업을 concurrent 한 sub task 로 분리하는 것은 쉽지 않다.
    token 문자열 을 feature index 에 mapping 하는 것은 각 token 의 첫 occurrence 의 순서에 달려있다. 그래서 공유되어야만 한다. 그런데 이것은 잠재적으로 councurrent worker들의 sequential variant 보다 더 느리게 만들정도로 성능에 해를 끼친다.


sklearn.feature_extraction.FeatureHasher class 에 구현되어 있는 hashing trick (Feature hashing) 과 CountVectorizer 의 text preprocessing,  tokenization feature 들과 결합해서 이 한계를 극복할 수 있다.


Feature hasing

machine-learning 에서 feature hashing 은 hashing trick 으로 알려져 있다.
빠르고, space 효율적인 feature 를 vetorize 하는 방법이다. 즉, 임의의 feature 들을 vector 안의 index 로 바꿔주는 작업이다.
hash function 를 feature 들에 적용한다. 그리고 그들의 hash 값들이 바로 index 로 이용된다. 중간에 hash 와 array 의 index 를 다시 mapping 하는 부분을 두지 않는다.

보통 document 가 있으면 이것을 word 로 쪼개서 matrix 를 만들게 된다. 그러면 하나의 row 가 하나의 document 를 뜻하게 되고, column 이 한개의 word 를 뜻하게 된다. 이 경우에 word 에 해당하는 index 가 무엇인지를 알려주기 위해 index table 이 필요하다. 일반적으로 learning time 또는 그 전에 training set 의 vocabulary 에 대한 dictionary 를 하나 만들게 된다.


1st doc : Nam is working
2nd doc : Nam is not working

         Nam     is  working   not
1st doc.  1       1     1       0
2nd doc.  1       1     1       1

dictionary = {
 'Nam': 0,
 'is': 1,
 'working': 2,
 'not': 3
}


value = matrix[1][dictionary['Nam']]

 |
 |
 |
 \/
 
value = matrix[1][hashFunc('Nam')]
이것의 문제는 document 크기가 크거나, document 가 많아져서, training set 이 커지고, 그 안의 vocabulary 가 많아지면, dictionary 를 만들기 위해 더 많은 memory 가 필요하다.

이렇게 dictionary 를 만드는 대신에 hashing trick 을 이용하는 feature vectorizer 는 hash function 을 feature(여기선 word 가 되겠다.) 에 적용해서 "미리 정해진 길이의 vector" 를 만들 수 있다.
hash value 를 feature index 로 사용해서 그 index 에 있는 vector 값을 업데이트 한다.(hash value 가 vector size N 을 넘지 않게 하기 위해 mod N 을 해준다.)



이 경우에, collision 이 생길 수 있다. 이를 위해 또 다른 hash function을 제공한다.(그러나 이것으로 collision 이 해결되지는 않을 듯 한데....)



Reference

  1. 4.2. Feature extraction — scikit-learn 0.17.1 documentation
  2. Feature hashing - Wikipedia, the free encyclopedia