[CS231n]Lecture07-Training Neural Networks2

지난 6강에서는 activation function을 중점적으로 다루어 보았는데, 10년전 까지만 해도 sigmoid가 아주 유명했다. 허나, Vanishing gradient가 생기는 문제로 인해 최근에는 Sigmoid와 tanh 보다는 ReLU를 쓴다라고 했다.

  • 대부분의 경우 normalize나 zero-centered로 데이터를 처리해 주지 않으면, Loss가 파라미터에 너무 민감하기 때문에 학습시키기에 어렵다.

  • 하이퍼파라미터를 몇 개씩 선택하는지에 따른 고민은 보통 모델에 따라 다르며, 하이퍼파라미터의 수가 많을 수록 기하급수적으로 경우의 수가 늘어난다. 많은 하이퍼 파라미터 중 learning rate가 가장 중요할 것이라고 본다. regularization, learning rate decay, model size 같은 것들은 Learning rate보단 덜 중요하다. 그렇기에 Block Coordinate Descent(BCD) 같은 방법을 쓸 수도 있다. 우선 learning rate를 정해놓은 다음에 다양한 모델 사이즈를 시도해 보는 것이다. 이 방법을 사용하면 기하급수적으로 늘어나는 Search space를 조금은 줄일 수 있다. 하지만 정확히 어떤 순서로 어떻게 찾아야 할지 정해야 하는 것이 가장 큰 문제이다.

  • 우리가 어떤 하이퍼파라미터 값을 변경할 시에 다른 하이퍼파라미터의 최적 값이 변해버리는 경우는 가끔 발생한다. 이런 경우 더 좋은 최적화 방법을 사용하면 모델잉 learning rate에 덜 민감하도록 할 수 있다.

Fancier Optimization

SGD(Stochastic Gradient Descent)의 문제점
  • 1)가중치가 움직일수 있는 방향 중 불균형한 방향이 존재한다면 SGD는 잘 동작하지 않을 것이다.

    • 아래의 그림을 보고 수평축과 수직축 이 두가지에 대해 가중치의 변화에 따른 손실함수의 변화량이라고 생각해 보자.(우리가 쉽게 어릴적 보았던 지도에서 등고선을 떠올린다면 더 쉽게 이해할 수 있을 것이다.) 그렇다면, 수평축의 가중치 보다 수직축의 가중치가 훨씬 더 손실함수의 변화하는 속도가 빠를 것이다.(왜? 기울기가 더 가파르니까!!!) 즉, Loss는 수직 방향의 가중치 변화에 훨씬 더 민감하게 반응한다. 아래의 그림에서 red point가 현재 Loss라고 가정했을때, 현재 지점의 Hessian matrix의 최대/최소 singular values값의 비율이 매우 안좋다는 뜻이므로 Loss는 bad condition number를 지니고 있다고 말할 수 있을 것이다.[그림0] 아래와 같은 손실함수에서 SGD를 시행한다면, gradient의 방향이 고르지 못하기 때문에 지그재그 모양으로 gradient의 방향이 그려지게 된다. Loss에 영향을 덜 주는 수평방향 차원의 가중치는 업데이트가 아주 느리게 진행된다. 즉, 이렇게 가중치가 움직일수 있는 방향 중 불균형한 방향이 존재한다면 SGD는 잘 동작하지 않을 것이다. [그림1]
  • 2)local minima와 saddle points

    • X축은 어떤 하나의 가중치를 나타내고, Y축은 Loss를 나타내고 있다. 위의 그림은 local minima에 관한 그림이고, 아래의 그림은 saddle point와 관련된 그림이다. saddle point가 의미하는 것은 어떤 방향은 Loss가 증가하고 몇몇 방향은 Loss가 감소하고 있는 곳을 생각해 볼 수 있다. 그에 반해 local minima는 한 방향으로 Loss가 상승하는 방향이다. 이런 saddle point 문제는 고차원 공간에서는 더욱 더 빈번하게 발생하며, 지난 몇 년간 알려진 사실은 very large neural network가 local minima 보다는 saddle point에 취약하다는 것이다. saddle point 뿐만 아니라 saddle point 근처에서도 문제가 발생하는데 근처에서 gradient가 0은 아니지만 기울기가 아주 작은 곳들이 보일 것이다. 그것이 의미하는 바는 gradient를 계산해서 업데이트를 해도 기울기가 아주 작기 때문에 현재 가중치의 위치가 saddle point 근처라면 업데이트는 아주 느리게 진행된다는 점 또한 문제점이다.
  • 3) mini-batch로 인한 가중치 업데이트는 추정값이다.

    • 손실함수를 계산할 때는 엄청 많은 Training Set 각각의 loss를 전부 계산해야 한다. 매번 이렇게 전부를 계산하는 것은 어렵기 때문에 실제로는 mini-batch의 데이터들만 가지고 실제 Loss를 추정하기만 한다. 이는 gradient의 부정확한 추정값만을 구할 뿐이라는 것이다.

위에서 말한 위험요소들을 다루기 위해서 더 좋은 최적화 알고리즘이 필요하다.

  • 아래에서 소개하는 최적화 알고리즘들의 velocity은 하이퍼 파라미터가 아니며 초기값을 항상 0으로 둔다!
    1) SGD + momentum
  • 아이디어는 gradient의 방향으로만 움직이는 SGD에 velocity를 유지하는 것이다. 즉, gradient를 계산할 때 velocity를 이용한다. 현재 mini-batch의 gradient 방향만 고려하는 것이 아니라 velocity를 같이 고려하는 것이다.아래의 수식을 보면 velocity의 영향력을 rho의 비율로 맞춰주는데 보통 0.9 또는 0.99 같은 높은 값으로 맞춰준다. gradient vector 그대로의 방향이 아닌 velocity vector의 방향으로 나아가게 된다. [그림2]local minima와 saddle points 문제는 local minima에 도달해도 여전히 velocity를 가지고 있기 때문에 gradient가 0이라도 움직일 수 있으며 계속해서 내려갈 수 있다. saddle point 주변의 gradient가 작더라도, 굴러내려오는 속도가 있기 때문에 velocity를 가지게 되어 이 또한 잘 극복해 내고 계속 밑으로 내려올 수 있는 것이다. 기존의 SGD만을 사용했을 경우처럼 지그재그로 움직이는 상황을 momentum으로 인해 그러한 변동을 서로 상쇄시켜 버린다. noise가 평균화 되버리는 의미를 갖는다. 이를 통해서 Loss에 민감한 수직 방향의 변동은 줄여주고 수평방향의 움직임은 점차 가속화 될 것이다. momentum을 추가하게 되면 high condition number problem을 해결하는데 도움이 되는 것이다! 직관적으로 보면 velovity는 이전 gradients의 weighted sum이다. 더 최근의 gradients에 가중치가 더 크게 부여되고 계산되는 과정이 일좀의 smooth moving average라고 볼 수 있다. 시간이 지날수록 이전의 gradient들은 exponentially하게 감소한다.
    [그림3]
2) Nesterov momentum

SGD momentum은 현재지점에서의 gradient를 계산한 뒤에 velocity와 곱해주었지만 Nesterov momentum은 계산 순서만 변형을 시켜 주었다고 보면 된다. 아래의 왼쪽 그림을 보면, 빨간 점에서 시작해서 우선은 Velocity 방향으로 움직인다. 그리고 그 지점에서의 gradient를 계산한 후 다시 원점으로 돌아가서 이 둘을 합치는 것이다. velocity의 방향이 잘못되었을 경우에 현재 gradient의 방햐을 좀 더 활용할 수 있도록 해준다. Nesterov는 Convex Optimization 문제에서는 뛰어난 성능을 보이지만 하지만 Neural network와 같은 Non-convex problem에서는 성능이 보장되는 않는다.
[그림4]
Nesterov의 첫번째 수식은 기존의 momentum과 동일하다. 아래 그림에서 재배열한 수식을 보면 기존과 동일하게 velocity와 계산한 gradient를 일정 비율로 섞어주는 역할을 한다. 그리고 두 번째 수식에서 마지막 부분을 보면 현재 점과 velocity를 더해주며, 현재 velocity - 이전 velocity를 계산해서 일정 비율(rho)을 곱하고 더해줍니다. 현재/이전의 velocity간의 에러 보정(error-correcting term)이 추가되었다.
[그림5]
이전의 velocity의 영향을 받기 때문에 momentum 방법들은 minima를 그냥 지나쳐 버리는 경향이 있다. 하지만 스스로 경로를 수정하고는 결국 minima에 수렴한다.

3) AdaGrad
  • 학습 도중에 계산되는 gradient에 제곱을 해서 계속 더해준다. 가중치를 업데이트 할때 gradient로 나눠주는 작업을 수행한다. 한 차원은 항상 gradient가 높은 차원이고 다른 하나는 항상 작은 gradient를 가지는 2차원 좌표가 있다고 가정하자. small dimension에서는 gradient의 제곱 값 합이 작은데 이 작은 값으로 나워지므로 가속도가 붙게된다. Large dimension에서는 gradient가 큰 값 이므로 큰 값이 나워지게 되어 속도가 점점 줄어든다. 하지만 학습이 계속 진행될수록 학습 횟수가 늘어난다는 문제가 있다. 학습 횟수가 많아질수록 AdaGrad의 값은 점점 작아진다. 이러한 점은 Convex한 Loss인 경우에 좋은 특징이 될 수 있다. minimum에 근접하면 서서히 속도를 줄여서 수렴할 수 있게 해 줄 수 있기 때문이다. 하지만 saddle point problem과 같은 non-convex 문제에서는 AdaGrad가 멈춰 버리는 상황이 발생할 수 도 있어 문제가 있다. 일반적으로 NN을 학습시킬 때는 잘 사용하지 않는다.[그림6]
4) RMSProp
  • 위와 같은 문제를 보완하기 위한 알고리즘이다. AdaGrad의 gradient 제곱 항을 그대로 사용한다. 점점 속도가 줄어드는 문제를 제곱항을 그저 누적시키는 것이 아니라 기존의 누적 값에 decay_rate를 곱해주는 방식을 통해 해결하였다. decay_rate는 보통 0.9 또는 0.99를 자주 사용한다. gradient 제곱을 계속 나눠준다는 점은 AdaGrad와 유사하다. 이를 통해 step의 속도를 가속/감속 시킬 수 있다. [그림7]
5) Adam
  • momentum + RMSProp 으로 위에서 종합한 momentum계열의 알고리즘과 Ada계열의 알고리즘의 특징을 합한 것이다. 빨간색 부분은 gradient의 가중합이다. 파란색 부분은 AdaGrad나 RMSProp처럼 gradients의 제곱을 이용하는 방법이다. 초기 Step이 엄청 커져 버릴 수 있고 이로 인해 잘못될 수도 있다. 이런 문제를 해결하기 위해 보정하는 항을 추가한다.(bias correction term) Adam은 다양한 문제에도 정말 잘 동작한다. 하지만 예를들어 손실함수가 타원형이고 축 방향으로 정렬되어 있지 않고 기울어져 있다고 생각해 보자. 회전된 타원(poor conditioning) 문제는 Adam을 비롯한 다른 여러 알고리즘들도 다를 수 없는 문제이다.[그림8]

learning rates decay 전략

  • 처음에는 learning rate를 높게 설정한 다음에 학습이 진행될수록 learning rates를 점점 낮추는 것이다. 예를 들면, 100,000 iter에서 learning rates를 낮추고 학습시키는 것이다.(step decay) 또는 exponential decay 처럼 학습과정 동안에 꾸준히 learning rate를 낮출 수도 있다. learning rate가 너무 높아서 더 깊게 들어가지 못하는 상황에 learning rate를 낮추게 되면 속도가 줄어들며 지속해서 Loss를 내려갈 수 있을 것이다. learning rate decay는 부차적으로 생각해보는 것이지 학습 초기부터 고려하지는 않는다. 또한 Adam 보다는 SGD Momentum을 사용할 때 자주 사용한다.[그림9]

위에서 언급한 알고리즘들은 1차 미분값을 사용하여 1차 근사함수를 실제 손실함수라고 가정하고 가중치의 업데이트를 진행하였다. 이런 방식은 근사 시킨 값이므로 정확성이 떨어져 스텝의 사이즈를 키워 멀리 갈수가 없다. 2차 미분값을 활용하여 근사 시키는 방법을 통해 그러한 문제를 해결할 수 있을 것이다.[그림10][그림11]

Second-Order Optimization

  • 위의 2차원을 다차원으로 확장시켜보면 이를 Newton step이라고 한다. Hessian matrix의 inverse matrix를 이용하게 되면 실제 손실함수의 2차 근사를 이용해 곧바로 minima로 이동할 수 있다는 것이다. 다른 알고리즘들과 달리 learning rate를 사용하지 않는다. 실제로는 2차 근사도 완벽하지 않기에 learning rate가 필요하다. 어디까지나, minima로 이동하는게 아니라 minima의 방향으로 이동하기 때문이다. 허나, inverse matrix를 구하기 힘들고 메모리에 대량의 파라미터를 저장할 방법이 없기에 이 알고리즘은 NN에서 사용되지 않는다.
  • Full Hessian을 그대로 사용하기 보다 근사시킨다. Low-rank approximations하는 방법이다.
2) L-BFGS
  • Hessian을 근사시켜 사용하는 second-order optimizer이다. 사실상 DNN에서는 잘 사용하지 않는다. 왜냐하면 L-BFGS에서 2차 근사가 stochastic case에서 잘 동작하지는 않으며, Non-convex 문제에도 적합하지 않기 때문이다. 단지 full batch update가 가능하고 stochasticity가 적은 경우라면, L-BFGS가 좋은 선택이 될 수 있다. NN을 학습시키는데 많이 사용되지는 않지만 Style transfer 같은 stochasticity와 파라미터가 적은 경우에서 Optimization을 해야할 경우에 종종 사용할 수 있다.
  • 위에서 살펴본 방법들은 학습과정의 error를 줄이기 위한 방법들이었다. 허나 우리가 진정으로 관심을 갖고 보아야 할 것은 test set의 error이다. 그런 test set의 error를 줄이기 위한 방안들을 다음에서 제시한다.

Model Ensemble

  • model을 train 시킨 후 우리가 가장 기대하는 바는 새롭게 들어온 test set에 대한 성능. 즉, test set에 대한 error가 작기를 기대한다. 그렇게 하는 가장 쉽고 빠른 방법이 바로 Model Ensemble이다. machine learning 분야에서 종종 사용하는 기법으로 예를 들어 설명하자면 모델을 하나만 학습시키지 말고 10개의 모델을 독립적으로 학습시키는 것이다. 결과는 10개 모델 결과의 평균을 이용한다. 모델의 수가 늘어날수록 Overfitting이 줄어들고 성능이 조금씩 향상된다. 보통 2%정도 증가한다. ImageNet이나 Kaggle competition 같이 모델의 성능을 최대화 시키는 것이 주된 목표일 경우 많이 사용한다. 허나 개인적으로나 주변의 조언들을 종합해보자면 우선 기본적인 base모델의 성능을 높이는데 주력하는 것이 더 좋을 듯하다. 실제로 실무에서는 Ensemble이나 Stacking같은 기법을 자주 사용하지는 않는다고 하기 때문이다. 하지만 한번 쯤은 만들어 보는 것도 좋은 것 같다. 또한 학습 도중 중간 모델들을 저장하고 앙상블로 사용할 수도 있다. 그리고 Test시에는 여러 중간 모델들을 통해 나온 예측값들을 평균을 내서 사용한다.

  • 만약 모델간의 Loss 차이가 크면 한쪽이 Overfitting 일수 있고, 차이가 작아도 안좋은 것은 아닐까라는 생각에 의해 좋은 앙상블 결과를 위해서라면 모델 간의 최저그이 갭을 찾는 것이 중요하지 않는냐는 생각이 들 수도 있겠지만, 언제나 말하듯 우리에게 중요한 것은 validation set의 성능을 최대화시키는 것이다.

  • 앙상블시에 다양한 모델 사이즈, learning rate, 그리고 다양한 regularization 기법 등을 앙상블 할 수 있다.

  • 이런 모델을 독립적으로 학습시키는 방법외에도 학습하는 동안에 파라미터의 exponentially decaying average를 계속 계산한다. 이 방법은 학습중인 네트워크의 smooth ensemble 효과를 얻을 수 있다. 즉, checkpoints에서의 파라미터를 그대로 사용하지 않고 smoothly decaying average를 사용하는 방법이다.(Polyak averaging)

Regularization

  • 모델에 어떤 조건들을 추가할 텐데 그 term들은 모델이 Training data에 fit하는 것을 막아줄 것이다. 그리고 한번도 보지 못한 데이터에서의 성능을 향상시키는 방법이다.
  • L2 regularization은 NN에는 잘 어울리지 않는다. 왜???
  • NN에서 가장 많이 사용하는 Regularization은 바로 dropout이다!!!

    • Dropout

      • Forward pass 과정에서 한 layer씩 출력(activation = previous activation * weight)을 전부 구한 후에 임의로 일부 뉴런을 0으로 만들어 주는데 매번 Forward pass마다 0이 되는 뉴런을 바꿔주어 특징들 간의 상호작용을 방지한다고 볼 수 있다. 즉, 네트워크가 어떤 일부 feature에만 의존하지 못하게 해준다. 다양한 feature를 골고루 이용할 수 있도록 하여 Overfitting을 방지한다고 볼 수 있다..보통은 0.5로 준다. [그림12]

      • 단일 모델로 앙상블 효과를 가질 수 있다는 것이다. 서로 다른 파라미터를 공유하는 서브네트워크 앙상블을 동시에 학습시키는 것이라고도 생각할 수도 있다. 그러나, 뉴런의 수에 따라서 앙상블 가능한 서브네트워크의 수가 기하급수적으로 증가하기 때문에 가능한 모든 서브네트워크를 사용하는 것은 사실상 불가능하다.

    • Dropout을 사용하면 Test time에는 어떤 일이 발생되나?

      • Dropout을 사용하면 기본적으로 NN의 동작자체가 변하게 된다. 기존의 NN은 w와 x에 대한 함수였다. 그러나 Dropout을 사용한면 Network에 z라는 입력이 추가된다. z는 random dropout mask이다. test시에는(예측시) 임의의 값을 부여하는 것은 좋지 않다. 왜냐하면 예측할때마다 결과가 바뀔수 있기 때문이다. 이런 randomness를 average out시키는데 적분을 통해 marginalize out시키는 것으로 생각해볼 수 있다. 허나 실제로는 까다로운 문제이므로 z를 여러번 샘플링해서 예측시에 이를 average out시키는 것이다. 하지만 이 방법도 test time에서의 randomness을 만들어 내기 때문에 좋지 않은 방법이다. 허나 다음 그림과 같이 test time에서 stochasticity를 사용하지 않고 할 수 있는 값 싼 방법 중 하나는 dropout probability를 네트워크의 출력에 곱하여 test time과 train time의 기대값을 같게 해주는 것이다. [그림13] 실제로 코드에서는 아래와 같이 예측시에 dropout probability를 곱해주거나 tip으로 train에서는 연산이 GPU에 의해 계산되어 추가되는 것에 별로 신경쓰지 않지만 Test time에서는 효율적으로 동작하길 바라므로 train시에 오히려 역으로 dropout probability를 나누어주는 식으로 수행할 수 있다. [그림14]

      • dropout을 사용하게 되면 Train time에서 gradient에는 어떤 일이 일어나는지 궁금할 것이다. 결론은 우리가 생각하던 Dropout이 0으로 만들지 않은 노드에서만 Backpropagation이 발생하게 된다. Dropout을 사용하게 되면 각 스텝마다 업데이트되는 파라미터의 수가 줄어들기 때문에 전체 학습시간은 늘어나지만 모델이 수렴한 후에는 더 좋은 일반화 능력을 얻을 수 있다.

      • 기본적으로 Dropout은 일반적인 regularization전략을 구체화시킨 하나의 예시에 불과하다. 이 전략은 Train time에는 네트워크에 randomness를 추가해 네트워크를 마구잡이로 흩뜨려 놓으므로써 Training data에 너무 fit하지 않게 해준다. 그리고 Test time에서는 randomness를 평균화 시켜서 generalization 효과를 주는 것이다. Dropout이 Regularization에 가장 대표적인 예이긴 하지만 Batch normalization 또한 비슷한 동작을 할 수 있다. 왜냐하면 mini-batch로 하나의 데이터가 샘플링 될 때 매번 서로 다른 데이터들과 만나게 된다. Train time에서는 각 데이터에 대해서 이 데이터를 얼마나 어떻게 정규화시킬 것인지에 대한 stochasticity이 존재했다. 하지만 test time에서는 정규화를 mini-batch 단위가 아닌 global 단위로 수행함으로써 stochasticity를 평균화 시킨다. 이러한 특성 때문에 Batch-Normalization은 Dropout과 유사한 Regularization 효과를 얻을 수 있다. 실제로 Batch-Normalization을 사용할 때는 Dropout을 사용하지 않는다. Batch-Normalization에도 충분히 regularization 효과가 있기 때문이다.[그림15]

      • Batch-Normalization과는 다르게 자유롭게 조절할 수 있는 파라미터 p가 있기 때문에 Batch-Normalization은 여전히 쓸모있다.

    • data augmentation

      • Regularization 패러다임에 부합하는 전략 중 하나이다. 예를 들어 고양이 사진을 classification 문제로 풀려고 할때, 이미지의 반전을 주어 입력한다던지 아니면, 임의의 다야한 사이즈로 잘라서(crop) 사용할 수 있다. 또한, color jittering도 있는데 간단한 방법으로는 학습시 이미지의 contrast 또는 brightness를 바꿔준다. 복잡한 방법으로는 PCA의 방향을 고려하여 color offset을 조절하는 방법이다. 이런 방법은 color jittering을 좀 더 data-dependent한 방법으로 진행하는 것으로 자주 사용하는 방법은 아니다.

      • data augmentation은 어떤 문제에도 적용해 볼 수 있는 아주 일반적인 방법이라고 할 수 있다. 어떤 문제를 풀려고 할 때, 이미지의 label을 바꾸지 않으면서 이미지를 변환시킬 수 있는 많은 방법들을 생각해 볼 수 있다.train time에 입력 데이터에 임의의 변환을 시켜주게 되면 일종의 regularization 효과를 얻을 수 있다. 그 이유는 위에서 언급하고 강조한 것과 같이 train time에는 stochasticity가 추가되고 test time에는 marginalize out 되기 때문이다.

    • DropConnect

      • Dropout과 다르게 activation이 아닌 weight matrix를 임의적으로 0으로 만들어주는 방법이다.
    • fractional max pooling

      • 보통의 경우, 2x2 max pooling 연산은 고정된 2x2 지역에서만 수행하지만 fractional max pooling에서는 그렇게 하지 않고 pooling 연산을 수행할 지역이 임의로 선정된다. 예를 들면 아래의 그림에서 Train time에 샘플링 될 수 있는 임의의 pooling region을 볼 수 있다. 그리고 test time에 stochasticity를 average out 시키려면 pooling regions를 고정시켜 버리거나 혹은 여러개의 pooling regions를 만들고 averaging over를 시킨다. 많이 사용하지는 않지만 좋은 방법이다.[그림16]
    • Stochastic Depth

      • Train time에는 layer 중 일부를 제거해 버리고 일부만 사용해서 학습한다. Test time에는 전체 네트워크를 다 사용한다. 최신의 연구이며 실제로 잘 사용하진 않지만 아주 좋은 아이디어이다.

보통 하나 이상의 regularization 방법을 사용하는데 그 중에서도 Batch-Normalization만으로도 충분하다. 다만 Overfitting이 발생한다 싶으면 Dropout과 같은 다양한 방법을 추가해 볼 수 있다. 이를 가지고 blind cross-validation을 수행하지는 않는다. 대신에 네트워크에 overfit의 조짐이 보일때 하나씩 추가시켜 본다.

Transfer Learning

  • overfitting이 일어날 수 있는 상황 중 하나는 충분한 데이터가 없을 때이다. 우리는 이런 상황에서 Transfer learning을 사용하여 문제를 해결 할 수 있다. 또한, 흔히들 CNN 학습에는 엄청많은 데이터가 필요하다고 생각할 수 있는데 그런한 사고를 무너뜨려 버려준다.

  • 1) 먼저 ImageNet 같은 아주 큰 데이터셋으로 학습을 한번 시킨다.
    ImageNet에서 학습된 feature를 우리가 가진 작은 데이터셋에 적용하는 것이다.이제는 1000개의 ImageNet 카테고리를 분류하는 것이 아니라 10종의 강아지를 분류하는 문제이다. 데이터는 엄청 적다. 이 데이터 셋은 오직 C(예:10개)개의 클래스만 가지고 있다.

  • 2) 가장 마지막의 Fully connected layer는 최종 feature와 class scores간의 연결인데 이를 초기화시킨다. 또한, 기존의 ImageNet은 4,096 x 1,000 차원의 matrix였지만 이제는 우리가 10개의 클래스를 갖으므로 4,096 x 10 차원의 matrix로 바꿔준다. 나머지 이전의 모든 레이어드르이 가중치는 그대로 둔다. 이렇게 되면 linear classifier를 학습시키는 것과 같다. 왜냐하면 오로지 마지막 레이어만 가지고 우리 데이터를 학습시키는 것이기 때문이다.

이러한 방법을 사용하면 아주 작은 데이터 셋일지라도 아주 잘 동작하는 모델을 만들 수 있다.

  • 만일, 데이터가 조금 더 있다면 전체 네트워크를 fine-tuning 할 수 있다. 최종 레이어들을 학습시키고 나면, 네트워크의 일부만이 아닌 네트워크 전체의 학습을 고려해 볼 수도 있을 것이다 데이터가 더 많이 있다면 네트워크의 더 많은 부분을 업데이트 시킬 수 있을지도 모른다. 이 부분에서는 보통 기존의 Learning rate보다는 낮춰서 학습시킨다. 왜냐하면 기존의 가중치들이 이미 ImageNet으로 잘 학습되어 있고 이 가중치들이 대게는 아주 잘 동작하기 때문이다. 우리가 가진 데이터셋에서의 성능을 높히기 위해서라면 그 가중치들을 아주 조금씩만 수저정하면 될 것이다.

  • transfer learning은 거의 일상적인 수준이 되었다. 대부분은 ImageNet pretrained model을 사용하고 현재 본인의 task에 맞도록 fine tuning한다. captioning의 경우 word vectors를 pretrain하기도 한다. pretrained CNN 뿐만 아니라 큰 규모의 코퍼스로 부터 학습된 pretrained word vectors도 함께 이용할 수 있다. 허나, captioning task에서는 pretrained word vectors을 사용하는 경우가 많지 않고 크게 중요하지 않다.

문제에 대한 데이터셋이 크지 않은 경우라면 풀려는 문제와 유사한 데이터셋으로 학습된 pretrained model을 다운로드 받아라. 그리고 이 모델의 일부를 초기화시키고 가지고있는 데이터로 모델을 fine-tuning한다.

TensorFlow : https://github.com/tensorflow/models
Pytorch : https://github.com/pytorch/vision