9 minute read

Abstract

Training loss를 개선하는 optimization방법들과 개선사항들을 설명하고 cost function 최적화를 끝낸 상황에서 Test loss를 개선하는 Regularization기법들도 설명한다. 대규모 데이터가 필요한 상황에서 모델 학습에 필요한 data scale을 줄여주는 Transfer Learning에 대해서도 다룬다.

Optimization

Optimizer는 loss를 줄이기 위해 Weight, Learning rate와 같은 neural network 속성을 변경하는데 사용되는 Algorithm이다.

stochastic Gradient Descent (SGD)

image-20240204183447113

미니 배치 안의 데이터에서 Loss를 계산하고 Gradient의 반대방향을 향해 parameter 행렬을 업데이트한다. 이 단계를 mini-batch단위로 수행하면 결국 붉은색 지역으로 수렴할 것이고, loss가 낮아질 것이다. 예를 들어 전체 데이터 셋이 100개의 데이터를 포함하며 이중에 10개씩 mini-batch를 구성한다고 가정하자, 그러면 1epoch(전체 dataset 학습)가 일어나는 동안 총 10개의 mini-batch가 순서대로 학습되게 되는데 첫 mini-batch가 SGD를 통해 W를 갱신해내면 갱신된 W는 두번째 mini-batch를 학습하기 위한 초기 가중치 행렬이 된다. 이때 가중치 갱신횟수를 iteration이라고 하는데 예시에서는 1 epoch에 총 10번의 iteration이 발생한다고 해석할 수 있다.

image-20240204183457670

이런 SGD에는 문제가 몇 가지 있다. 첫번째 문제는 W최적화 과정에서 불필요한 손실이 발생한다는 것이다. 위의 그림과 같이 W1, W2를 변수로 하는 Loss가 수직방향의 가중치 변화에 훨씬 더 민감하게 반응하게 된다. 현재 지점에서 Loss는 나쁜 condtion number(조건수)를 지니고 있다고 말할 수 있다. Loss가 특정 가중치 변수 W1에만 민감하게 반응해서 local minimum으로 바로 이동하지 못하고 지그재그로 이동하게 되는 것이다. 이러한 문제는 손실 함수가 고차원일수록 심각해지는 경향이 있다.

image-20240204183524772 local minimumimage-20240204183537146saddle point

두번째문제는 Local minimum에서 gradient가 0이 되어버린다면 SGD는 멈춰버린다는 것이고 세번째 문제는 Saddle point에 관한 것이다. 함수값이 지속적으로 내려가는 부분임에도 gradient가 0에 가까워져 더 이상 내려가지 못하는 문제가 생긴다. 1차원의 예제만 봐서는 local minimum이 더 심각하고 saddle point는 덜 심각해 보이지만, 고차원의 공간에서는 사정이 정반대다.

생성 공간이 1억 차원 정도 된다고 가정하면 saddle point가 의미하는 것은 어떤 방향은 Loss가 증가하고 어떤 방향으로는 Loss가 감소하는 경향을 보이는 상황이라고 판단할 수 있다. 1억 차원에서 생각해보면 이는 정말 빈번하게 발생한다고 추론할 수 있다. 반면에 local minimum은 1억개의 모든 방향에서 Loss가 상승하는 상황이라고 해석할 수 있다. 고차원 공간을 생각하면 그런 일이 발생하는 것은 매우 드문 경우다. 지난 몇 년간 알려진 사실은 very large neural network가 local minimum 보다는 saddle point에 취약하다는 것이다. saddle point 뿐만 아니라 saddle point의 근처에서도 문제는 발생하는데 gradient가 0에 가까우면 gradient가 매우 천천히 업데이트되기 때문이다. 게다가 SGD는 mini-batch의 데이터를 가지고 전체 Data set의 Loss를 추정하기 때문에 상대적으로 부정확한 추정값(noisy estimate)을 구할 수 밖에 없다.

SGD Momentum

image-20240204183639244image-20240204183643149

이러한 SGD의 문제를 해결하기 위해서 SGD에 Momentum을 추가하는 방법이 있다. 현재 미니 배치의 gradient 방향만 고려하는 것이 아닌 velocity를 함께 고려하는 것이다. Momentum의 비율을 결정하는 hyperparameter또한 추가된다. 이때 velocity에는 기존 이동 경향이 반영된다. \(Actual\,step = (Velocity * hyperparameter) + gradient\) 벡터를 연산해서 그 방향으로 나아가는 것이다. 엄청 간단한 방법이지만 지금까지 말했던 문제들을 해결하는데 많은 도움을 줄 수 있다. Local minimum과 saddle point문제를 생각해보면 물리적으로 공이 굴러 내려가는 것을 상상해 볼 수 있다. 이 공이 local minimum에 도달한다고 해도 여전히 velocity를 가지고 있기에 gradient=0이라도 움직일 수 있다. 따라서 어지간한 local minimum, 모든 saddle point에 대해서 면역을 가진다. 또한 high condition number problem을 해결하는데 도움이 된다. Gradient의 방향을 Velocity의 방향이 상쇄시켜주기 때문이다. 하지만 속도가 너무 커서 gradient의 방향이 제대로 반영이 되지 않는 경우가 존재할 수 있다. 이를 우리는 overshooting 문제라고 한다. Velocity의 초기값은 항상 0으로 초기화된다.

Nesterov momentum

image-20240204183744813image-20240204183750206

기본 SGD momentum은 현재 지점에서의 gradient를 계산한 후에 velocity와 더해주는데 Nesterov를 활용하면 우선 velocity방향으로 이동 후 그 지점에서 Gradient를 연산해 Velocity와 합쳐준다. 즉, Nesterov는 현재 지점에서 gradient를 연산하지 않고 velocity 방향으로 이동한 후 gardient를 연산해 기존 velocity와 더해주는 것이다. Velocity에 gradient정보를 조금 더 반영한다고 이해하면 편하다. Gradient와 velocity의 방향이 일치하는 경우 momentom기법은 global minimum을 지나칠 수 있다는 문제가 있지만 nesterov는 그럴 우려가 없기 때문이다.

AdaGrad (Adaptive Gradient Algorithm)

image-20240204183903630

Adagrad는 훈련 도중에 계산되는 gradients를 활용하는 방법이다. 학습 도중에 계산되는 Gradient에 제곱을 해서 계속 더해준다. 그리고 업데이트를 할 때 Learning rate*Gradient를 grad_squared로 나눠준다. 만약 bad condition number인 경우 변화율이 큰 가중치 방향의 속도는 줄어들고 변화율이 작은 가중치 방향의 속도는 커진다. 하지만 가중치의 제곱 값이 나눠짐에 따라 전체적인 속도가 줄어들게 될 수 있다는 단점이 있다. cost function이 볼록 함수가 아닌 Non-convex case에서는 중간에 멈춰버릴 가능성이 있는 것이다.

RMSProp

image-20240204183924977

기존의 누적값에 decay rate를 곱해준다. Decay rate란 지수적으로 감소하는 속도를 나타내는 개념인데 보통 decay rate로 0.99, 0.9를 사용해 decay rate를 통해 step의 속도를 조절할 수 있다. 초기에 설정해놓은 decay rate값에서 변동성을 낮춰 최대한 부드럽게 grad_squared의 변화가 형성되도록 변경한 것이다. Bad condition number problem에 대한 상대적인 대처 능력은 떨어지지만 전체적인 step의 크기가 빠르게 줄어들지 않아 Non-convex case에서의 문제가 많이 줄어들 수 있다. \(Grad\,squared = decay\,rate\,*\,grad\,squared+(1- decay\,rate)*dx*dx\) 위의 식은 지수 가중 평균 식이다. decay_rate가 1에 가까워질 때 오래된 데이터일수록 현재의 경향에 미치는 영향이 줄어든다는 것을 알 수 있다.

위의 식은 지수 가중 평균 식이다. decay_rate가 1에 가까워질 때 오래된 데이터일수록 현재의 경향에 미치는 영향이 줄어든다는 것을 알 수 있다.

image-20240204184042853

RMSProp이나 momentum은 기본 SGD보다 성능이 더 좋다. 그러나 momentum은 overshoots를 거쳐 minima로 돌아오지만 RMSProp은 각 차원 마다 상황에 맞도록 적절하게 궤적을 수정한다. AdaGrad는 RMSProp과 동일한 궤적을 그리나 점점 step이 작아져 끝점에 도달하지 못한다. 그렇다면 Ada계열과 Momentum계열을 조합하면 어떨까?

Adam

Adam은 first moment와 second moment를 활용해 이전의 정보를 유지시킨다.

image-20240204184118984

e-7은 분모가 0이 되는 것을 막아주는 상수이다. First moment는 gradient의 가중 합이다. 그리고 second moment는 gradient의 제곱의 가중 합이다. 우선 first_moment가 velocity의 역할을 담당하며 이후 second_moment(gradient 최솟값)으로 나눠준다. Adam은 마치 RMSProp + momentum과 같은데 두 종류의 유용한 특징을 모두 이용하는데 문제가 하나 있다. Adam의 초기 step, 즉 second moment 초기값 0에서 1회 업데이트하고 난 후의 상황을 가정해보자. Beta2는 decay_rate로 0.9, 0.99로 1에 가까운 값이라면 1회 업데이트 이후에도 second moment는 여전히 0에 가깝다. 분모가 0에 가까운데 반해 분자는 특정 값이 나오므로 초기 step이 엄청나게 커지게 된다. 이는 실제 손실 함수가 가파르기 때문이 아닌 second moment를 0으로 초기화시켰기 때문에 발생하는 인공적인 현상이다. 이를 해결하기 위해 보정하는 항을 추가한다(bias correction term).

image-20240204184142975

First/ second moments를 update하고 난 후 현재 step에 맞는 적절한 unbiased term을 넣어줘야 한다. 이를 통해 초기 step이 엄청나게 커지는 문제를 부분적으로 방지할 수 있다. Adam은 거의 모든 문제에서 잘 동작한다.

image-20240204184155697

Learning rates decay

처음에는 LR를 높게 설정한 다음 학습이 진행될수록 LR을 낮추고 학습시키는 것이다(step decay). 혹은 exponential decay처럼 학습과정 동안에 꾸준히 learning rate를 낮출 수도 있다.

image-20240204184206094

위 사진의 ResNet논문에서는 step decay learning rate 전략을 사용한다. 평평해지다가 갑자기 내려가는 구간은 Learning rate를 낮추는 구간이다. Learning rates decay는 부차적인 second hyperparameter이며 이는 학습 초기에 고려하지 않고 학습의 양상을 관찰하며 결정한다.

Order Optimization

image-20240204184249026image-20240204184312364

우리는 지금까지 1차 도함수를 이용해 기울기 값을 통해 최적화를 해나갔다. 이를 first-order optimization이라고 한다. 하지만 2차 도함수를 통해서 가중치를 갱신하는 방법도 있다. 이를 second-order optimization이라고 한다. 하지만 잘 안쓴다. 증명은 패스한다.

Regularization

image-20240204184331397

지금까지 Training Error를 줄이기 위한 방법들을 설명했다. train과정의 성능을 높이기 위한 방법들이다. 하지만 우리는 한번도 보지 못한 데이터에 대한 성능, 즉 test성능이 훨씬 중요하다. 우리가 원하는 것은 train error와 test error의 격차를 줄이는 것이다.

질문은 바로 우리가 손실 함수 최적화를 이미 끝마친 상황에서 한번도 보지 못한 데이터에서의 성능을 올리기 위해서는 어떻게 해야 할 것인가? 이다. 가장 쉽고 빠른 방법은 모델 앙상블이다.

image-20240204184341642

아이디어는 아주 간단하다. 모델을 하나만 학습시키지 말고 10개의 모델을 독립적으로 학습시키는 것이다. 결과는 10개 모델 결과의 평균을 이용한다. 학습한 10개의 가중치 W를 평균 내서 활용하는 것이다. 모델의 수만큼 다양한 관점에서 데이터 셋을 분석할 수 있고 이는 일반화 능력을 상승시켜 overfitting 위험성을 낮춰준다. 모델의 수가 늘어날수록 overfitting이 줄어들고 성능이 보통 2%정도 향상된다. 모델을 여러가지 만드는 것이 비용, 시간적으로 부담이 된다면 오른쪽 그래프처럼 학습 도중에 모델들을 저장해서 이를 평균 내는 방식이 있다. 각각 learning rate를 다르게 해서 여러 지점에 수렴하게끔 만든 것이다.

앙상블이 아닌 단일 모델의 성능을 향상시키는 방법으로는 전통적인 regularization방법들이 있다.

손실 함수에 추가적인 항을 삽입하는 방법이 있다. L2 regularization이 대표적이나 Neural Network에는 잘 어울리지 않는다.

Dropout

image-20240204184411172

Forward pass과정에서 임의로 일부 뉴런을 0으로 만드는 것이다. 한 레이어의 activations를 전부 구한 뒤 임의로 일부를 0으로 만든다. 그리고 다음 레이어로 넘어가는 식이다. Forward pass iteration마다 mini-batch 단위로 모양이 계속 바뀌게 된다. 일부 값들을 0으로 만들면서 training time의 Network를 훼손시킨다. 대략적으로 말하자면, 특징들 사이의 상호작용을 방지한다고 볼 수 있다. Layer의 특정 뉴런은 입력 데이터의 어떤 특징에 대해서 학습할 것이다. 이때 Drop out을 적용하게 되면 네트워크가 어떤 일부 features에만 의존하지 못하게 만든다. 대신 다양한 features를 골고루 활용할 수 있도록 한다. 이는 overfitting을 어느정도 막아주는 효과가 있다. 그리고 Dropout이 단일 모델로 앙상블 효과를 가질 수 있다는 시각 또한 존재한다. 왜냐하면 Dropout으로 만들 수 있는 서브 네트워크의 경우의 수가 정말 다양하기 때문이다. Mini-Batch마다 다른 node가 꺼지기 때문에 Dropout은 아주 거대한 앙상블 모델을 동시에 학습 시키는 것이라고 볼 수 있다. 당연히 Test time에는 Dropout 기법을 적용시키지 않는다. Dropout은 train 과정에서 model의 일반화 성능을 올리기 위한 도구이다.

결국 Dropout 기법은 네트워크에 randomness를 추가해 특정 feature에 과도하게 fit하는 것을 방해하는 것이다. 그리고 Test time에는 randomness를 평균화시켜서 generalization 효과를 주는 것이다. Batch normalization 또한 dropout처럼 Regularization역할을 할 수 있는데 Train time에는 Mini-batch단위로 정규화한 데이터 분포에 noise가 생길 수 있으나 test time에는 이 Mini-batch단위마다 연산한 parameter들을 평균해 global 단위로 정규화를 수행하기 때문에 Regularization 효과가 존재한다. Dropout과 유사하나 activations가 아닌 weight matrix를 임의적으로 0으로 만들어주는 Dropconnect라는 방법도 있다.

Data augmentation

Data augmentation 또한 regularization 패러다임에 부합하는 전략이다.

image-20240204184442656

image-20240204184445729

기본 버전의 학습과정에서는 데이터 + 레이블을 통해 매 스텝 CNN을 업데이트했다. 그렇다면 train time에 레이블은 유지시킨 채 이미지를 무작위로 변환시켜 볼 수도 있을 것이다. 가령 이미지가 horizontal flips(수평 반전)될 수도 있고 이미지를 임의의 다양한 사이즈로 crop(자르기)할 수도 있다. 그래도 여전히 우리 눈에는 고양이로 보인다. 이처럼 train time동안 input data에 임의의 변환을 시켜주게 되면 일종의 regularization효과를 얻을 수 있다. Train time에는 stochasticity(무작위성)가 추가되고 test time에는 marginalize out(평균화)되기 때문이다.

Fractional max pooling

image-20240204184535582

보통 2X2 max pooling 연산은 고정된 2X2 지역에서 수행한다. 하지만 Fractional max pooling에서는 pooling 연산을 수행 할 지역이 임의로 선정된다. 그리고 test time에 stochasticity를 average out(평균화)시키려면 무작위로 생성한 pooling regions를 고정시켜 버리거나 혹은 여러 개의 pooling regions를 만들고 averaging over(평균화)시킨다.

Stochastic depth

img

2016년에 나온 최신 연구이다. DNN의 train time에 네트워크의 layer를 randomly drop해보자. 그리고 test time에는 전체 네트워크를 다 사용한다. 즉 test time에는 drop out기법을 쓰지 않는 것이다. regularization효과는 dropout과 같은 다른 방법들과 유사하다. 일반적으로 regularization으로는 batch normalization을 많이 사용한다. 하지만 BN을 추가해도 overfitting이 발생한다 싶으면 Dropout과 같은 다양한 방법을 추가해 볼 수 있다.

Transfer Learning

지금까지는 train/test error간의 격차, 즉 overfitting을 줄여보려는 regularization기법을 배웠다. Overfitting이 일어날 수 있는 상황 중 하나는 바로 충분한 데이터가 없을 때이다. 우리는 엄청 크고 powerful한 model을 원할지 모르겠지만 그 모델은 아주 작은 data set을 지나치게 overfitting할 수 있다. Regularization이 이를 해결할 수 있는 전략 중 하나이지만 Transfer Learning(전이 학습)이라는 방법 또한 존재한다.

image-20240204184644593

Transfer learning은 CNN학습에 엄청 많은 데이터가 필요하다는 미신을 무너뜨릴 수 있다. 아이디어는 정말 간단하다. 한 CNN 모델에 우선 ImageNet과 같은 아주 큰 data set으로 학습을 한번 시킨다. 그리고 ImageNet에서 학습된 features를 우리가 가진 작은 data set에 적용하는 것이다. 이제는 1000개의 ImageNet category를 분류하는 것이 아니라 10종(10-class)의 강아지를 분류하는 문제로 변한다. 필요한 데이터의 양은 ImageNet에 비해 매우 적다. 여기서부터 일반적인 절차로 최종 feature와 class score간의 연결인 FC-layer를 초기화시킨다. 기존 ImageNet을 학습시킬 때는 4096X1000차원의 행렬이♘으나 우리는 새로운 문제를 풀기 위해 4096X10으로 바꿔주게 된다. 새로운 특징 행렬에 대해 학습하므로 FC layer는 초기화시키는 것이다. 그리고 나머지 이전 layer의 모든 weight는 freeze시켜서 linear classifier를 학습시키는 것과 같게 만든다. 이 방법을 잘 사용하면 아주 작은 data set으로도 아주 잘 동작하는 model을

만들 수 있다. 만일 데이터가 조금 더 있다면 전체 네트워크를 fine-tuning(미세 조정)할 수 있다. 최종 layer들을 학습시키고 나면 남은 데이터를 가지고 네트워크 전체의 가중치들을 미세하게 조정할 수 있다는 뜻이다. 이때 이미 ImageNet data 학습을 통해 어느정도 Loss를 최소화했으니 기존 Learning rate보다는 낮춰서 학습시킨다. 전체적인 관점으로 볼 때 Transfer Learning이란 이미지에서 특징을 추출하는 작업은 비슷한 분야에서 학습한 기존의 유명한 model parameter에 맡기고 추출한 특징으로 점수를 부여하는 FC-layer에는 내 train data에 어느정도 맞게 설계가 가능하도록 tuning을 하는 것이다. 따라서 transfer learning을 수행함에 있어서 아래와 같이 생긴 2X2의 격자 시나리오를 예상해 볼 수 있다.

img

우선 적은 양의 dataset이 있는 경우와 아주 많은 양의 dataset이 있는 경우가 있을 것이다. 그리고 이전에 학습된 dataset과 현재 데이터 셋이 얼마나 유사한지의 경우도 생각해 볼 수 있다. 기존의 데이터와 유사하고 소량의 데이터를 가지고 있다면 기존 model의 마지막 layer만 학습시켜 볼 수 있겠다. 데이터가 그보다는 많다고 생각이 되면 모델 전체를 fine-tuning해 볼 수도 있을 것이다. 하지만 ImageNet과 다소 다르게 생긴 data set(ex. X-rays)을 갖고 있다면 문제가 될 수 있다. 기존의 특징 추출방식을 달리해야 함으로 소량의 다른 data를 가지고 있다면 FC layer만 학습시킬 이유가 없다. 그러나 많은 양의 다른 데이터를 가지고 있다면 전체 layer를 fine-tuning하는데 활용할 수 있다. Transfer learning은 아주 보편적인 방식으로 거의 일상적인 수준이 되♘다. 요즘은 거의 모든 computer vision 관련 응용 알고리즘들이 모델들을 밑바닥부터 학습시키지 않는다. 대부분은 ImageNet 같은 대규모 dataset에 미리 학습된 model을 활용하며 응용 분야에 맞도록 fine-tuning을 수행한다.

Leave a comment