오늘은 6강입니다.
6강 또한 제 소신껏 정리해 보겠습니다.
많이 어려워 지는 부분인데요.
그래도 다들 힘내서 같이 공부해 봅시다.
앞전에 우리는 위 그림처럼 computational graphs에 대해서 알아 보았습니다.
말 그대로 f = Wx + regularization 이다를 배웠습니다.
위 그림을 보겠습니다.
F = Wx 는 아주 기본적인 식입니다.
뉴럴네트워크에서는 hidden layer가 쌓이게 되는데요.
위의 기본적인 식인 F = Wx의 기본적인 식에서 층이 생기게 됩니다.
F = W2max(0,w1x) 이런식으로 층을 쌓는 것입니다.
위 그림들 처럼 우리는 CNN에 대해서 알아 보았습니다.
CNN은 큰 input에서 세부적으로 들어가면서 보는 것입니다.
그래서 CNN에서 사용하는 Filter , activation map , optimization 등을 배웠습니다.
위 그림들 처럼 우리는 SGD도 배웠습니다.
Training Neural Networks에 대해서 더 자세히 배워볼 시간을 갖겠습니다.
자 , 이제부터 Training Neural Networks에 대해서 알아 보겠습니다.
이번장에서는
활성화 함수 ( activation functions ) 들에 대해서 배우고 data preprocessing ( 데이터 전처리 )에 대해서 배울것입니다.
이후에 weight를 효율적으로 초기화 하는 weight initialization을 배우고
배치 정규화 ( Batch Normalization ) 등 이런것들을 배울것 입니다.
활성화 함수 ( activation functions ) 입니다.
activation function은 f = Wx에 대해서 앞에서 input값이 들어오면 이 값을 다음 노드로 보낼 때 값을 어떻게 보낼지를
정해줍니다.
보통 활성화 함수는 non-linear한 함수를 사용합니다.
input은 linear한 값이 들어오지만 여기를 통과하면 non-linear한 값이 나오게 되는 것입니다.
예를 들어보면 이해가 될 것입니다.
2개의 linear한 값을 사용한다고 하였을 때 , y ( x ) = h(h(x)) 처럼 되어서
보게되면 y = c ^ 2 이 되어 하나의 layer 처럼 되는 것입니다.
사용자의 의도는 2개의 layer가 쌓여야 하는 것인데 이게 1개 처럼 되는 것입니다.
그렇기 때문에 non-linear한 값을 사용하는 것입니다.
활성화 함수 ( activation function ) 의 역할은 말 그대로 '활성화'를 시켜주는 것입니다.
어떤 값이 들어오면 이 값들을 어떻게 활성화 시킬 것인지를 정하는 것입니다.
이 값이 다음 layer로 전달되는 것입니다.
이런 특징 때문에 활성화 함수의 종류에 따라서 그 값의 형태도 매우 다양합니다.
활성화 함수는 생각보다 다양한(?) 것들이 있습니다.
이제 위의 활성화 함수들을 각각 알아 보겠습니다.
위 그림을 보겠습니다.
Sigmoid 함수 입니다.
단순한 '단일','이진' 분류 등에서도 많이 쓰이고 있다고 합니다.
하지만 최종 출력에서만 사용합니다.
왜 그럴까요 ??
이유는 다음과 같습니다.
위 그림을 보겠습니다.
가장 큰 문제가 있습니다.
바로 기울기 소실 문제인 gradient vanishing 문제가 있습니다.
왜그럴까요...??
위 그림을 보겠습니다.
각각의 예제를 보겠습니다.
-10 , 0 , 10 일때 어떻게 될까요....??
위 그림에서 오른쪽 그래프를 보시면 아시겠지만
-10일 때 기울기가 거의 0이 됩니다.
10일 때도 마찬가지 입니다.
0일 때는 그나마 0에 가깝지 않은 상태를 보여주고 있습니다.
위 결과들을 기반으로 계속 backpropagation을 하게 되면 0과 가까운 값이 계속 곱해지게 됩니다.
그렇다 보니 기울기가 0에 매우매우매우 가까워진 수가 되어버려서 기울기가 소실되어 버리는 것입니다.
2번째 문제는 zero-centered가 되어 있지 않는 문제입니다.
위 그림을 보겠습니다.
위 그림을 보면 그래프의 기준점이 0이 아닌 다른곳에 기준점이 되어 있습니다.
0을 중심으로 될려면 y축도 0 밑으로 내려와야 할 것입니다.
그런데 보면 이것이 큰 문제가 될 듯 하진 않습니다.
그러나 왜 문제가 되는 것일까요!?
위 그림을 보겠습니다.
x가 언제나 양수일 때 어떻게 될까요...??
언제나 양수가 될 것입니다.
왜냐하면 들어오는 x는 앞단의 sigmoid 계산을 통해서 들어왔기 때문에 언제나 양수가 되는 것입니다.
이 상태에서 W의 gradient 값은 어떻게 될까요 ?
f ( 시그모이드 wixi + b ) 식을 미분해 보면 될 듯합니다.
미분을 하면 df / dwi = xi 가 됩니다.
이 식을 다시 편미분 해보면 dL / dwi = dL / df * df/dwi 즉 dL / df * xi 가 됩니다.
근데 xi는 sigmoid 처리가 되어서 넘어오기 때문에 무조건 양수가 됩니다.
결국 dL / dwi 는 dL / df의 부호에 따라서 부호가 결정이 되는 것입니다.
dL / df 가 음수이게 되면 음수인 것이고 , 양수이면 양수가 되는 것입니다.
즉 , W의 gradient는 모두 양수이거나 모두 음수이게 되는 것입니다.
그래서 위 그래프를 보시면 모두 양수 혹은 모두 음수가 되기 때문에 지그재그 형태로 가게 되는 것입니다.
대각선으로 가는 것이 제일 이상적인 것인데
지그재그로 가다보니까 매우 비효율적이라는 것입니다.
이것이 문제입니다.
세 번쨰 문제는 exp 연산의 값이 비싸다는 것인데요
비싸다는 것은 어려운 연산이라는 것입니다.
그렇다 보니까 sigmoid는 잘 쓰지 않습니다.
위 그림은 sigmoid 을 약간 바꾼 하이퍼볼릭 탄젠트 ( tanh) 입니다.
Zero centered가 되어 있습니다.
그러나 기울기 소실문제와 exp연산이 남아 있죠.
위 그림을 보겠습니다.
ReLU ( Rectified Linear Unit ) 입니다.
이것은 사용자들이 가장 많이 사용하는 activation functions 입니다.
ReLU는 0 이하이면 전부 0 으로 그 이상인 값들은 그 값대로 내보냅니다.
그렇기 때문에 f(x) = max(0,x)의 식을 가지게 되는 것입니다.
이렇게 보면 매우 간단해 보이는 데요.
맞습니다. 간단하며 작동이 잘 되는 활성화함수 입니다.
그러나 ReLU 또한 문제가 있습니다.
zero-centered가 되어 있지 않으며 0 이하 값들은 전부 버리게 되는 것입니다.
위 그림을 보겠습니다.
x의 값이 -10 혹은 0 이게 되면
0이 되게 되는데요 .
이렇게 된다면 dead ReLU에 빠지게 됩니다.
위 그림처럼 전부 0이 되어버리기 때문입니다.
그래서 위 그림처럼
사람들은 0.01의 bias 값을 주자고 하였습니다.
조금이라도 움직임을 주자는 것인데요.
이렇게 해서 보완되어 나온 것이 Leaky ReLU입니다.
0 이하의 값을 0.01x 값을 줘서 작은 값이라도 주게 하는 것입니다.
그리고 이걸 조금 변형한게 parametric Rectifier ( PReLU ) 입니다.
이거는 알파 값을 줘서 이것도 일종의 학습을 통해 찾아는 방법이다 라고 생각하시면 될 것 같습니다.
ReLU의 변형으로 나온 것이 ELU라는 것이 있습니다.
이것도 ReLU의 모든 장점을 가지고 있고 zero mean과 가까운 결과가 나오게 됩니다.
exp 계산을 해야하는 것이 단점이라고 합니다.
Maxout 이라는게 있는데 max() 값을 통해서 2개의 파라미터를 준 뒤 더 좋은 것을 선택하는 것입니다.
그런데 이것은 연산량이 2배가 되어서 잘 사용하지는 않는다고 합니다.
일반적으로 딥러닝에서는 ReLU와 Leaky ReLU를 많이 사용한다고 합니다.
Tanh는 RNN과 LSTM에서 자주 사용합니다.
sigmoid 는 절대 사용하지 않는다고 합니다.
데이터 전처리는 무엇인지 알아 보겠습니다.
데이터 전처리는 zero-centered , normalized를 많이 사용합니다.
zero-centered는 앞에서 다뤄본 내용으로써 중요한 부분입니다.
normalized는 특정 범위 안에 이 값들을 모아놓은 것입니다.
예를 들면
값의 차이가 많이 나는 값들이 있다고 해봅시다.
그래프 상에 찍게 되면 그래프의 모양이 뒤죽박죽이 될 것입니다.
그래서 표준편차를 나눠줍니다.
하지만 이미지에선은 사용하지 않습니다.
왜냐하면 이미지의 값은 0 ~ 255 라는 값이 이미 정해져 있기 때문입니다.
그래서 normalized 를 하진 않고 zero-centered를 사용하는 것입니다.
그 외에도 PCA , Whitening data 가 있는데 이 것들은 이미지에서 잘 사용하지는 않는다고 하네요.
이미지에서는 zero-centered를 주로 하고
방법은 채널별로 하나씩 , 전체를 하나로 나뉘어 지는데
다 다르다고 하네요.
이제 Weight Initialization에 대해서 알아 보겠습니다.
만약 w가 0이면 어떻게 될까요...??
Gradient vanishing 이 발생할 것입니다.
첫번째 생각이 바로 랜덤의 작은 값들을 넣는 것입니다.
위의 그림과 같이
0.01 * np.random.randn(D,H)를 통해 랜덤으로 값을 넣어주는 것입니다.
생각보다 잘 된다고 하네요.
그러나 네트워크가 깊어질수록 문제가 생깁니다.
위 그림을 보겠습니다.
위 그림처럼 네트워크를 10개의 레이어에 500개 노드를 두고 활성화 함수는 tanh을 사용합니다.
위 그림을 보겠습니다.
보시면 알겠지만 레이어가 깊어질수록 값들이 전부 날라가게 됩니다.
tanh 그림을 보면 기울기가 0인 지점이 날라가게 됩니다.
기울기가 0이 안되는 지점 ( 가운데 지점 ) 만 살아남는 것입니다.
결국에는 위 그림처럼
액티베이션들이 0이 되버리는 것입니다.
그렇다면 0.01 대신에 1을 곱해서 값을 크게 하면 어떻게 될까요...??
위 그림처럼 w 값이 너무 크기 때문에 -1 과 1에 포화가 되버리고 맙니다.
그래서 적절한 weight 값을 주기 위해서 Xavier initalization을 사용하게 됩니다.
Xavier initialization은 무엇인가 하면
노드의 개수 (fan_in) 을 normalized 하자 입니다.
큰것은 큰값으로 나눠주고 작은것은 작은값으로 나눠주는 것입니다.
즉 , input의 개수가 많아지면 나눠주기 때문에 값이 작아지고
input의 개수가 적으면 weight값이 커지는 식으로 weight를 초기화 하는 것입니다.
하이퍼볼릭 탄젠트에서는 잘 적용이 되지만 ReLU에 적용이 잘 안되는 문제가 있습니다.
그래서 2015년 카이밍 he가 2를 나눠주는 방식을 적용했더니 잘 동작하던데? 라고 발표를 하게 됩니다.
ReLU에서는 2를 나눠주어 진행합니다.
위 그림을 보시면 성능이 괜찮은 것을 알 수 있습니다.
위 그림을 보시면 아시겠지만
이 weight initialization 분야는 지금까지도 활발하게 연구가 진행되고 있음을 보여 주고 있습니다.
그렇지만 우리가 굳이 weight initalization을 안해도 되는 방법이 있습니다.
다음에서 다뤄볼 Batch Normalization 입니다.
Batch normalization ( BN ) 은 기본적으로 Gradient Vanishing이 나오지 않도록 하는 아이디어 입니다.
training 하는 과정 자체를 전체적으로 안정화시켜 주는 것입니다.
이것은 internal covariance shift를 방지하는 것입니다.
network 각 층이나 activation 마다 input의 distribution이 달라지는 것입니다.
이걸 막기 위해서 각 층의 input distribution을 평균 0 , 표전편차 1인 분포로 만들어 버리는 것입니다.
우리는 input을 한 번에 처리하지 않고 batch 별로 처리를 합니다.
그래서 위 그림에서 처럼 N x D의 input이 들어오게 됩니다.
이 batch가 들어오면 이걸 normalize 한다는 것입니다.
위 그림을 보겠습니다.
위 그림은 일반적으로 activation전에 잘 분포되도록 한 다음에 activation을 진행할 수 있도록 해줍니다.
그래서 FC --> BN --> activation 으로 들어가게 되는 것입니다.
그런데 여기서 BN을 하면 unit gaussian이 되게 되는데
이게 적합한 것인지 아니면 적합하지 않은지를 생각해야 합니다.
BN에서는 이런 판단 조차도 학습에 의해 가능하다라고 말하고 있습니다.
처음에 normalize를 하고
두 번째에 정규화된 것을 조정할 수 있도록 기회를 주고
감마랑 이런 저런 값들이 있는데 감마는 노멀라이즈 스케일링 값 등과 같습니다.
y(k)에다가 위의 x식과 감마 등의 식을 대입하면 상쇄가 되기 때문에
BN을 undo 할지 do할지 판단을 하게 되는 것입니다.
B는 쉬프트하는 값을 의미합니다.
이 감마와 B도 학습을 통해서 값을 찾게 되는 것입니다.
결론적으로 학습을 통해서 BN을 어느정도로 할 것이냐를 결정할 수 있다라는 말입니다.
위 그림은 실제 값들이 어떠한 과정을 거치게 되는지 나타낸 것입니다.
첫번째로 mean값을 구한 다음 normalize를 합니다.
그리고 scale은 어느 정도 퍼지게 해주는지 정하는 것이고 shift는 이동하는 정도를 의미합니다.
여기서의 scale과 shift 는 학습을 통해서 값을 찾습니다.
보통 BN을 하면 Dropout을 안써도 된다고 합니다.
그 이유는 Dropout은 랜덤하게 값을 꺼내주기 때문입니다.
BN도 마찬가지로 배치마다 값이 조금씩 다르게 들어가고 값이 계속 바뀌게 되니까 노이즈가 적어지게 된다고 합니다.
이제 Learning Process에 대해서 알아보도록 하겠습니다.
첫 번째는 전처리 입니다.
이미지 인식에서는 zero-centered를 합니다.
이미지 값이 0 ~ 255 값을 가지고 있기 때문입니다.
그런 다음 아키텍처를 선택합니다.
Hidden layer를 어떻게 구성할 것인지 등을 선택하는 것입니다.
그리고 이렇게 레이어를 구상했으면 loss값이 잘 나오는지 확인을 합니다.
여기서 보면 sanity check 방식을 사용하게 되는데요.
softmax 에서는 loss가 -log(x)였습니다.
그런데 규제값을 0으로 줘버리게 되면 -log(1/c)가 나오게 됩니다.
그 값이 2.3인 것입니다.
규제값을 살짝 올렸을 때 loss가 증가된 것을 볼 수 있습니다.
이렇게 우리의 layer가 동작하는지 확인하는 것이 sanity check 입니다.
그 다음 훈련을 시켜봅니다.
모든 데이터를 넣지 않고 작은 데이터셋을 먼저 넣습니다.
위 그림처럼
데이터 수가 작기 때문에 거의 100 % overfitting이 나오게 됩니다.
그래서 train accuracy가 100% 나오게 되는 것입니다.
이것은 overfitting이 제대로 되고 있으면 모델이 동작한다는 것을 의미합니다.
그러고 나서 regularization 값과 learning rate 값을 찾아 볼 것입니다.
적절한 값들을 넣어줘서 차례대로 찾아보는 것입니다.
Learning rate가 1e-6 일 때 loss가 바뀌는 것을 위 그림에서 확인할 수 있습니다.
lr값이 너무 작기 때문에 cost 값이 매우 조금씩 떨어짐도 알 수 있습니다.
위 그림에서와 같이 train값은 서서히 증가됨을 확인할 수 있습니다.
위 그림에서와 같이
아무리 작아도 조금씩 훈련은 되고 있기 때문에 accuracy가 증가되는 것을 확인을 할 수 있습니다.
위 그림에서와 같이 이제 learning rate 값을 1e6 으로 올려보겠습니다.
결과를 보겠습니다.
보면 cost 값이 nan이 됩니다.
이것은 값이 너무 커서 튕겨져 나가버리게 된 것을 의미합니다.
그래서 3e-3으로 수정을 해봅니다.
그래도 inf 로 튕겨져 나가버리는 것을 확인할 수 있습니다.
위와 같은 결과를 토대로
저희는 1e-3 ~ 1e-5값이 적당하겠는데(?) 라고 추측을 할 수 있습니다.
위와 같은 과정을 통하여서 적절한 lr값을 찾아가는 것입니다 !!
이제 Hyperparameter Optimization을 알아 보겠습니다.
처음에는 넓은 값의 범위에서 좁은 범위로 줄여나가는 방법을 사용합니다.
위 그림을 보겠습니다.
보시면 10 ** uniform ( -5 , 5 ) 값을 취해줍니다.
로그값을 취해주면 값이 더 안정적으로 되기 때문에 log값을 취해준다고 합니다.
개인적인 생각이지만 이것또한 일종의 normalization 이라고 생각이 듭니다.
이 범위에서 하니까 nice한 영역이 보입니다.
바로 val_acc 가 48 % 가 나오는 지점입니다.
lr 값이 e-04인 지점입니다.
그리고 reg 는 e-01이구요
다시 진행해서 이 값의 범위를 좁혀보겠습니다.
위 그림처럼
Reg는 -4에서 0 , lr는 -3에서 -4로 수정한 화면입니다.
이렇게 하니까 best 지점이 이제 53%지점으로 변경되었음을 확인할 수 있습니다.
이런식으로 좁혀나가는 것입니다.
하지만 53% 지점이 잘 나온 것은 아닙니다.
왜냐하면 -3 부터 - 4 까지 다 보니까 범위에 들어가지 않는 값이 있을 수도 있습니다.
처음에 nice한 지점이 lr이 e-04 , reg가 e-01이어서 값을 저렇게 수정했지만 이게 값을
모두 충족시키지 못할 수도 있기 때문입니다.
그래서 값을 조금 줄여줘서 하는게 좋을듯 합니다.
예를 들어서 - 3 이 아니라 - 2.5 정도의 값으로요 !!
이렇게 찾는 방법은 그리스 서치 ( grid search ) 와 random search 2가지 방법이 있습니다.
여기서는 random search가 더 좋습니다.
위 그림에서와 같이 grid search는 일정한 간격이기 때문에 랜덤 서치가 더 좋아보입니다.
그렇지만 랜덤은 말 그대로 랜덤으로 떨어지기에 더 좋은 값의 영역에 접근할 확률이 좋다고 합니다.
그래서 보통은 random search를 사용한다고 합니다.
이렇게 하이퍼파라미터를 찾는 과정은 위 그림처럼 DJ가 클럽에서 노래를 킬 때 기계{를 조절하는 것과 같다고 얘기하고
있습니다.
저 기계를 조절함으로써 좋은 사운드가 나오게 합니다.
하이퍼 파라미터도 이렇게 조절하면서 좋은 값을 찾아내는 것입니다.
하이퍼 파라미터는 네트워크 아키텍처 , learning rate , dccay , regularization 등이 있다고 합니다.
위 그림을 보겠습니다.
위 그림은 loss curve를 모니터링하면 나오는 그래프입니다.
노란색은 learning rate가 매우 높을 때이며 파란색은 learning rate가 낮을 때 , 초록색은 learning rate가 약간 높을 때를
의미하고 있습니다.
우리가 원하는 learning rate는 빨간색과 같은 것입니다 !!
가끔은 위 그림처럼 생긴 그래프를 볼 수 있습니다.
이 그래프는 처음에 적절한 값을 찾지 못해서 훈련이 되지 않다가 갑자기 어느 지점에 도달하여서 값을 찾았고
그 후로 학습이 되어버린 것입니다.
위 그래프를 보았을 때
앞부분에서는 initialization이 좋지 않았던 것입니다.
위 그림처럼
우리는 빨간색 선과 초록샌 선의 gap이 없어야 할 것을 알고 있습니다.
gap이 커지게 되버리면 과적합이 걸린 것일 것입니다.
오버피팅이 되버리면 실제 데이터 셋에서 잘 동작이 되지 않습니다
이 점을 유의하시면 좋을듯 합니다.
'컴퓨터비전' 카테고리의 다른 글
#IT #먹방 #전자기기 #일상
#개발 #일상