※ 본 내용은 stanford에서 제공하는 cs231n 강의, 강의자료를 바탕으로 작성하였습니다.

 

Lecture 4 에서는 역전파(Backpropagation) 과 Neural Network에 대해 다루고 있다. 

<Backpropagation>

- Backpropgation이란?

Backpropagation이란, 계산 그래프와 연쇄 법칙(chain rule)을 통해 미분을 간단하게 하는 방법이다.

계산 그래프

먼저 간단한 계산 그래프는 위와 같다.

f = (x+y)z의 계산과정에서, 각 연산을 node 단위로 나눠 표현할 수 있다.

 

이렇게 하면 각 node 별 미분 값(local 미분 값)은 간단하게 구할 수 있는데, 이에 연쇄법칙까지 적용하면 각 변수에 대한 미분을 쉽게 구할 수 있다는 것이 역전파의 아이디어이다. 

(물론 f = (x+y)z 는 이러한 단계를 거치지 않아도 쉽게 미분할 수 있지만, 복잡한 경우 역전파를 이용하면 훨씬 간단하게 계산할 수 있다.)

 

역전파 적용

빨간색으로 표현된 값이 역전파를 통해 계산된 미분값이다. 

순전파와 반대의 순서대로 1에서 부터 시작하여 local 미분값과 역전파를 통해 전달되는 값을 곱하면 전체 결과에 대한 해당 노드의 미분값을 계산할 수 있다.

 

역전파 예시2

조금 더 복잡한 함수에서 역전파를 통해 미분을 수행한 예시이다.

간단한 미분과 곱셈을 계속해서 수행하면 복잡한 미분을 수행할 수 있다.

 

- Backpropagation for Vectorized Operations

input과 output이 vector인 경우에도 역시 backpropagation을 적용할 수 있다.

이때 input과 미분의 shape는 동일하다.

 

행렬곱의 결과의 L2 norm을 구하는 과정에 대한 미분 과정을 통해, 그 예시를 살펴보겠다. 

2x2 행렬 W와 크기가 2인 vector x의 내적결과

에 대한 L2 norm을 구하는 계산 그래프이다.

 

먼저 L2 노드에 대한 미분 값을 살펴보면, 

$ \frac{\partial f}{\partial q_i} = 2q_i $ 라는 것은 $ f(q) = q_1^2 + ... + q_n^2$ 이라는 점을 생각하면 쉽게 이해할 수 있고, 

위와 같은 벡터의 미분을 나타낼 때  $ \nabla_qf $ 와 같이 나타낸다고 한다. (역삼각형은 '나블라'라고 한다.)

$ 2q $와 역전파를 통해 전달되는 값 1.00을 곱해주면 미분값이 된다. 

 

 

다음으로 $ \frac{\partial f}{\partial W} $를 구하는 과정이다.

$ \frac{\partial q_k}{\partial W_(i, j) }$ 표현이 조금 복잡한데,

우선 $ 1_{k = i}$는 k == i 인 경우 1이라는 것을 의미하고, 결국 아래 결과를 풀어쓴 것이다.

$ q_1 = W_{(1,1)}x_1 + ... + W_{(1, n)}x_n$ 이라는 점을 생각해보면 쉽게 미분 결과에 대해 이해할 수 있을 것이다.

마지막으로 역전파를 통해 전달된 값과 local 미분값을 곱해주면 $ \frac{\partial f}{\partial W}$를 구할 수 있다.

 

q에 대한 미분도 동일한 방법으로 계산할 수 있다.

 

<Neural Network>

앞서 하나의 weight로 구현한 linear classifier를 다뤘는데, Neural Network에서는 Weigth, Layer를 여러 층 쌓는다. 

템플렛을 거친 결과에 대해 또 새로운 템플렛과 비교해보는 과정이라 생각해보면 된다. 

예를 들어 첫 템플릿($ W_1$)에서는 모양에 대해 비교하고, 두 번째 템플렛($ W_2$)에서는 방향에 대해 비교해보는 등의 방식으로 더 정교하게 예측이 가능해질 것이다. 

 

lecture4에서는 자세한 개념에 대해서는 다루지 않았다. 

 

이러한 neural network의 구조는 뉴런에서 영감을 얻었다고 한다.

각각의 뉴런은 impulses를 전달받고 해당 수치들에 대해 어떠한 연산을 수행한 결과(ex)NN에서 Weight를 곱하는 것)가 임계점 이상이면 다음 뉴런으로 신호를 전달하고, 그렇지 않으면 신호를 전달하지 않는다고 한다. 

 

그러나 엄밀히는 뉴런과 NN이 정확히 동일하지는 않다고 한다.

우선 뉴런에 여러 타입이 있고, 처리하는 연산이 Linear하게 Weight를 곱하는 것과 다르다는 등의 이유가 나와있다.

 

뉴런에서 임계점을 기준으로 신호를 전달하고 말지를 결정하는 것처럼, NN에서도 연산 결과를 다음 층으로 어떻게 전달할지 activation function을 통해 결정한다. 

위 그림처럼 다양한 종류가 있고 앞으로의 강의에서 계속해서 살펴볼 것이라고 한다. 

 

'Computer Vision > cs231n' 카테고리의 다른 글

[cs231n] Assignment1-Q5  (0) 2022.01.01
[Assignment1 - Q4] 2-layer NN  (0) 2022.01.01
[Assignment1 - Q3] Softmax  (0) 2021.12.30
[Assignment1 - Q2] SVM  (0) 2021.12.30
[Lec 3] Loss Functions and Optimization  (0) 2021.12.30


※ 본 내용은 stanford에서 제공하는 cs231n 강의, 강의자료를 바탕으로 작성하였습니다.

 

Q3에서는 Softmax loss의 구현과 SGD에 대해 다루고 있다. 

Q2와 비슷한 구조로, naive하게 loss와 미분을 계산하는 것에서 fully vectorized한 코드까지 작성하는 것을 다룬다.

(SGD를 이용한 train의 경우 Q2와 동일하므로 생략)

 

<Softmax>

- Setup

 

마찬가지로 CIFAR10 dataset을 load하여 사용하고, shape는 위와 같다.

 

- Naive하게 loss와 미분(dW) 계산하기

def softmax_loss_naive(W, X, y, reg):
    """
    Softmax loss function, naive implementation (with loops)

    Inputs have dimension D, there are C classes, and we operate on minibatches
    of N examples.

    Inputs:
    - W: A numpy array of shape (D, C) containing weights.
    - X: A numpy array of shape (N, D) containing a minibatch of data.
    - y: A numpy array of shape (N,) containing training labels; y[i] = c means
      that X[i] has label c, where 0 <= c < C.
    - reg: (float) regularization strength

    Returns a tuple of:
    - loss as single float
    - gradient with respect to weights W; an array of same shape as W
    """
    # Initialize the loss and gradient to zero.
    loss = 0.0
    dW = np.zeros_like(W)

    #############################################################################
    # TODO: Compute the softmax loss and its gradient using explicit loops.     #
    # Store the loss in loss and the gradient in dW. If you are not careful     #
    # here, it is easy to run into numeric instability. Don't forget the        #
    # regularization!                                                           #
    #############################################################################
    # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    # -- loss, dW --
    num_train = X.shape[0]

    for i in range(num_train) :
      score = np.dot(X[i], W)
      score = np.exp(score)
      score = score / np.sum(score)

      X_temp = np.repeat(X[i].reshape(-1, 1), 10, axis = 1)

      dW += X_temp*score / num_train # 3072x10
      dW[:, y[i]] += -X[i] / num_train

      loss += -np.log(score[y[i]])

    dW += 2*reg*W

    loss /= num_train
    loss += reg*np.sum(W*W)
    
    # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    return loss, dW

loss와 미분을 naive하게 구현하는 코드는 위와 같다. 

 

Softmax Loss

for문을 사용하여 loss는 직관적으로 구현되어 있다. 계산 방법을 순서대로 코드화한 것 뿐이라 크게 어렵지 않다.

 

● 미분(dW)

처음엔 Softmax에서 Weight(W)에 대한 미분을 어떻게 계산해야 할지 감이 안왔지만,

SVM에서 했던 것과 유사하게 loss에 더해지는 값을 풀어쓴 후 미분할 수 있었다. 

 

각 데이터마다 loss에 더해지는 값은 다음과 같다.

(s_x는 x-th class에 대한 prediction score, y_i는 정답 label을 의미한다.)

 

이를 좀 더 풀어보면, 

위와 같이 정리할 수 있다.

 

따라서 각 데이터마다 $ dW^{(i)}$에 대한 미분은 위식을 $ W^{i}$에 대해 미분한 결과와 같다.

score가 데이터와 Weight의 내적인 점을 고려하여 미분을 진행하면 최종적으로 다음과 같은 식이나온다. 

 

$ dW^{(i)} += x^{(n)}*probability(i) $ (i가 정답 label이 아닌 경우)

$ dW^{(i)} += -x^{(n)} + x^{(n)}*probability(i) $ (i가 정답 label인 경우)

다항식과 log로 이뤄진 복잡하지 않은 식이라, 자세한 미분과정은 생략하였다.

 

추가적으로 data의 수로 나눠주고, regularization term에 대한 미분을 더해주면 미분 계산이 완료된다.

코드는 단순히 위 내용을 구현한 내용이라 자세히 설명하진 않겠다.

 

- Inline Question 1

위 결과가 -log(0.1)과 비슷한지 검사하는 내용이 있었는데, 왜 해당 값과 비교하는지 설명하라는 질문이 있었다.

 

- Fully vectorize하여 loss와 미분 계산하기

def softmax_loss_vectorized(W, X, y, reg):
    """
    Softmax loss function, vectorized version.

    Inputs and outputs are the same as softmax_loss_naive.
    """
    # Initialize the loss and gradient to zero.
    loss = 0.0
    dW = np.zeros_like(W)

    #############################################################################
    # TODO: Compute the softmax loss and its gradient using no explicit loops.  #
    # Store the loss in loss and the gradient in dW. If you are not careful     #
    # here, it is easy to run into numeric instability. Don't forget the        #
    # regularization!                                                           #
    #############################################################################
    # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    #loss
    score = np.dot(X, W) # 500 x 10
    score = np.exp(score)
    score = score / np.sum(score, axis = 1).reshape(-1, 1)
    loss = np.sum(-np.log(score[np.arange(X.shape[0]), y])) / X.shape[0] + reg*np.sum(W*W)

    
    #dW
    score[np.arange(X.shape[0]), y] -= 1 #not valid from here
    dW += np.dot(np.transpose(X), score) / X.shape[0]  # 3072x10
    dW += 2*reg*W

    # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    return loss, dW

for문을 사용하지 않고, vectorization을 통해 구현한 코드는 위와 같다. 

 

● Loss

loss의 경우 사실 처음부터 vectorized version으로 작성하는 것이 편했다.

score의 shape가 어떻게 결정되는지만 이해했다면 쉽게 이해할 수 있을 것이다.

앞서 각 데이터별로 for문을 거치며 계산한 과정을 행렬에 저장된 결과를 보고 계산한 것 뿐이다.

 

● 미분

 앞서

위와 같은 수식을 확인할 수 있었다.

 

i번째 W에 대한 미분을 구하려면 n번째 데이터와 해당 데이터의 i-th class에 대한 score의 곱을 모든 데이터에 대해 더해주면 된다. i가 정답인 경우는 probability에 -1을 더해줘서 곱하면 된다.

 

앞서 Q2에서 모든 데이터에 각각 어떤 값을 곱하고, 그 합을 구하는 것을 for문을 사용하지 않고 구현하는 코드가 있었고, 해당 코드와 동일한 원리로 행렬곱을 이용해 계산할 수 있었다. 

X의 전치행렬과 확률이 계산된 행렬을 곱해주면 되었다. (정답 label인 경우 확률에 -1을 해줘야한다.)

 

위 그림은 $ dW^{(0)}$를 계산하는 예시로, 그림을 통해 확인하면 보다 쉽게 이해할 수 있을 것이다. 

 

마지막으로 regularization term에 대한 미분을 더해주면 fully vectorized된 미분 계산 코드를 완성할 수 있다.

'Computer Vision > cs231n' 카테고리의 다른 글

[Assignment1 - Q4] 2-layer NN  (0) 2022.01.01
[Lec 4] Backpropagation and Neural Network  (0) 2021.12.30
[Assignment1 - Q2] SVM  (0) 2021.12.30
[Lec 3] Loss Functions and Optimization  (0) 2021.12.30
[Assignment 1 - Q1] KNN  (0) 2021.12.29

 


※ 본 내용은 stanford에서 제공하는 cs231n 강의, 강의자료를 바탕으로 작성하였습니다.

 

Q2에서는 SVM loss의 계산과 미분 그리고 SGD를 통한 optimization에 대해 다루고 있다.

 

 

<SVM>

- setup

 

X_train, X_val, X_test, X_dev 의 shape는 위와 같다. 

 

- Naive하게 svm loss와 dW 계산하기

def svm_loss_naive(W, X, y, reg):
    """
    Structured SVM loss function, naive implementation (with loops).

    Inputs have dimension D, there are C classes, and we operate on minibatches
    of N examples.

    Inputs:
    - W: A numpy array of shape (D, C) containing weights.
    - X: A numpy array of shape (N, D) containing a minibatch of data.
    - y: A numpy array of shape (N,) containing training labels; y[i] = c means
      that X[i] has label c, where 0 <= c < C.
    - reg: (float) regularization strength

    Returns a tuple of:
    - loss as single float
    - gradient with respect to weights W; an array of same shape as W
    """
    dW = np.zeros(W.shape)  # initialize the gradient as zero

    # compute the loss and the gradient
    num_classes = W.shape[1]
    num_train = X.shape[0]
    loss = 0.0
    for i in range(num_train):
        scores = X[i].dot(W)
        correct_class_score = scores[y[i]]
        for j in range(num_classes):
            if j == y[i]:
                continue
            margin = scores[j] - correct_class_score + 1  # note delta = 1
            if margin > 0:
                loss += margin
                dW[:, y[i]] += -X[i] / num_train
                dW[:, j] += X[i] / num_train

    # Right now the loss is a sum over all training examples, but we want it
    # to be an average instead so we divide by num_train.
    loss /= num_train

    # Add regularization to the loss.
    loss += reg * np.sum(W * W)

    #############################################################################
    # TODO:                                                                     #
    # Compute the gradient of the loss function and store it dW.                #
    # Rather that first computing the loss and then computing the derivative,   #
    # it may be simpler to compute the derivative at the same time that the     #
    # loss is being computed. As a result you may need to modify some of the    #
    # code above to compute the gradient.                                       #
    #############################################################################
    # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
    #pass
    dW += W*2*reg

    # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    return loss, dW

2중 for문을 이용해서 loss와 미분(dW)를 계산하는 코드이다.

 

loss의 경우 2중 for문을 통한 구현은 직관적이고 어렵지 않기 때문에 생략한다.

 

미분의 경우 loss 의 식을 천천히 살펴보면 된다. 

 

loss에 값이 추가되는 경우는 margin > 0인 경우이고, 그때 더해지는 값, margin은 다음과 같다. 

$ loss += (x^{(n)}W^{(j)} - x^{(n)}W^{(y_i)} + 1) $

(j : 잘못 예측한 class, $ y_i$ : 정답 class)

따라서 $ W^{(j)}$에 대한 미분값으로는 $ +x^{(n)}$, $ W^{(y_i)}$에 대한 미분값으로는 $ -x^{(n)}$이 더해질 것이다.  

 

(어차피 선형수식으로 계산이 되기 때문에 각 연산마다 개별적으로 dW += ~ 를 연산해도 된다.)

 

마지막으로 data의 수로 나눠주고, 마지막에 regularization에 대한 미분을 더해주면 된다.

 

 

- fully vectorize하여 loss와 미분(dW) 계산하기

def svm_loss_vectorized(W, X, y, reg):
    """
    Structured SVM loss function, vectorized implementation.

    Inputs and outputs are the same as svm_loss_naive.
    """
    loss = 0.0
    dW = np.zeros(W.shape)  # initialize the gradient as zero

    #############################################################################
    # TODO:                                                                     #
    # Implement a vectorized version of the structured SVM loss, storing the    #
    # result in loss.                                                           #
    #############################################################################
    # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    mul = np.dot(X, W) #500x10
    S_correct = mul[np.arange(X.shape[0]), y].reshape(-1, 1) # 500x1, 맞는 label 들의 score

    S_gap = (mul - (S_correct - 1)).clip(0)
    S_gap[np.arange(X.shape[0]), y ] =0
    loss = (np.sum(S_gap) / X.shape[0]) + reg*np.sum(W*W)

    # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    #############################################################################
    # TODO:                                                                     #
    # Implement a vectorized version of the gradient for the structured SVM     #
    # loss, storing the result in dW.                                           #
    #                                                                           #
    # Hint: Instead of computing the gradient from scratch, it may be easier    #
    # to reuse some of the intermediate values that you used to compute the     #
    # loss.                                                                     #
    #############################################################################
    # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    #pass
    Z = np.where(S_gap > 0, 1, 0)
    Z[np.arange(X.shape[0]), y] = -np.sum(Z, axis = 1) # 정답보다 score가 높은 lable의 수
    dW += np.dot(X.T, Z) / X.shape[0]
    dW += (2*reg*W)




    # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

    return loss, dW​

● loss

  1. $ XW $의 결과로 score가 계산되고(code상으로는 mul이라고 표시) 

  2. 맞는 label의 score와 margin을 고려해서 각 행에 빼준다.

  3. clip을 통해 0 이하의 값은 0으로 바꾸고, 맞는 label의 값도 0으로 바꿔준다.

위 3과정만 거치면 margin값만 남게되고, np.sum()을 통해 margin을 전부 더해주면 loss가 계산된다. 

 

미분(dW)

미분을 fully vectorize하는 것은 꽤 복잡하다.

처음엔 구현을 하지 못했고, 코드를 참고한 후 이해하는 방향으로 학습했다.

덕분에 다음 과제인 softmax classifier에서 비슷한 내용은 스스로 구현할 수 있었다.

(https://github.com/hohyun312/cs231n-stanford 의 코드를 사용하였습니다.)

 

먼저 기본적으로 계산 원리는 naive하게 구현한 원리를 그대로 이용한다. 

 

$ dW^{(i)}$ = ($ W^{(i)}$와 곱해져 margin > 0이 된 $ x^{(n)}$들의 합)

                  - ( ($ i$-th label이 정답이고, 그 외 class에 대한 margin > 0 인 label의 수 x $ x^{(n)}$) 의 합 )

 

naive 방식에서 하나의 데이터마다 더하거나 뺐던 값을 모든 데이터에 대해 정리하면 위와 같이 나타낼 수 있다. 

위식을 vectorize하는 것이 문제였는데, 각 $ x^{(n)}$에 대한 합을 for문을 사용하지 않고 구현하는 방법이 떠오르지 않았다.

결과적으로, 행렬곱의 연산 중 다음과 같은 특징을 이용하면 됐다.

보통 행과 열의 내적에만 집중을 하지만, column간의 연산에도 위와 같은 관계가 있다.

 

이제 다시 코드를 미분을 계산하는 코드를 살펴보면 먼저 Z에는 margin > 0 인 score에만 1이 masking되고,

(Z.shape = (n_data, class의 수))

 

다음 줄에서는 정답 label의 score가 자리에는 정답 label이 아닌데 margin > 0 인 label의 수를 구한다.

(이 경우 뺴야하기 때문에 음수로)

 

이제 X의 전치행렬과 Z를 곱하기만 하면 dW가 계산된다. (물론 regularization의 미분도 더해줘야  한다.)

 

다소 이해가 안갈수 있어 위 특징을 미분의 연산에 그대로 적용한 예시를 한 번 더 살펴보면 다음과 같다. 

데이터의 수를 4개로 간소화한 예시이다.

Z에서 1인 경우는 $ W^{(0)}$와 곱해져서 margin > 0이 된 경우이고, Z의 4행 1열의 -3은 그 외 3개의 class가 모두 margin > 0이라는 것을 의미한다. 

 

$ dW^{(i)}$ = ($ W^{(i)}$와 곱해져 margin > 0이 된 $ x^{(n)}$들의 합)

                  - ( ($ i$-th label이 정답이고, 그 외 class 중 margin > 0 인 label의 수 x $ x^{(n)}$) 의 합 )

위 설명과 일치되도록 계산이 되는 것을 확인할 수 있다. 

 

<SGD>

SGD의 경우 구현의 문제로 크게 어렵진 않기 때문에 자세한 내용은 생략한다.

 

hyperparameter를 조정하여 validation accuracy를 높이는 실험이 포함되었는데, 다음과 같은 결정과정을 따랐다.

 

1. loss가 계속하여 감소되지 않으면 learning rate를 줄인다.

2. loss는 줄었으나 validation accuracy는 감소하면 regulization parameter를 증가시킨다. 

 

문제에서 hyperparameter를 잘 조정하면 0.39이상의 validation accuracy가 가능하다는 hint가 있어서,

해당 수치가 나올 때 까지 위 과정을 반복하여 hyperparameter를 조정할 수 있었다. 

'Computer Vision > cs231n' 카테고리의 다른 글

[Lec 4] Backpropagation and Neural Network  (0) 2021.12.30
[Assignment1 - Q3] Softmax  (0) 2021.12.30
[Lec 3] Loss Functions and Optimization  (0) 2021.12.30
[Assignment 1 - Q1] KNN  (0) 2021.12.29
[Lec2] KNN, Linear Classifier  (0) 2021.12.29


※ 본 내용은 stanford에서 제공하는 cs231n 강의, 강의자료를 바탕으로 작성하였습니다.

 

lecture3 에서는 loss function과 optimization(train) 에 대해 다루고 있다.

 

<Loss Function>

Loss Function은 현재 모델이 얼마나 좋은지 알려준다. (= 얼마나 오류가 있는지)

 

Loss Function

앞서 다룬 Linear Classifer의 예측 결과가 위와 같다고 할 때, 현재 모델의 성능은 우측 하단의 Loss Function과 같이 나타낼 수 있다. 

 

이번 강의에서는 SVM, Softmax loss function에 대해 다루고 있다.

 

- SVM loss function

SVM Loss Function

$ s_{y_i}$는 정답 class의 score를 의미한다. 즉, (정답 class의 score) - (정답이 아닌 class의 score + 1)의 합이 Loss 가 된다.

여기서 '+1'은 임의의 수로, 다른 값이 사용될 수 있다. 정답 class의 score가 다른 class보다 넉넉하게 클 때 penalty가 없는 원리이다

 

SVM Loss 계산

실제 계산 과정을 확인해볼 수 있다. 

 

● Regularization

SVM Loss를 0으로 만드는 weight를 찾았을 때, 그러한 W는 유일하지 않다. 

그러나 우리는 모델이 간단하기를 (Weight가 작기를) 바라기 때문에 Loss function에 regularization 항인 $ \lambda R(W)$ 을 더해준다.

W가 커지는 것에도 penalty를 준다고 이해하면 된다. ( $ \lambda $는 regularization strength로 hyperparmeter이다.)

 

Regularization에도 L1과 L2 regularization이 존재한다. 

 

어떠한 regularization을 사용하는지에 따라 weight가 다르게 학습될 수 있다.

예를 들어,

$ x = [1, 1, 1, 1]$, 

$ w1 = [1, 0, 0, 0]$ 과 $ w2 = [0.25, 0.25, 0.25, 0.25]$ 두 개의 weight가 존재한다고 하자.

$ w^T_1x = w^T_2_x = 1$이지만 어떠한 regulaization을 사용하는지에 따라 선호되는 weight가 다르다. 

L2 regularization을 사용한다면 w2가 선호될 것이고, L1의 경우 두 weight 중 명확히 선호되는 값은 없을 것이다. 

 

그 외에도 여러 regularization 기법은 존재하고 이후에 계속하여 다룰 것이다. 

 

<Softmax Classifier>

 

Softmax Classifier

Softmax loss의 계산은 위와 같다. 먼저 모델에서 나온 score에 대해 exponential을 취해주고,

정답 (class의 score)/ (전체 score의 합) 에 -log를 취해준 값이 loss이다.

(이때 log를 취하기 전 값은 확률의 의미를 갖는다.)

 

-log 그래프는 0에 가까울 수록 무한대로 발산하고, 1에 가까울 수록 0에 수렴한다.

즉, 정답 class를 1에 가깝게 예측할수록 penalty를 적게 준다는 의미이다.

 

Softmax 와 SVM 차이

Softmax와 SVM의 차이에 대해 정리하면, 여러 차이가 있겠지만 대표적으로 다음과 같은 차이가 있다.

Softmax는 이미 맞게 예측하고 있다면 score가 약간 변하는 정도로는 loss가 변하지 않지만,

SVM은 조금이라도 차이가 발생하면 loss도 변한다.

 

<Optimization>

Weight를 optimzation하는 과정, 즉 train 과정은 Gradient Descent 기법을 이용한다. 

$ W := W - \alpha \frac{dL}{dW}$

 

그렇다면 어떻게 미분을 계산할까.

 

- Numerical Method

미분의 개념을 이용해서 미분을 수행하는 방법이다. 

 

silly한 방법이라고 소개하고 있다. 기본적으로 계산이 많이 필요하다.

 

- Analytic Method

Loss function은 W의 함수라는 점을 이용하여, 일반적인 미분식을 이용하는 방법이다.

 

 

앞서 말한 것처럼 Numerical method는 잘 사용하지 않고, Analytic method를 사용한다.

그러나 검증 차원에서 Numerical meethod를 계산해보는 것은 권장된다. (gradient check 라고 한다.)

 

- Stochastic Gradient Descent(SGD)

실제로 머신러닝에서는 매우 큰 데이터를 다루게 되고, 전체 데이터의 loss를 계산하는 것은 expensive하다.

따라서 minbatch를 이용하여 loss를 계산하고 학습하는 SGD가 자주 사용된다. 

 

- Image Feature

Image로부터 feature(색의 분포, 모서리 추출 등)를 추출하는 과정을 거친 후, 해당 feature에 대해서 학습을 진행하는 방식도 존재한다.

반면 이번 강의에서 다루려는 CNN 같은 경우는 데이터 그 자체로 학습을 하고, feature도 학습 중에 찾아낸다. 

'Computer Vision > cs231n' 카테고리의 다른 글

[Lec 4] Backpropagation and Neural Network  (0) 2021.12.30
[Assignment1 - Q3] Softmax  (0) 2021.12.30
[Assignment1 - Q2] SVM  (0) 2021.12.30
[Assignment 1 - Q1] KNN  (0) 2021.12.29
[Lec2] KNN, Linear Classifier  (0) 2021.12.29

+ Recent posts