이제는 사용하지 않는 공부방/Artificial intelligence

[밑바닥부터 시작하는 딥러닝] 6장 학습관련 기술들

환상상상속상 2021. 5. 7. 16:16

abstract.

신경망 학습에 중요한 방법들에 대해서 배운다.

- 매개변수 갱신 방법 ( sgd, momentum, adagrad, adam )

- 매개변수 초기화 방법 ( xavier, he )

- 배치정규화

- 오버피팅 보완: weight decay, drop out

 

1. 매개변수 갱신 방법

 

1) sgd

이처럼 최적화를 담당하는 optimizer을 클래스로 구분하여 모듈화 해두자.

 

2) momentum

위의 sgd의 경우, f = 1/20x^2 + y^2 처럼 x축으로 늘린 밥그릇의 모양을 하는 경우에 좋지않다.

(y축 방향으로는 가파르기때문에 기울어져 있지만 x축 방향으로는 완만하여 기울기가 존재하지 않고 실제 최적 값인 0,0에 접근하지 못한다. 실제 최적값과 다른 방향을 가르키기때문에 지그재그로 비효율적인 움직임을 보여준다.)

 

하지만, 모멘텀의 경우에는 물리에서와 같이 공기 저항에 해당하는 변수를 추가해준다.

 

x축 방향으로는 미약하게 움직이지만 y축 방향으로는 많은 변화가 있습니다. 그런데 모멘텀 값을 통해서 더 빠르게 다가가기때문에 비효율적인 움직임이 줄어들었습니다.

(추가로 관성이 존재하여 로컬미니멈에 빠질 가능성이 적어졌습니다.)

 

 

3) adagrad

learning rate decay를 발전시킨 기술입니다.

개별 prameter에 adaptive learning rate를 적용합니다.

 

h라는 변수를 추가하여 적용하는데, h는 기존 기울기 값을 제곱하여 계속 더해줍니다. (과거의 기울기를 계속 더해줍니다.)

즉, 움직인 정도가 클 수록 학습률이 낮아집니다. 왜냐하면 학습률에 H를 역수 취한 값을 곱해주기 때문입니다. 따라서 학습률 감소가 매개변수마다 미분 값이 다르기때문에 매개변수마다 각각 적용됩니다.

 

 

따라서, 원래 y축에 대하여 미분 값의 변동이 컸는데 그 큰 변동만큼 곱해주고 역수취해서 더해주기때문에 learning rate가 갱신되어 점점 변동이 작아진 것을 확인할 수 있습니다. ( 큰 움직임에 비례해 큰 폭으로 작아진다 )

 

4) adam

위의 momentum, adagrad를 융합한 기술입니다. 편향 보정이 잘된다고 하는데 정확히 모르겠다.

대체로 가장 좋은 방법이라고 한다.

 

 

 

2. 매개변수 초기화 방법

 

1) 초깃값을 0으로 하기

 

- weight decay 기술:

오버피팅을 보완하는 방법으로 l2 regularization라고도 불린다. 항을 추가하여 parameter의 값에 제한을 주는 방법이다. prameter가 커지게 되면 함수가 구불구불해지는데 항을 추구하여 완만하게 만들 수 있다.

 

parameter을 작게하고 싶다면, 초깃값 자체를 작게하는 것이 옳을 것이다. 하지만 0으로 하는 것은 bad idea이다.

오차역전파에서 모든 가중치의 값이 똑같이 갱신되기 때문입니다. 

 

0으로 초기화 -> 순전파 때 두 번째 층에 모두 같은 값이 전달 -> 역전파 때 두번째 가중치가 모두 똑같이 갱신됨 -> 가중치가 모두 같아짐.

 

- hidden layer의 활성화값 분포:

parameter의 초깃값에 따라 활성화값들이 어떻게 변화하는지 히스토그램을 그려보며 알아보자. 순전파를 통해서 활성화값을 확인한다.

**np.random.randn은 평균 0, 표준편차 1의 가우시안 표준정규분포 난수를 matrix array로 생성한다.

 

실험1. 표준편차가 1인 경우

 

사진과 같이 activation value가 0과 1에 치우쳐져 있다. sigmoid함수를 생각해보면 y값이 0,1인 경우 미분 값은 0에 가깝다. 따라서 역전파를 한다면 gradient vanishing문제가 발생하여 update에 어려움을 겪을 수 있다.

 

실험2. 표준편차가 0.01인 경우

사진과 같이 0.5 부근에 집중되어있습니다. 다수의 뉴런이 같은 값을 출력하고 있으니 뉴런을 여러 개 둔 의미가 없어진다. 하나의 layer의 여러 뉴런이 같은 값을 나타낸다는 것은 한 개의 뉴런이 있음과 다름이 없다.

 

2) 선형인 활성화 함수를 사용한다면, Xavier 초깃값 사용하기

 

따라서, 우리는 위의 실험을 통해 (1)초깃값이 0인 경우 가중치가 모두 같아진다는 문제점, (2)gradient vanishing 문제점, (3)표현력의 제한 문제점을 알게 되었습니다.

 

이를 해결하기 위해서 새로운 초깃값을 사용합니다.

이 초깃값을 사용하면 가중치의 적절한 분포를 가질 수 있습니다.

 

초깃값의 표준편차가 1 / ( np.sqrt(n))이 되도록 설정합니다.

 

 

완전하게 분포되어있지는 않지만 앞서 본 것보다 넓게 분포하여 상대적으로 효율적인 학습이 가능해보입니다.

( sigmoid가 아니고 tanhx를 사용하면 일그러짐이 개선됩니다. )

 

3) ReLU를 사용한다면, He 초깃값 사용하기

 

초깃값의 표준편차가 np.sqrt( 2 / n )이 되도록 설정합니다.

(앞선 함수는 0에서 대칭이었던 반면 relu는 음의 영역이 0이므로 더 넓게 분포시키기 위해서 2를 곱했다고 생각할 수 있습니다.)

(범위가 양수로 좁아졌으므로 표준편차를 늘려서 더 넓게 분포시키려 합니다.)

 

relu함수를 사용하고, std = 0.01, Xavier, He 때의 결과를 비교해보겠습니다.

 

 

std = 0.01, 활성화값이 너무 작아서 기울기 역시 작아지고 학습이 잘 되지 않습니다.

 

Xavier, 활성화값의 치우침이 생기고 gradient vanishing이 생길 가능성이 높아집니다.

 

결론적으로, sigmoid, tanhx 같은 s모양인 경우에는 Xavier 초깃값을 사용하고, ReLU를 사용하는 경우 He 초깃값을 사용하면 됩니다.

실제로 학습을 한 결과 std = 0.01은 학습이 이뤄지지 않고 Xavier에 비해 He인 경우 학습이 잘되는 것을 확인할 수 있었습니다.

 

 

3. Batch Normalization

 

앞선 내용에서는 초깃값을 조절하여 활성화값을 널리 분포하도록 하였습니다.

그렇다면 이를 "강제"하여 활성화값을 널리 분포하는 것은 어떨까요?

 

이를 통해 아래와 같은 효과를 얻을 수 있습니다.

- 학습이 빨리된다.

- 초깃값에 의존하지 않는다. (초깃값 고려하지 않아도 됨)

- 오버피팅을 보완한다. (드롭아웃 안써도 됨)

 

각 affine layer과 activation layer 사이에 batch normalization layer을 통해 사용할 수 있습니다.

mini batch를 기준으로 고등학교 때 배운 방식을 사용하여 m = 0, std = 1로 정규화합니다.

 

이를 통해 입력데이터를 정규화하면 덜 치우치게 된다 -> 왜?? 평균이 0이고 표준편차가 1로 변하므로 가우시안 분포 모양으로 변하기때문이다. (아래 링크를 확인하자)

gaussian37.github.io/dl-concept-batchnorm/

 

 

 

4. 오버피팅 보완

 

매개변수가 많아 표현력이 높은 모델, 훈련 데이터가 적은 경우, 오버피팅 문제가 발생할 수 있습니다.

 

해결방법은 아래와 같습니다.

- weight decay

- drop out

 

1) weigth decay ( L2 regularization )

가중치의 제곱 노름을 손실 함수에 더합니다. 가중치가 커지는 것을 억제할 수 있습니다.

결과적으로 train accu와 test accu가 줄어들었습니다.

 

2) drop out

뉴런을 임의로 삭제하며 학습을 하여 표현력이 증가되는 것을 억제합니다.

학습에서는 무작위로 뉴런을 선택해 신호를 전달하지 않고 테스트에서는 모든 뉴런에 신호를 보내 accu를 확인합니다.

 

 

self.mask를 통해서 삭제할 뉴런을 False로 표시한다. 그리고 dropout_ratio보다 큰 원소에 대해서는 True로 표기하여 학습에서 False인 원소는 신호를 흘려보낸다.

 

이때 코드와 같이 randn함수를 통해서 무작위로 원소의 값을 정해줄 수 있다.

정말 간단하게 말그대로 무작위로 뉴런을 학습시키지 않는 것이다. 순전파 때 신호를 통과시키면 역전파 때도 통과시키지만 반대의 경우에는 차단시킨다.

 

**ensemble learning과 dropout은 매우 비슷한데 그 이유는 ensemble learning은 여러 모델의 평균을 내는 것이라면 dropout은 하나의 모델에서 여러 모델을 만들어서 평균을 내는 방법이기 때문이다.

 

 

5. 적절한 hyperparameter 찾기

 

아래와 같은 hyperparameter가 있다.

-각 layer의 node_num

-batch_size

-learning rate

-weight decay 계수

-dropout_ratio

 

1) train, validation, test dataset

train: 학습시 사용

validation: hyperparameter 최적 값에 사용

test: metric에 사용

 

ex) np.random.shuffle을 통해서 데이터를 섞은 후에 사용하는 것이 좋다. 데이터가 편향되어 있을 수 있기 때문이다.

validation_num = int( x_ train.shape[0] * validation_ratio )

validation_ratio = 0.2

 

2) hyperparameter 최적화

범위를 log scale로 정해주는 것이 좋다. '10의 거듭제곱' 단위로 범위를 지정합니다.

ex) 10 ** np.random.uniform(-3, 3) 은 10^-3 ~ 10^3을 표현한다. 무작위로 범위 안의 숫자를 추출한다.

 

hyperparameter range를 정해준다 -> 설정된 범위에서 무작위로 추출 -> 에폭을 작게하여 검증데이터로 확인 -> 좁아진 범위를 앞의 과정을 통해 더 좁힌다 -> 반복하여 최적값을 정합니다.

 

앞선 방법은 개발자의 '직관'에 의해 찾아진다는 느낌이 강하다. 좀 더 엄밀한 방법을 위해 찾기 위해서는 bayesian optimization을 사용한 논문인 "practical bayesian optimizaitionof machine learning algorithms"를 참고하자. ( grid -> random -> bayesian optimization )

wooono.tistory.com/102 data-scientist-brian-kim.tistory.com/88

 

 

총정리.

매개변수 최적화를 하는 방법인 gd -> sgd -> momentum -> adagrad -> adam에 대해서 학습하였으며, 초기값을 통해 활성화값의 분포를 넓게하는 것이 중요하다. 따라서 초깃값 0, std = 0.01, xavier, he에 대해서 알아보았다. 그리고 배치정규화를 하면 학습 속도가 개선되고, 분포가 고르게 되어 초깃값을 고려할 필요없고, 오버피팅이 보완된다는 것을 알게 되었다. 또 dropout기법과 weight decay로 오버피팅을 보완할 수 있다는 것을 알았으며 마지막으로 parameter을 최적활하는 방법에 대해 알아보았다!