본문 바로가기
Team Project/핸들랭(handlang)

프로젝트 관련 강의 수강 [모두의 딥러닝]

by 지누: 2019. 11. 11.

11월 13일 수요일까지 모두의 딥러닝 시즌1 완강

 

(모두의 딥러닝 시즌1 강의 중 KNN 알고리즘 요약 및  정리)

[KNN]

 

*image classification

: 입력 이미지를 미리 정해진 카테고리 중 하나인 라벨로 분류하는 것

: 어떻게? - 데이터 기반 방법론(input->learing->evalution)

: input(training set)- 입력은 N개의 이미지, K개의 클래스로 라벨화

: learning(training a classifier 혹은 learning a model ) 

: evaluation-새로운 이미지에 대한 어떤 라벨로 분류하는지를 보면서 성능 평가

 

*Nearest neighbor classifier 최근접 이웃 분류기

: 테스트 이미지로부터 모든 학습 이미지와 비교를 하고 라벨 값을 예상

: 두개의 이미지가 주어지면, 이미지를 각각의 픽셀 값으로 비교하고, 그 차이를 모두 더하는 방법

: 각각의 이미지에서 벡터값을 I1,I2라고 했을 때 벡터 간의 거리 L1 distance를 계산

                           d1(I1,I2)=∑p|Ip1Ip2|

: 각 픽셀간의 차이를 이용하는 것이기 때문에 두 이미지가 같은 경우에는 결과가 0이고, 다르다면 값은 커진다.

: 위의 내용을 코드에서 어떻게 구현하는지.

Xtr, Ytr, Xte, Yte = load_CIFAR10('data/cifar10/') # 제공되는 함수-데이터를 4개의 배열에 저장
#학습데이터, test데이터
#Xtr-트레이닝 set의 모든 이미지 저장
#Ytr-1차원 배열, 트레이닝 data의 label(0~9)저장
# 모든 이미지가 1차원 배열로 저장된다.
Xtr_rows = Xtr.reshape(Xtr.shape[0], 32 * 32 * 3) # Xtr_rows는 50000 x 3072 크기의 배열.
Xte_rows = Xte.reshape(Xte.shape[0], 32 * 32 * 3) # Xte_rows는 10000 x 3072 크기의 배열.

-> 모든 이미지를 배열의 각 행들로

nn = NearestNeighbor() # Nearest Neighbor 분류기 클래스 생성
nn.train(Xtr_rows, Ytr) # 학습 이미지/라벨을 활용하여 분류기 학습
Yte_predict = nn.predict(Xte_rows) # 테스트 이미지들에 대해 라벨 예측
# 그리고 분류 성능을 프린트한다
# 정확도는 이미지가 올바르게 예측된 비율로 계산된다 (라벨이 같을 비율)
print 'accuracy: %f' % ( np.mean(Yte_predict == Yte) )

-> classifier를 어떻게 학습시키고 평가하는지

-> accurancy(정확도)- 평가기준

                                 - 예측값이 실제와 얼마나 일치하는지 비율로 측정

-> train(X,y): 데이터(X)와 데이터가 실제로 속하는 라벨(y)를 입력으로 받음

            : 라벨들을 활용하여 어떤 모델을 만들지, 그 값들이 데이터로 어떻게 예측될지 알아내는

-> predict(X): 새로운 데이터로부터 라벨을 예측하는 함수

 

import numpy as np

class NearestNeighbor(object):
  def __init__(self):
    pass

  def train(self, X, y):
    """ X is N x D where each row is an example. Y is 1-dimension of size N """
    # nearest neighbor 분류기는 단순히 모든 학습 데이터를 기억해둔다.
    self.Xtr = X
    self.ytr = y

  def predict(self, X):
    """ X is N x D where each row is an example we wish to predict label for """
    num_test = X.shape[0]
    # 출력 type과 입력 type이 갖게 되도록 확인해준다.
    Ypred = np.zeros(num_test, dtype = self.ytr.dtype)

    # loop over all test rows
    for i in xrange(num_test):
      # i번째 테스트 이미지와 가장 가까운 학습 이미지를
      # L1 거리(절대값 차의 총합)를 이용하여 찾는다.
      distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)
      min_index = np.argmin(distances) # 가장 작은 distance를 갖는 인덱스를 찾는다.
      Ypred[i] = self.ytr[min_index] # 가장 가까운 이웃의 라벨로 예측

    return Ypred

-> L1 거리를 이용한 nearest neighbor classifier 구현

-> distance 선택에는 L1외에도 L2가 있다. 

   *L2 distance

     : 기하학적으로 두 벡터간의 유클리디안 거리를 계산하는 것

         

     : 픽셀간의 차를 구하고 각각에 제곱을 취한 다음 전부 더한 후, 제곱근을 취한다.

     : 위의 코드 중 distance 변수 부분을 아래와 같이 고치면 된다.

distances = np.sqrt(np.sum(np.square(self.Xtr - X[i,:]), axis = 1))

     : 결과, 정확도는 L1보다 조금 더 낮다.

-> L1 vs. L2

   : L2 L1에 비해 두 벡터간의 차가 커질 때 더 크게 반응한다.

   : L2는 하나의 큰 차이보단 여러 개의 적당한 차이를 더 선호

 

*Knn: K-Nearest Neighbor Classification

-> training data set에서 가장 가까운 하나의 이미지만 찾는 것(nearest neightbor)이 아니라 k개의 이미지를 찾아서 test 이미지의 라벨에 대해 투표하도록 하는.

-> k가 클수록 분류경계가 더 부드러워진다.

-> 더 나은 generalization(일반화) 성능

-k는 작을수록, 홀수일수록 좋다.

 

!!그렇다면 어떻게 k를 정하나.

->여러가지 distance 함수들(L1,L2) hyperparameters라고 한다.

->(중요) hyperparameters값을 조정하기 위해 test set을 사용하면 안된다.

->hyperparameters를 튜닝하는 방법 1-validation set사용

: training set 1)validation set(적은 수의 training set) 2)나머지 training set으로 나눈다.

: validation set은 모의test set이 되는 것이다.

: validation set으로 hyperparameters값을 조정

-> hyperparameters를 튜닝하는 방법 2-cross validation

  : training set의 크기가 작을 경우 좀 더 정교한 방식 hyperparameters값을 조정(튜닝)

: 어떤 k값이 더 좋은지를 여러가지 validation set에 실험해보고 성능확인

: 여러가지 그룹으로 나누어서 validation set을 바꿔가면서 

-> cross validation은 계산양이 많아서, 실제로는 방법1을 더 선호한다.

 

(by. DSC ewha | HandLang | 손수현)

댓글