0. Recap

 

 

 

 

1. Neural Networks

 

우리가 알고 있는 linear classifier의 수식은 위와 같다.

이때 차원을 집중해서 보자. Input x의 차원이 D일때, Weight matrix의 차원은 CxD이다. 여기서 C는 Class라고 생각하면 된다.

 

이번에는 2 layer Neural Network를 보자.

수식이 위와 같을 때, 이번에도 차원을 살펴보면 H가 새로 정의된 것을 볼 수 있다. 

H값을 통해 설계하는 hidden layer / nodes의 수가 정해진다.

 

그리고 또하나, max operation을 확인할 수 있는데, 이는 즉 W1, W2에 의한 linear operation 사이에 non-linearity가 추가된 것으로 볼 수 있다. 

 

 

레이어를 더 쌓아서 더 정교하게 만들 수도 있다.

 

 

이러한 Neural Network를 학습시킨다는 것은, 학습 데이터에 해당하는 템플릿을 배우는 것이다.

 

 

다시 수식을 더 살펴보면, 여기서 max function은 activation function의 역할을 한다고 할 수 있다.

Activation function은 Neural Network에 있어서 매우 중요한 역할을 하는데, 만약 max function이 없다고 가정해보자.

그러면 이 수식은 그저 linear function과 같은 역할을 할 뿐이다.

 

Activation functions

 

다양한 activation 함수들이 있는데 우리가 본 함수는 ReLU 함수이다.

매우 유명하고 자주 사용되나, 단점은 음수에 대해서는 모두 출력이 0이 되므로 dead neuron을 만들 수 있다는 점이다.

이를 해결하기 위한 방법으로 Leaky ReLU, ELU, GeLU, SiLU 등이 제시되었다.

 

Sigmoid, tanh 또한 자주 사용되는 activation function이지만, 그래프를 보면 기울기가 나타나는 범위가 narrow하기 때문에, gradient vanishing 문제로 이어질 수 있다는 문제가 있다.

따라서 두 함수는 neural network 중간에는 잘 쓰이지 않고, 마지막에 output을 binarize 하는 목적으로 종종 쓰인다.

 

 

정리하자면 Neural Network의 구조는 위와 같다.

Activation function을 정의하면 hidden layer에서 그 값을 계산하고 output을 내보내는 형태이다.

 

 

 

20 Lines의 파이썬 코드로 작성한 2-layer Neural Network이다.

 

 

Hidden layer의 node 개수 변화에 따른 분류이다.

뉴런이 더 많을수록, 더 복잡한 함수 구현 및 분류가 가능해진다.

 

 

여기서 주의해야 할 점은 hidden layer의 수 또는 뉴런의 수(Neural Network의 크기)를 regularizer로 사용해선 안된다는 것이다.

즉 overfitting이 발생했다고 해서 네트워크의 크기를 조절하는 게 아니라, 우리가 이전에 배웠던 regularization loss의 λ에 해당하는 값을 조절하는 게 훨씬 효과적이다. 

λ를 키울수록 regularization을 강화, 즉 W의 자유도를 더욱 규제하는 방향으로 더 generic boundary를 생성하는 것을 확인할 수 있다.

 

 

 

지금까지 내용을 정리하면,

1) 우리는 score function을 위와 같이 nonlinear하게 정의해 보았다.

2) 이렇게 나온 score 값을 Loss function에 넣어 Loss값을 구할 수 있다. (위에서는 hinge loss를 사용했지만 softmax 등 다양한 loss function 이 있음)

3) 추가적으로 Regularization을 정의해서 data loss와 더하면 최종 loss(Total loss) 값을 구할 수 있다. 

 

최종 수식에서 $\frac{\partial L}{\partial W_1}, \frac{\partial L}{\partial W_2}$ 값을 계산할 수 있으면 W1, W2를 학습할 수 있다.

 

 

그 값은 backpropagation을 통해서 계산할 수 있다. 이 방법은 복잡한 neural network에서도 쉽게 적용될 수 있다는 점에서 매우 유용하다.

 

 

2. Backpropagation

 

간단한 예제를 활용한 backpropagation 문제이다.

$\frac{\partial f}{\partial x}$, $\frac{\partial f}{\partial y}$, $\frac{\partial f}{\partial z}$ 를 각각 computation graph를 통해 구한다.

이때 f와 y, f와 x는 바로 연결되어 있지 않으므로 chain rule을 적용하면 된다.

 

 

이때 backpropagation에서 하나의 노드를 통과할 때 chain rule이 어떻게 계산되는지 살펴보자.

 

  • Local Gradient ($\frac{\partial z}{\partial x}$, $\frac{\partial z}{\partial y}$):
    forward pass(순전파) 때 계산, 입력 변화에 대한 출력 변화율
  • Upstream Gradient ($\frac{\partial L}{\partial z}$) :
    출력값 z가 최종 손실 함수 L에 미친 영향
  • Downstream Gradient ($\frac{\partial L}{\partial x}$, $\frac{\partial L}{\partial y}$) :
    최종 Loss에 대해 입력값 x,y의 영향

 

 

또다른 예제를 보자. 복잡해보이지만 원리는 똑같다.

Computation graph에서 빨간 박스 안을 보자.

마찬가지로 Upstream gradient와 local gradient에 해당하는 값을 곱해주면 된다. 

 

 

Addition의 경우도 각각 살펴보면 upstream gradient 값은 같고, local gradient의 경우 덧셈이므로 미분 결과 1을 곱해주면 된다.

 

 

주어진 수식을 하나하나 분해해서 computational graph를 만들었지만, 실제로 파란 박스에 해당하는 영역은 sigmoid function이다.

이걸 하나로 묶어서 gradient descent 를 계산해도 된다. Computational graph는 유일한 게 아니라 표현하는 방법이 다양하다.

참고적으로 슬라이드 하단에 sigmoid 함수를 미분한 결과이며, 이를 이용해 local gradient를 구할 수 있다.

 

각 연산의 gradient flow

 

지금까지 스칼라 값을 가지고 backpropagation 하는 법을 살펴보았다.

 

그렇다면 vector-valued function에 대해서는 어떻게 계산할 수 있을까?

 

 

그전에 참고적으로 보면 좋을 벡터 미분에 대한 내용이다.

$\frac{\partial y}{\partial x}$에서 x, y가 스칼라라고 하자. 계산 결과 또한 스칼라 형태이며, 의미적으로 보자면 x가 조금씩 변할 때 y값을 얼마나 변하느냐를 보고자 하는 것이다.

이번에는 x는 N의 길이를 가진 벡터, y는 스칼라이다. 미분 결과는 gradient 형태로 나오며, x의 각각의 요소가 변할 때 y 값이 얼마나 변하느냐를 의미한다.

마지막으로 x,y 둘 다 벡터라면 미분 결과는 NxM 행렬, Jacobian 형태로 나오며, x의 각각의 요소가 변할 때 y의 각각의 요소가 얼마나 변하느냐를 의미한다.

 

 

Input이 x,y 벡터이고 Output이 z 벡터일 때 backpropagation 과정을 보자.

이때 Loss 값은 여전히 scalar이다.

우선 Upstream gradient 에 해당하는 $\frac{\partial L}{\partial z}$는 Vector to Scalar에 해당하므로 gradient 결과값으로 나올 것이다.

Local gradient에 해당하는 $\frac{\partial z}{\partial x}$, $\frac{\partial z}{\partial y}$ 둘 다 Vector to Vector 이므로 Jacobian matrices 로 결과가 나오며, 그 크기는 input vector, output vector 사이즈에 따라 달라진다.

마지막으로 Downstream gradient의 경우, $\frac{\partial L}{\partial x}$, $\frac{\partial L}{\partial y}$ 는 둘 다 Vector to Scalar에 해당하므로 gradient 결과값으로 나오며, chain rule 적용이 필요하다.

 

 

위와 같은 예시를 보자. 이 슬라이드는 Forward pass 진행 과정이다.

 

해당 그래프에 대해 backpropagation을 진행하면 아래와 같이 나온다. 

Local gradient를 계산하는 과정을 보면 각 요소가 서로 독립적으로 계산되므로 대각선 요소만 값을 가지는 대각 행렬 형태의 결과가 나온다는 것을 알 수 있다. 

 

 

그러나 만약 입력 벡터의 차원이 4가 아니라 훨씬 큰 숫자였다면 야코비안 행렬의 크기가 매우 커져 메모리 문제가 발생할 것이다.

따라서 어차피 결과가 대각행렬이라는 점을 이용해 위 슬라이드의 수식처럼 입력 벡터 x의 부호에 따른 미분값을 구한 뒤, Upstream gradient와 곱셈만 해주면 똑같은 결과를 얻을 수 있다.

 

 

Input과 Output이 matrices (or tensor)인 경우에 대해서도 똑같이 backprop을 적용할 수 있다.

 

 

이번 시간에는 Regularization and Optimization에 대해 다룬다.

 

우선 지난 시간에 이어서, 이 예시의 classifier는 결과를 보면 좋은 classifier는 아니다. 

 

 

우리는 loss function을 통해 classifier의 성능을 측정할 수 있다.

 

맨 아래 수식을 보면, linear classifier 결과값과 실제 label을 비교하는 loss function을 적용한 뒤 평균을 구하는 방식으로 Loss 값을 구하고 있다.

저번 강의에서 이와 관련하여 가장 많이 사용되는 Softmax loss, Cross Entropy loss에 대해 설명했었다.

 

 

1. Regularization (정규화)

지금까지 설명한 내용이 Data Loss에 해당하는 내용이다.

우리의 모델(Classifier)이 얼마나 학습 데이터를 잘 맞추는지에 관한 값이고, 우리는 이 값이 최대한 작아지길 원하는 것이다.

 

추가적으로 우리는 여기에 Regularization에 해당하는 값을 더할 것이다.

이 값은 모델이 학습 데이터를 너무 잘 맞추게 되는 것을 방지하기 위한 값이다.

(Regularization에 해당하는 내용을 종종 문제집을 풀 때 답지까지 외워버려서 문제집은 잘 푸는데, 막상 시험에서 처음 보는 문제는 못 푸는 상황에 비유하곤 한다.)

 

즉 학습 데이터에 대해서는 성능이 낮아지지만 테스트 데이터에 대해서는 더 잘 작동하도록 해주기 위한 값이다.

 

 

위 이미지가 Regularization을 이해하는 데 직관적으로 와닿는 예시이다.

f1은 학습 데이터에 대해서는 완벽하지만, 위 예시가 아닌 일반적인 다른 데이터에 대해서는 매우 성능이 나쁠 것이다. (Overfitting)

그에 비해 f2는 f1에 비해 현재 학습 데이터 기준 성능은 낮겠지만 훨씬 일반적이고 나은 모델링임을 알 수 있다.

 

 

 

다시 수식으로 돌아와서, 람다(λ)에 해당하는 값은 우리가 설정하는 hyperparameter 중 하나이다.

값을 어떻게 설정하느냐에 따라서 얼마나 Regularization을 하느냐가 정해진다.

 

또한 R(W)에 해당하는 식도 여러 가지 예시가 있다.

L2 Regularization의 경우, 각 W(weight)에 해당하는 값을 제곱하여 다 더해주는 방식이다. 

특징은 W 자체가 매우 작은 값이므로 제곱하면 더 작아진다는 것이다. 따라서 Regularization 값(=Penalty)이 매우 작다.

그에 반해 L1 Regularization은 W의 절댓값을 모두 더해서 Regularization값으로 지정하는 방식이다. 

 

이외에도 Regularization 방법으로 Dropout, Batch normalization 등 많은 방법들이 있다. 

이는 추후에 더 다루게 될 것이다.

 

Regularization에 대해 정리하자면,

  • Weight를 더 분산시킬 수 있으며
  • 모델을 더 simple하게 만들 수 있고
  • 곡률을 더해서 optimization을 개선할 수 있다.(특히 L2 regularization)

 

 

 

이제 예시를 보자.

 

두 개의 weight 예시가 있다. (w1, w2)

L2 Regularization을 한다면 둘 중 무엇을 더 선호할까?

 

답은 w2. 모든 w를 다 제곱해서 더하는 것이므로 w1을 사용하면 R(W) = 1, w2를 사용하면 R(W) = 1/4이다.

R(W)은 최종 Loss에 더해지는 값이고, 우리는 Loss를 최소화하는 게 목적이므로 w2가 더 선호되는 것이다.

이 예시를 통해 L2 Regularization의 경우 weight 값들을 더 퍼뜨리는 것을 선호함을 확인할 수 있다.

 

 

그렇다면 L1 Regularization의 경우는 어떨까?

이 경우에는 w 절댓값의 합이므로 w1, w2 둘 다 R(W)의 관점에서는 1로 값이 같다.

 

 

 

 

 

지금까지 한 내용을 정리해보자.

 

1. 우리는 학습 데이터셋 (x,y)를 가지고 있다. 

2. 그리고 score function을 이용해 각 x 데이터에 대해 score 값을 얻을 수 있다. 이때 score function으로 Linear function을 사용하고 있다: f(s,W) = Wx

3. 이렇게 각 데이터에 대해 얻은 score 값을 Loss function의 입력으로 넣어서 각 데이터에 해당하는 loss 값을 구할 수 있다. 이때 loss function으론 주로 softmax를사용한다.

4. 최종적으로 이렇게 얻은 Loss 값의 평균과 Regularization 값을 더해서 Final loss(Full loss)를 얻을 수 있다.

 

 

이제 다음 의문점은, 어떻게 하면 좋은 Weights 값을 설정할 수 있느냐이다.

 

이는 우리가 다음으로 공부할 Optimization을 통해 해결할 수 있다.

 

2. Optimization (최적화)

 

Optimization은 주로 위와 같은 예시로 설명된다.

한 사람이 산에 올랐는데, 그곳에서 가장 낮은, 즉 깊은 골짜기를 찾으려고 한다. 

사람이라면 육안으로 바로 관찰할 수 있겠지만, 지금 우리는 사람이 아닌 컴퓨터가 하는 작업을 말하고 있으므로

눈을 가린 사람이 기울기를 통해 골짜기를 찾아 가는 과정이라고 생각하면 된다.

 

그렇다면 이제 어떻게 찾으면 될지 방법을 알아보자.

 

 

그냥 무작정 해보는 방법이다. 랜덤한 Weight matrix 1000개를 해보고 가장 좋은 값을 찾는 방법으로 당연히 좋은 방법은 아니다.

 

 

두번째 방법은 기울기를 구하는 것이다.

낮은 골짜기를 찾기 위해 현재 위치에서 낮은 쪽으로 향하는 기울기 방향으로 나아가는 방법이다.

 

2-1. Gradient Descent

 

 

각 지점에서 기울기를 계산하여, 감소하는 방향으로 나아가는 방법이다.

 

 

빨간색 영역이 고도가 낮은 영역이라고 했을 때, 현재 W의 위치(흰색 동그라미)에서 기울기가 향하는 방향으로 나아간다. 

이때 화살표의 크기를 step size라고 생각하면 된다. 점점 진행할수록 step size는 작아지는 게 일반적이다.

 

2-2. Stochastic Gradient Descent (SGD)

 

가장 많이 사용되는 Stochastic Gradient Descent 는 전체 데이터를 보는 게 아니라 데이터를 나눠서 계산하는 방법이다.

즉 위의 코드처럼 전체 데이터 중 256개의 데이터 사이즈를 정해놓고 그 단위를 batch라 부른다.

각 batch 마다 Loss를 계산해서 gradient를 평가하고 이를 반복한다.

이때 모든 데이터셋에 대한 batch 작업이 끝나면 이를 1 epoch라고 한다.

 

이 방법의 문제점 중 하나는 step size가 만약 너무 크다면, top-down을 향해 가는 과정에서 발산이 일어날 수 있다는 점이다.

또는 진행 과정이 너무 느리다면, oscillation이 일어날 수 있다.

 

 

또다른 문제점은 loss function의 그래프가 슬라이드처럼 local minima를 가지고 있거나, saddle point를 가지고 있을 때 문제가 발생할 수 있다는 점이다. 

참고로 saddle point의 경우 weight matrix의 차원이 높아질수록 더 흔하다.

 

 

SGD의 또다른 문제점은 우리는 앞서 말했듯 모든 데이터를 보고 업데이트를 하는 게 아니라 배치 단위로 전체 데이터를 나누어서 업데이트를 진행한다. 그렇게 되면, 최종적으로 가장 낮은 곳을 향해 나아가기는 하지만 전체 데이터를 보는 게 아니기 때문에 중간중간 noisy한 업데이트가 발생할 수 있다.

 

2-3. SGD + Momentum

 

이러한 세가지 문제점을 해결하기 위해 Momentum 을 적용할 수 있다.

왼쪽은 지금까지 배운 SGD이고, 오른쪽은 SGD에 Momentum을 결합한 것이다.

 

Momentum을 결합한 식을 살펴보면, velocity라는 새로운 개념을 추가하고 있다. 

이전 velocity값과 현재 gradient값을 더해서 v_t+1이라는 값을 업데이트한다.

ρ가 momentum에 해당하는 값으로, 그 값이 커질수록 현재 velocity가 이전 시점의 velocity에 영향을 많이 받게 된다.

 

2-4. RMSProp

 

또다른 Optimizer로는 RMSProp이 있다.

수도 코드를 보면, grad_squared라는 term이 추가된 걸 볼 수 있는데 들여다보면 dx를 제곱해주고 있는 게 보인다.

즉 gradient가 큰 값은 더 커지고, 작은 값은 더욱 작아진다.

그리고 최종적으로 x를 업데이트하는 과정에서 이 값을 루트를 취해 나눠주고 있다.

 

이를 이론적으로 이해해보자면 변화량이 커서 gradient가 커진다면,

분모의 값이 커질테고 따라서 업데이트 시 해당 방향으로 진행하는 step size가 작아진다.

 

쉽게 말하자면 한 번 업데이트할 때 gradient가 크게 나오면, 즉 변화하는 방향이 크게 변하면 그 step size를 작게 해서 위험을 방지한다고 볼 수 있다.

 

 

 

 

2-5. Adam

 

다음 Optimization 기법으로 현재 가장 많이 쓰이는 Adam 알고리즘이 있다.

앞서 배운 Momentum과 RMSProp의 장점을 합친 방법이다.

 

그러나 first timestep을 생각해보면, first_moment와 second_moment = 0 으로 설정되고, beta1, beta2 값도 1에 매우 가까운 값(ex.0.99)에 가깝게 설정된다. dx에 해당하는 값이 매우 작더라도 최종적으로 x를 업데이트하는 식에서 분모의 값이 매우 작아지므로 업데이트되는 값은 매우 커지게 된다.

 

이를 방지하기 위해 bias term을 추가한다. 

 

 

그렇다면 우리가 앞서 매운 Regularization은 Optimizer과 어떻게 상호작용할까?

 

 

우리가 배운 기존 Adam 방식은 dx = compute_gradient(x) 단계에서 L2 정규화 항을 계산한다.

그러나 AdamW (Weight Decay 적용)는 최종 가중치(파라미터) 업데이트 단계인 최하단의 x -= learning_rate * ... 코드 위치에 가중치 감쇠 항을 직접 더해준다.

 

 

 

2-6. Learning Rate

다음으로 Learning rate에 대해 알아보자.

 

 

 

노란색 그래프의 경우 learning rate가 매우 빠르게 증가한다. 이 경우 앞서 보았던 oscillation case에 해당한다.

파란색 그래프처럼 Learning rate가 느리게 증가하는 경우, 매우 느리게 수렴하는 경우이다.

초록색 그래프처럼 learning rate가 높은 경우, 수렴은 했지만 loss가 큰 값에 수렴하므로 Local minimum하는 케이스이다.

 

이제 learning rate를 조절하는 방법(scheduler)에 대해 알아보자. 

 

Scheduler

 

 

(1) Step Decay

하나의 좋은 방법은 특정 iteration을 기준으로 learning rate의 1/10 비율로 감소시키며 학습을 반복하는 방식이다. 

학습률이 감소할 때마다 loss가 계단형태로 감소하며, Resnet을 학습시킬 때 많이 사용하는 방법이다.

 

 

(2) Cosine Decay

cosine 함수를 이용하는 방법으로 learning rate를 부드럽게 감소시키는 방식이다. 

 

 

 

(3) Linear learning rate decay

learning rate를 직선 모양으로 일정하게 줄여나가는 방식이다.

 

 

(4) Linear Warmup

실제로 매우 많이 활용되는 linear warmup 방식은 학습 초반 특정구간 동안 목표 초기 learning rate까지 선형적으로 증가시킨 후 이후 감수 스케줄러를 적용하는 기법이다.

Empirical rule로는 만약 데이터 배치 사이즈를 N배로 키운다면, initial learning rate도 똑같이 N배로 키워주는 게 잘 작동한다.

 

Image Classification

 Computer vision이란 분야에서 Image Classification(이미지 분류)은 가장 핵심적인 작업이다.

 

그렇다면 Image Classification이란 무엇인가?

입력된 이미지에 대해 하나의 라벨을 할당하는 작업으로 생각하면 된다. 

 예를 들어 사람의 눈으로 볼 땐 위 이미지가 바로 고양이임을 알 수 있지만, 컴퓨터 입장에서 이 이미지는 0부터 255 사이의 픽셀로 이루어진 행렬일 뿐이다. 

컴퓨터가 이 이미지를 보고 고양이라고 제대로 라벨링할 수 있도록 하는 작업이 Image Classification이라고 생각하면 된다.

 

 

Challenges

Image classification이 겪고 있는 문제점들은 다음과 같은 것들이 있다.

같은 대상에 대해 view point가 바뀔 때마다 이미지를 이루는 픽셀들이 바뀌기 때문에 발생하는 문제

 

 

똑같은 고양이더라도 그림자, 조명 등에 의해 기계가 인지하기 힘들어 발생하는 문제

 

 

배경으로 인한 문제

 

 

일부가 가려져 발생하는 문제

 

기존 이미지와의 변형으로 발생하는 문제

 

색, 무늬 등 다양성으로 인해 발생하는 문제

 

 

그렇지만 현대의 컴퓨터 비전 알고리즘은 큰 이미지 데이터셋과 큰 규모의 모델로 학습하고 있기 때문에 이미지 분류에서 좋은 성능을 보이고 있다. 

그렇다면 이러한 이미지들을 어떻게 분류할 수 있을까?

 

Image Classifier

 

초반 연구는 edge detector를 이용한 알고리즘을 시도했다.

edge를 추출하고, 해당 이미지에서 중요한 패턴(ex.corner)을 추출한 뒤 패턴을 이용해 라벨을 찾는 방법을 시도했지만

알고리즘에 해당하는 조건을 하나하나 설정해야 하며, 결론적으론 성공적이지 못했다.

 

따라서 아래와 같은 방법으로 이미지 분류를 연구하기 시작했다.

간단히 말해서 images랑 그에 해당하는 labels 데이터셋을 모으고 이를 이용해 ML 알고리즘을 학습하는 방법이다.

이 작업은 데이터 기반 방법론(Data-driven approach)으로 아래와 같은 세부 방법으로 이루어진다. 

  1. image와 label 데이터쌍 수집
  2. ML 알고리즘을 이용해 classifier를 데이터쌍을 가지고 훈련
  3. test 이미지에 classfier를 적용해보고 평가

 

지금부터 2개의 가장 유명한 Image Classifier에 대해 알아보자.

 

 

1. Nearest Neighbor Classifier

아래와 같이 왼쪽 5개의 training data가 있다고 하자. (이미지와 라벨 쌍)

Query data(왼쪽 이미지)가 training data 5개 중 어떤 것과 가장 비슷한지 측정하는 게 우리의 목표이다.

이때 query image와 training image 간의 distance를 활용해 얼마나 가까운지 측정하여 label을 예측하는 게 이 방법론이다.

그렇게 하려면 두 이미지를 비교하여 거리를 측정하기 위한 distance metric가 필요하다.

 

 

이러한 distance metric에는 여러 가지가 있는데 그중 아래 예시는 L1 distance(pixel 간 절댓값 차이를 구한 뒤 합)를 이용한 방법이다.

 

파이썬으로 구현한 Nearest Neighbor Classifier

이 방법론은 구현 시 학습시간은 짧은데, 모든 데이터와 비교해야 하니 prediction 시간이 오래 걸린다는 단점이 있다. 

이게 치명적인 단점이 되는 이유는 실제 서비스에서는 training 시간은 중요하지 않고, prediction이 짧은 게 중요하기 때문이다.

 

k-nearest neighbor (one of ML model)

 단순히 가장 가까운 nearest neighbor의 label을 가져오는 게 아니라 k 개의 closet point들을 보고 다수에 해당하는 label을 가져오는 방법이다.

단점은 k개로 늘리면 이미지에서 흰색에 해당하는 부분, 즉 unclear space가 생기고 이 영역은 어떤 라벨인지 결정을 내릴 수가 없어진다. 또한 k를 몇개로 할 것인지 적절히 선ㅌ낵하는 것도 중요하다.

 

또다른 선택 요소로는 아까 언급했던 distance metric를 무엇으로 할 것인지이다.

distance metric에 가장 기본적으로 사용되는 2가지: L1 distance, L2 distance

 

두 방법론의 가장 큰 차이점은 그래프를 통해 확인할 수 있다.

위 그림에서 x,y 축은 feature라고 보면 되는데 지금은 2차원이므로 2가지의 feature를 사용했다는 뜻이 된다.

만약 feature를 바꾸게 된다면(즉 회전이 일어남) L1 distance에서는 값에 차이가 생기겠지만, L2 distance는 그대로일 것이다.

이 점을 활용하여 적절하게 사용해야 하는데, L1 distance를 사용하면 feature를 뭘 사용하느냐에 따라 그 값이 달라진다는 점을 활용할 수 있지만, 반대로 사용하려는 feature가 모호하다면 L2 distance를 사용하는 게 낫다.

 

 

아까 봤던 예시에 L1 distance, L2 distance를 적용한 예시이다.

눈여겨 볼 점은 L1 distance를 사용한 경우 경계선이 축와 평행하게 형성된 경향이 강한 반면

 L2 distance를 적용한 경우 경계선이 전반적으로 부드럽게 형성되어 있다.

 

=> 지금까지 Nearest Neighbor 알고리즘 정리

  • easy algorithm
  • hyperparameter를 어떻게 설정하느냐 매우 중요하다.
    hyperparameter란 알고리즘을 설계하는데 설계자가 정해야 하는 변수라고 생각하면 된다.
    이 알고리즘에선 두 개의 hyperparameter가 있다.
    • k
    • distance metric

 

hyperparameter를 설정하는 방법

: 사용하는 데이터셋과 어떤 문제이냐에 따라 결정되며, 설계자가 hyperparameter를 조정하는 것을 hyperparameter tuning이라고 한다. 

그렇다면 어떤 방법으로 hyperparameter를 setting할 수 있을까?

 

방법 1) 학습 데이터셋에 대해 가장 좋은 결과를 보이는 하이퍼파라미터 선정

=> 좋지 않다. 학습 데이터셋에 대해서는 모든 결과를 알고 있으니 k=1일 때 언제나 최고의 결과를 보일 것이다.

 

방법 2) 테스트 데이터셋에 대해 가장 좋은 결과를 보이는 하이퍼파라미터 선정

=> 이것도 좋지 않다. 왜냐하면 이 테스트 데이터말고 새로운 데이터에 대해서 어떻게 알고리즘이 동작할지 모르기 때문이다.

 

방법 3) 데이터를 train / validation / test 로 나눈 뒤 train data로 학습, validation data로 hyperparameter tuning, test data로 결과 측정

=> 위 3개 중 가장 나은 방법, 그러나 validation data 양이 적으므로 좋은 표본이 아닐 수도 있다는 단점

 

방법 4) Cross validation

데이터를 여러 폴드로 나눈다. 위 예시에선 5개의 폴드로 나누었을 때, 각 폴드가 validation set이 되도록 5번 모델을 돌려보고 정확도를 평균 내어 측정한다. 

그러나 학습할 데이터가 많은 케이스에 대해서는 여러번 폴드를 나눠서 여러번 학습 시켜봐야 되므로 잘 사용하지 않는다.

 

CIFAR-10 데이터셋을 가지고 5-cross validation을 k에 따라 나타낸 결과이다.

k=7 정도일 때 정확도가 그나마 높은 편 약 0.31 정도로 보인다.

Random guess보단 낫지만 많이 부족한 편이다.

 

성능이 이렇게 낮은 이유는 무엇일까?

 

k nearest neighbor 알고리즘 자체가 픽셀 기준으로 실행되는 알고리즘이다.

실제로 픽셀 간 거리를 측정하는 알고리즘은 실무에서 사용되지 않으며, 더 좋은 알고리즘을 앞으로 배울 것이다.

위 슬라이드는 같은 이미지를 픽셀 단위로 조금만 수정한 것으로, 사람 눈으로 보면 매우 간단하게 파악이 되지만

이걸 픽셀 간 거리로 계산하게 되면 그 차이에 해당하는 값이 매우 클 것이라는 점을 말하고 있다.

 

k Nearest Neighbor Algorithm 정리

 

 

2. Linear Classifier

앞으로 배울 딥러닝을 설계하는데 매우 중요한 요소이다.

 

nearest neighbor과는 뭐가 다를까?

 

위 슬라이드에서 f(x,W) = Wx + b 에 해당하는 식이 우리가 설계할 Linear Classifier이다.

이 수식을 이해해보자.

 

  • 우선 x는 입력값으로, 우리는 왼쪽에 해당하는 32x32x3 크기의 이미지를 입력으로 넣을 것이다.
    32x32x3 = 3072이므로 3072x1의 벡터(=x)가 입력이 된다. 
  • 우리는 10개의 output class를 설정할 것이므로 10개의 score이 필요하다.
  • 따라서 f(x,W)의 결과는 10x1의 벡터여야 한다. 따라서 W의 크기는 10x3072이 되어야 한다.
  • 그리고 bias에 해당하는 값을 더해준다. (크기는 10x1로 맞춰줌)

 

이런 linear classifier를 여러개 쌓아서 neural network를 만드는 것이다.

 

 

이제 CIFAR-10 example 이용해 여러 관점에서 linear classifer를 해석해보자.

input image가 vector로 변환되어 linear classifier에 입력으로 들어가 값이 출력됨

 

설계된 linear classifier를 geometric viewpoint에서 나타낸 것

 

 

그러나 linear classifier에도 단점이 있다.

위 3개의 case와 같은 경우, linear classifier로 분류할 수 있는 방법이 없다는 단점이 있다.

 

 

다시 linear classifier로 돌아와서

linear classifier를 설계할 때, W는 어떻게 결정할 것인가?

W를 설계하는 방법은 아래와 같다.

  • loss function(손실 함수)을 설계한다.
  • loss function의 결과값을 최소화한다.(이 과정을 optimization이라고 한다)

예시를 보자.

 

위 슬라이드와 같이 3개의 training images가 있고, 3개의 클래스가 있다고 하자. 

이때 데이터셋(training images)을 (xi, yi)로 나타낸다.

각 데이터에 대해 f(x,W)를 계산하고, 그 결과값을 이용해 다시 Loss 값을 계산할 수 있다. 

 

위 과정을 설계하기 위해선 Li에 해당하는 Loss function을 잘 설계하는 것이 중요하다.

그 방법으로 softmax classifier에 대해 알아보자.

 

Softmax Classifier

파란색 박스에 해당하는 값은 각 클래스에 해당하는 score(s)값이다.

즉 우리가 설계한 linear classifier(=f)의 각 클래스에 해당하는 결과값이다.

이렇게 나온 값을 정규화하여 확률로 바꾸는 작업을 거칠 것이다.

 

그러기 위해 각 score에 exp를 적용하고, 그 값이 빨간색 박스에 해당한다. (exp를 적용하면 언제나 0 이상이 된다.)

 

그리고 softmax function을 활용해 정규화하면 초록색 박스에 해당하는 확률 값으로 변환된다. (합이 언제나 1)

 

 

 

다시 돌아와서, 우리의 목적인 Loss function을 어떻게 설계할 수 있을까?

우리의 목적은 정답 클래스에 해당하는 값, 즉 위 예시에선 cat에 해당하는 0.13 값이 최대가 되는 것이다.

해석하면 maximization problem이라는 건데, 이걸 Minimization problem으로 바꿔서 풀자.

즉 정답 클래스의 확률값에 -log를 취하는 것을 loss function으로 설정하는 것이다.

이 값을 이용해 손실 점수를 계산한다. 

(다루기 쉽게 하기 위해서)

 

더 나아가 이 loss function의 의미를 알아보자.

우리는 예측에 해당하는 확률값(초록색 박스)을 알고 있고, 우리가 원하는 정답은 보라색 박스이다.

이때 우리는 KL divergence를 최소화하는 방법으로 Loss function을 설정하려고 하는 것이다. 

KL divergence란 쉽게 생각하면 두 확률 분포 사이의 거리를 측정하는 도구라고 생각하면 된다. 

참고로 지금 이 방법은 Cross Entropy라고도 할 수 있다.

Cross Entropy는 위 슬라이드의 식으로 나타낼 수 있는데, 이때 P는 정답이고, Q는 예측에 해당한다.

H(p)는 Entropy(P)로, 이 상황에선 정답이 정해져 있으므로 H(p)=0이다.

즉, H(P,Q) = D_KL(P||Q)라고 할 수 있다.

위 내용을 정리해보자면,

Loss function(Li)는 -logP(Y|X)로 정의할 수 있고(왼쪽 식),

여기서 P에 해당하는 확률의 경우, score 값을 이용해 softmax 식으로 구할 수 있는 것이다.(오른쪽 식)

 

 

이 강의는 2025년 봄학기에 스탠포드에서 진행된 강의로,

 AI라는 넓은 분야 중 computer vision과 deep learning의 교집합에 해당되는 내용을 설명한 강의다. 

 

 

 

이 강의는 딥러닝과 컴퓨터 비전 분야에서 기본 개념을 잘 설명한 강의로 매우 유명하며,

앞으로 전반적인 강의 중 주요한 내용만을 요약 및 정리하려 한다.

 


 

history of computer vision

 


 

1. Deep Learning Basics

 

- 이 섹션에선 Deep Learning 의 아주 기초적인 구조를 배운다. 

 

우선 Computer vision이란, 컴퓨터가 이미지를 보고 이해할 수 있게 하는 것이다.

가장 근본적인 작업으로는 Image Classification(이미지 분류)가 있다.

이미지를 입력으로 받고 그에 해당하는 라벨을 출력으로 내보내는 것이다.

 

그렇다면 어떤 원리로 컴퓨터가 이 작업을 하도록 할 수 있을까?

가장 간단한 방법은 Linear Classification(선형 분류)를 이용하는 것이다.

 

 

가장 간단한 예시로 위 우측 그래프에서 이미지 하나가 2차원의 점이라고 생각해보자.

그리고 이미지가 가진 feature을 이용해 점 하나하나를 2차원에 위치시킨 것이다. 

이 점들을 고양이 / 강아지로 분류하는 선 하나를 찾는 것을 선형 분류라고 한다. 

 

그러나 실제론 데이터가 선 하나로 완벽히 분류되기 쉽지 않다.

즉 더 복잡한 모델이 필요하다.

 

 

더 복잡한 모델을 도입하다 보면 여러 문제를 직면하게 되는데 ex.overfitting, underfitting)

모델 복잡도를 다루기 위해 Regularization, Optimization 과 같은 방법들을 모델에 도입하게 될 것이다.

이런 방법들을 활용하면 단순히 입력 데이터 뿐만이 아니라, 모델이 보지 못한 새로운 데이터에 대해서도

잘 작동할 수 있게 모델을 발전시킬 수 있다.

 

 

위에서 설명한 선형 모델과 달리 Neural Networks는 여러 개의 레이어를 쌓은 형태이다.

Neural Networks는 선형 모델과 비선형 함수를 도입하였기 때문에 더 복잡한 문제를 풀 수 있다는 장점이 있다.

우리가 사용하는 대부분의 모델은 이런 Neural Networks 구조이다.

 

 

2. Perceiving and Understanding the Visual World

- 이 섹션에서는 computer vision 분야에서 AI가 적용되는 다양한 tasks, models에 대해 다룬다.

 

Computer vision을 이용한 task에는 위에서 얘기한 image classification 외에도 object detection, scene understanding, motion detection 등이 있다.

이러한 task를 수행하기 위해 우리는 다양한 모델들(MLP, CNNs, RNNs, transformers) 을 사용할 것이며 이에 대해 배울 것이다.  

 

이번 학기에 새롭게 도입된 강의 주제로, Large Scale Distributed Training 에 대해서도 배울 것이다. 

최근 Large Language Models, Large Vision Models라는 말을 많이 들어보았을 것이다.

이는 모델이 점점 커지는 경향성 때문이다. 

 

이러한 모델들을 실제로 어떻게 학습하는지,

어떤 방법론(data parallelization, model parallelization)을 사용하는지, 

어떤 문제들(synchronization)이 있는지에 대해 배울 것이다.

 

 

3. Generative and Interactive Visual Intelligence

 

1) Self-supervised learning

Large scale model 학습에 큰 도움을 준 학습 방법으로,

다량의 학습 데이터가 필요할 때, 정답 라벨 없이 학습 가능한 방법이다.

 

 

2) Generative Modeling

단순히 Recognization을 넘어서서 Generation까지 진행하는 방법이다.

심지어 텍스트가 주어졌을 때 이에 해당하는 이미지를 생성하는 모델링도 가능하다.

(Dall-E)

 

이 분야에서 대표적인 모델로 노이즈에서 이미지를 생성하는 방법을 학습하는 Diffusion 모델이 있다. 

 

 

3) Vision Language Models

이 모델은 텍스트와 이미지를 shared representation space에서 연결하며,

캡션이나 이미지가 모델에 주어지면 해당하는 텍스트와 이미지 페어를 출력한다.

 

 

4) 3D Vision

2차원을 넘어서 3차원에서도 모델은 다양한 테스크를 수행할 수 있으며

이는 로보틱스나 AI VR에서 매우 중요하게 다뤄지고 있다.

 

 

5) Embodied Intelligence

실제 물리적인 세계에서 적용에 대해 다룬다.

 

 

4. Human-Centered Application and Implications

이렇게 AI와 컴퓨터 비전이 다양한 분야에서 발전해오고 있으며 영향력을 끼치고 있다.

이를 human-centered 관점에서 해석하고 적용하는 것 또한 매우 중요하게 여겨지며 현재 활발히 연구되고 있다.

 

 

 

 

+ Recent posts