ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CS231n] 7강 Training Neural Networks II
    Study/CS231n 2020. 11. 21. 03:01

    7강에서는 optimization에 대해 더 배우고 regularization에 대해 배운다.

    dropout 또한 배운다.

     

    마지막에는 전이학습을 배운다.

     

    Fancier Optimization

     

    SGD에 대해 배웠다. batch 단위로 끊어서 데이터 loss를 계산하고 gradient descent의 방향으로 파라미터를 업데이트한다. 

     

    일반적으로 SGD방식에는 문제가 있다.

     

    gradient를 계산할때 이처럼 타원모형이라고 생각해보자. 빨간색점이 이모티콘이 있는 부분 까지 간다고 생각해보자.

     

    y축으로 가면 금방인데 x축은 엄청 완만하다. 위의 경우 Loss가 수직방향의 가중치 변화에 훨씬 덜 민감하게 반응한다. 

    gradient 방향이 고르지 못하기 때문에 위 그림 처럼 튀게 된다.

     

    이처럼 불균형한 방향이 존재하면 SGD는 잘 동작하지 않을 것이다.

    파라미터의 수가 많으면 이럴 확률이 더 큼.

     

    Local minma는 gradient가 0이되니까 내가 원하는 곳을 찾았다고 생각하고 멈춰버린다.

    saddle point는 순간적으로 기울기가 0이 되는 부분에서 멈춰버릴 수도 있다.

     

    파라미터가 많은 NN 일수록 saddle point에 취약하다. 또한 gradient가 작아서 업데이트가 매우 느리게 진행 된다.

     

    미니배치로 gradient를 업데이트 하면 정확한 값을 얻을 수 없다. 부정확한 값을 추정할 뿐이다. 노이즈를 억지로 줘도 그림처럼 이쁘지 않게 나온다.


    이를 해결하고자 모멘텀(momentum)이 나온다.

     

    기존의 SGD에서 가속도를 준다. gradient를 계산할때 velocity를 이용한다.

     

    즉 물리학에 가속도를 준다고 생각하면 된다.

    위 식에서 vx를 velocity, rho를 마찰계수로 보면 된다. rho 갑승ㄴ 보통 0.9 or 0.99를 준다.

     

    모멘텀 단어 자체가 운동량을 의미한다.

     

    SGD와 비교했을때 파랑색 선을 보면 더 부드럽게 이동하는 것을 확인할 수 있다. SGD보다 local minima와 saddle points 에서도 더 안전하다.

     


    Nesterov 모멘텀이 있다. velocity 위치에서 gradient를 예측하는 actual step을 그린다. 

     

    이둘의 가중 평균으로 구할 수 있다. 

     

    차이는 그냥 모멘텀은 gradient를 계산하고 velocity와 합쳐준다. 후자는 velocity 방향으로 먼저 움직인다. 

     

    첫번째 수식은 모멘텀과 비슷한데 파란색 부분으로 현재와 이전의 velocity간의 에러보정을 해준다.

     

    Nesterov 는 convex optimization에서 굉장히 뛰어난 성능을 보인다고 한다.

     

    하지만 보통 고차원, deep한 러닝에서는 non-convex가 더 많다. 그래서 Nesterov는 NN에서 성능이 좋지 않다고 한다.


     

    AdaGrad 방법이다. 이것은 각각의 매개변수를 갱신하는 알고리즘이다. training 중에 gradient를 활용한다. grad squared term을 이용한다. 식에서 볼 수 있듯이 학습 도중에 계산 되는 gradient를 제곱해서 더해준다. 

     

    업데이트 할때는 앞서 계산한 gradient 제곱근 항으로 나눠준다. 

     

    빨강색 부분이 위에서 말한 업데이트할때 제곱은 항으로 나눠주는 부분이다. 

     

    분모값이 계속 커지니까 step을 진행할 수록 값이 커진다. saddle point에 걸려서 멈출 수도 있다.

    AdaGrad도 convex한 경우에 유용하다.


    위와 같은 문제를 해결하고작 RMSProp를 사용한다.

     

    RMSProp는 grad squared를 그대로 사용한다. 하지만 누적시키는 것이 아니라 파란색 부분처럼 decay_rate를 곱해준다. 보통 0.9 or 0.99로 한다. 그 다음 저 식을 사용하면 step의 속도를 효율적으로 가속/감속 시킬 수 있다고 한다.

     


    모멘트계열과 adagrad 계열을 설명했다.

     

    이 둘을 합치면 어떻게 될까?? 바로 이게 더 발전된 최적화 방법인 Adam이다.

     

    위 식에서 first_moment가 모멘텀이다. 가중치의 합이다. 파랑색부분은 제곱근을 이용하는 Adagrad/RMSprop 방법이다.

    두개를 합친 모습이다.

    second_moment를 0으로 잡아주는데 초기 step 이 엄청 작아지는 것을 방지하고자 1e-7이라는 아주 작은 숫자를 더해준다.

     

    하지만 first time step에서 문제가 있다.

     

    1회 업데이트 후에 second_moment는 여전히 0에 가깝다. 이후 update step에서 엄청 작은 값으로 나눠주면 분자가 커져서 값이 튀어버릴 수 있다. 어차피 first_moment도 작은 값이라 상관 없다고 생각하는데 강의에서는 운이 안좋으면 큰 step이 발생 할 수 있다고 한다. 

     

    이를 해결하기 위해 초록색 부분인 Bias를 추가한다. 적절한 값으로 값이 튀지 않게 방지하는 것이다.

     

    그래프에서 볼 수 있듯이 아주 좋다.

     

    learning rate에 따라 값이 튀거나 느리게 된다. 이를 조절하기 위해 learning rate decay를 사용한다.

     

    처음에는 학습률은 높게 잡고 점점 낮추는 것이다.

     

    ResNet 논문이다. loss 그래프를 보면 감소하다가 평평해지다가 다시 내려가는 구간이 learning rate를 낮추는 구간이다.

    이 논문에서 step decay learning rate를 사용했다.

     

    학습에서는 learning rate를 초기에 잘 잡는 것이 중요하다.

     

     


    지금까지 우리는 1차 미분(First-order)을 이용해 Optimization을 했다. 즉 빨간색 부분에 있으면 그림 처럼 기울기를 구하는 것이다.

     

    2차근사 정보를 추가적으로 활용하는 방법이 있다. 

    2차 미분 행렬로 된 hessian matrix를 계산하고 역행렬을 이용하면 실제 손실함수의 2차 근사를 이용해 minima로 step이 이동할 수 있다.

     

    여기서 테일러 급수를 활용한다고 한다. 

    테일러 급수에 대한 자세한 개념 설명은 다크프로그래머님 블로그에서 공부하면 좋다.

     

    Hessian 방법을 통해 2차근사를 이용해 값을 찾아 갈 수 있다. 2차미분은 극소/극대 값을 알 수 있기 때문이다. 

     

    Q2에 딥러닝에서 나쁘다고 나와있다. 이유는 간단하다. hessian 행렬은 n*n행렬이다. 딥러닝 파라미터가 수만개니까 메모리가 벅차서 사용하지 않는다.

     

    그래서 Hessian을 근사시켜 활용하는 L-BFGS를 사용한다고 한다. 자세한 설명은 X

     

    정리하자면 Adam은 좋은 방법이다. 

    full batch이고 parameter가 적다면 L-BFGS도 좋다고 한다.

    여태까지 설명한 것들은 traing error을 줄이고 손실함수를 최소화 하기 위한 방법이었다.

     

    우리는 loss를 줄이면서 training과 val데이터 간의 차이를 줄여야한다. 오버피팅을 줄여야 하니까

     

    즉 한번도 보지 못한 새로운 데이터를 봤을때 이 상황에서 성능을 올리기 위한 다른 방법은 뭐가 있을까??

     

    Model 앙상블 방법이다. 다수개의 모델을 만들어 독립적으로 training 하고 평균을 구한다.

     

    모델이 다수니까 성능이 항상된다.

     

    90프로 이상일대 마지막 2% .확률을 올리기 위해 유용하게 사용된다고 한다.

     

    tip and tricks 이다. 모델을 학습시킬때 독립적으로 학습시키지 말고 학습 도중 모델들을 저장(snapshot)하고 앙상블을 한다.

     

    그리고 test할때 여러개의 snapshot에서 나온 평균값을 이용한다. 

     

    예를 들어 5개의 체크포인트?구간을 설정하면 5개 마다 새로하는 것이다. 모델을 여러개 만드는 것이 아닌 한 모델에서 구간을 나누어 마치 여러개의 모델 처럼 training 하는 것이다.

     


    Regularization

     

    앙상블은 모델을 여러개 만드니까 효율적이지 않다. 우리는 L1,L2 regularization을 배웠는데 실은 NN에서 많이 사용하지 않는다고 한다.

     

    Dropout 방법이다. Forward pass 에서 랜덤으로 노드를 삭제한다. zero로 만드는 것이다. 활성화 값 자체를 0으로 만든다.

     

    모델이 어떤 것을 예측할때 다양한 feature를 사용하도록 유도한다. 위에 그림 보면 고양이를 예측할때 ear, tail 관련 node가 없어진다고 생각하면 남은 node들이 이 정보까지 학습하려고 한다. 어떤 특정 feature만 의존하지 못하니까 overfitting을 줄여준다.

     

    그 다음 단일모델로 앙상블 효과를 보인다. foward pass 마다 랜덤하게 dropout하니까 마치 서로 다른 모델을 학습하는 것 처럼 느낀다.

     

    학습할때는 random mask 라는 z를 사용한다. 하지만 test할때는 이를 사용하지 않는다.

     

    test할때 이런 임의의 값을 부여하는건 좋지 않다. 그래서 average out 한다.

     

    Dropout을 0.5로 학습하면 경우의 수가 4가지다. 4개의 값을 평균화시켜주는데

     

    train과 test값이 서로 상이하지 않는다. 그래서 dropout probability(0.5)를 출력에 곱해준다.

     

    코드에서는 p를 곱해준다.

     

    이건 처음보는 내용이었는데 일종의 트릭이다. test time 에 곱하기연산은 train으로 옮긴다.

     

    즉 p로 나눠주는 것이다. 우리는 test time에서 효율이 중요하기 때문이다.

     

    dropout을 하면 학습시간이 늘어난다. 그 만큼 좋은 일반화 모델이 나온다.

     

    training에서는 random하게 training data가 fit 하지 않게 하고 test에서는 randomness를 average해서 사용한다.

    regularization 효과를 주는 것이다.

     

    그리고 뒤에 Batch Normalization이 나오는데 실제로는 dropout을 안하고 이걸 많이 쓴다.


     

    Data Augmentation 이다. 최근에 랩실에서 논문세미나 했을때 image 피라미드 관련해서 일종의 data augmentation이라고 생각했던 점이 기억이 났다.

     

    train 할때 이미지를 조금씩 변형시키는 것이다. 일종의 데이터를 많이 확보하는 것이다. 레이블은 유지시키면서

     

    이미지를 좌우 반전해도 고양이는 고양이다. 

     

    랜덤으로 잘라도 고양이는 고양이다. 

    이렇게 이미지를 임의로 변환시키면 일종의 regularization 효과를 얻는다. 

     

    색을 바꿔주는 color jitter도 있다.

     

    More complex하게 PCA방향을 고려해 color offset을 조절 할 수도 있다고 한다.

    그리고 pixel을 offset한 training image를 추가한다.

     

    Regularization하는 여러가지를 봤다. DropConnect라는 방법도 있다고 한다.

     

    activation이 아닌 weight matrix를 임의로 0으로 만든다.

     

    Fractional Max Pooling은 pooling 이 될 지점을 임의로 정한다.

     

    Stochastic Depth은 train time 에서 일부 네트워크 layer를 drop한다. 그리고 test time 에는 전부 사용한다. 

     

    dropout가 효과가 비슷하다.

     

    regularization은 보통 1개를 사용한다고 한다. BN이 대표적이다. BN으로도 overfitting이 나온다면 dropout을 추가해주기도 한다. 

     

    아직 블로그에 정리해서 올리지 않았지만 개인적으로 데이터를 가지고 이미지 처리를 했는데 이때도 accuracy높이기 위해 BN과 Dropout을 다 사용했다.

     


    Transfer Learning 

     

    전이학습은 CNN할때 많은 데이터가 필요하지 않다는 것을 보여준다.

    또한 원하는 데이터의 양이 없을때 사용한다. 

    먼저 imagenet과 같이 학습을 시킨다.

     

     

    이 훈련된 모델을 우리가 가진 Small dataset에 적용한다.

     

    image net에 비해 우리는 분류할려고 하는 카테고리의 데이터는 작은 상황이다.

     

    가장 마지막의 Fc layer는 최종 feature 와 class의 score간의 연결 고리이다. 이걸 초기화 시켜준다.

     

    그리고 차원을 줄이고 이전의 나머지 layer들의 가중치를 Freeze 해버린다. 우리는 마지막 layer만 가지고 데이터를 학습시킨다. 

     

    데이터가 조금 많으면 전체를 fine tuning 한다. 

    낮은 learning rate를 사용한다.

    컴퓨터 비전 관련 알고리즘은 pretrained-model를 사용하고 우리가 필요한 용도로 fine tuning하는 것이다.

     

    Image Captioning은 뒤에 RNN 관련 강의에서 더 자세히 나온다.

    Summary다. 

     

    이걸로 7강 요약을 마치겠다.

    댓글

Designed by Tistory.