2020. 4. 30. 21:00ㆍAI/모두를 위한 딥러닝
이 포스트는 모두를 위한 딥러닝 - Tensor Flow를 정리한 내용을 담았습니다.
누구나 이해할 수 있는 수준으로 설명하고자 하였으며 LAB의 코드는 TF2.0에 맞추어 재작성되었습니다.
· learning rate (학습 속도)
이전의 포스트들에서 우리는 다양한 모델에서 Gradient descent를 적용할 때 learning rate(학습 속도)를 설정하였고 이 과정을 텐서플로우에서 직접 구현도 해보았습니다. 이번 포스트에서는 먼저 learning rate가 너무 작거나 클 때의 문제를 다뤄보고, 적절한 learning rate를 설정하는 방법을 알아보겠습니다. 아래 그래프 1.1은 일반적인 비용 함수(cost function)의 한 예시입니다.
먼저 learning rate가 너무 작은 경우입니다. learning rate가 너무 작으면 아래 그래프 1.2에서처럼 최솟값에 도달하는 데에 너무 많은 학습이 필요합니다. 따라서 최솟값에 도달하기까지 시간이 오래 걸리고, 최악의 경우에는 정한 Epoch 내에 최솟값에 도달하지 못해 지역적 최솟값(local minimum)에서 멈출 수도 있습니다. 이렇게 되면 우리는 이 지역적 최솟값을 전역적 최솟값(Global minimum)으로 착각하여 기대했던 결과와는 전혀 다른 결과를 얻을 것입니다. 결국 learning rate가 너무 작을 때는 단순히 시간이 오래 걸리는 것에 그치지 않고, 결과에 영향을 주어 잘못된 결과를 얻을 수도 있기 때문에 값을 조정할 필요가 있습니다.
이번에는 learning rate가 너무 큰 경우입니다. learning rate가 크다는 것은 한 번의 Epoch에 값이 크게 변한다는 의미입니다. 아래의 그래프 1.3은 흔하지는 않지만 learning rate가 커서 cost값이 반대편으로 이동하다가, 어느 순간 cost값이 좌우로 반복하는 모습입니다. 반면 아래의 그래프 1.4는 learning rate가 너무 커서 cost가 줄어들기는커녕 학습할수록 늘어나는 모습을 보입니다. 결국 아래의 두 그래프는 cost가 최솟값에 도달하지 못해 잘못된 결과를 얻을 수 있다는 것을 보여줍니다.
그렇다면 어떻게 해야 적절한 learning rate를 구할 수 있을까요? 모든 데이터와 환경에 맞는 learning rate를 찾는 정답은 없습니다. 따라서 우리는 적절한 초기값을 선정하고 cost의 변화 추이를 살펴보며 조금씩 조절하는 것이 필요합니다. 보통 많이들 learning rate의 초기값을 0.01로 정하여 실행 후 cost값이 변화하는 모습을 지켜보며 값을 조금씩 조절해나갑니다.
· Data preprocessing (데이터 전처리) / Feature scailing
우리는 바로 위에서 W(weight)가 하나인 경우의 cost function 그래프를 살펴보았습니다. 이번에는 W가 두 개인 경우의 cost function을 보겠습니다. W가 두 개면 x = W1, y = W2, z = cost(W1, W2), 즉 3차원으로 표현해야 하지만 설명의 편의상 W1, W2을 x, y축으로 갖는 2차원 상에 표현하겠습니다. 앞으로 우리는 2차원 상의 그래프를 등고선 그래프라고 부르겠습니다. 3차원 그래프를 2차원 상에 표현하는 과정은 아래의 그림 1.1을 참고해주시길 바랍니다.
그래프 2.1에서 알 수 있듯 cost를 최소로 하는 값은 등고선 그래프의 중앙입니다. 따라서 cost를 최소화한다는 것은 그래프의 어느 한 점에서 시작하여 그래프 중앙으로 이동하는 것을 의미합니다. 아래 그림 1.2는 이 과정을 그림으로 표현하고 있습니다.
그렇다면 아래의 데이터(x1, x2, y)를 토대로 등고선 그래프를 그리면 어떤 모양이 나올까요? x1, x2를 각각 w1, w2와 곱해 합한 값을 최소화하기 위해 범위가 좁은 x1과 곱하는 w1은 조금 더 큰 값이 될 것이며 반대로 범위가 넓은 x2와 곱하는 w2는 조금 더 작은 값이 될 것입니다. 따라서 그래프를 그려보면 아래와 같이 양옆으로 길쭉한(한쪽으로 치우친) 모양으로 나타납니다.
x1 | x2 | y |
1 | 9000 | A |
2 | -5000 | A |
4 | -2000 | B |
6 | 8000 | fB |
9 | 9000 | C |
그림 1.3의 경우 어느 한 점에서 다른 점으로 이동할 때, 수평으로 이동할 때와 수직으로 이동할 때 엄청난 불균형이 발생하여 Gradient descent 알고리즘을 적용하기 어려운 문제가 있습니다. 실제로 파란색 점은 조금만 밖으로 이동해도 큰 변화가 일어나 값이 밖으로 튀어나가 버립니다. 따라서 우리는 등고선 그래프의 이상적인 형태는 완벽하게 둥근 원의 모양이며, 이는 데이터들의 범위가 일정한 경우에 나타날 것입니다. 하지만 당연히 데이터들의 범위가 항상 일정한 것을 기대할 수는 없습니다. 따라서 데이터들을 적절히 조절하여 이용하는 것이 필요하며, 우리는 이러한 작업을 Data preprocessing(데이터 전처리)이라고 합니다.
위의 그래프 3.1은 원래의 데이터(original data)에서 데이터의 중심을 0에 맞춰 이동하는 방법(zero-centered data, 모든 데이터 각각에 대해 평균값만큼 차감하는 방식으로 구현됩니다)과 데이터 범위를 어떤 범위에 항상 들어가도록 조절하는 방법(normalization, 자동으로 zero-centered data가 됩니다)으로 Data processing의 두 예시를 보여줍니다. 아직 이해가 되지 않으신다면, 아래의 링크 사이트에서 자세한 설명을 확인하시길 바랍니다.
아래 코드는 파이썬의 numpy()를 이용하여 zero-centerd data와 normalization을 구현하는 코드입니다.
# data matrix : X
X -= np.mean(X, axis = 0) # zero-centered data, using Mean Subtraction
X /= np.std(X, axis = 0) # normalization
이제 데이터 전처리 과정의 하나인 Feature scailing에 대해 알아보겠습니다. Features scailing에는 Normalization(정규화)과 Standardization(표준화)의 2가지 방법이 있는데, 본 강의에서는 후자인 Standardization을 소개하고 있지만 두 방법 모두 중요하므로 Andrew ng 교수님의 Machine learning 강의에서 Normalization에 대한 설명을 빌려와 두 방법 모두를 설명하겠습니다. 먼저 Standardization(표준화)은 데이터들의 평균과 표준편차를 이용해 "(데이터 - 평균) / 표준편차"의 식으로 해당 분포에서의 데이터가 평균으로부터의 위치를 표준편차 단위로 옮겨서 표현하는 방법입니다. Standardization을 하면 각 데이터들은 평균을 기준으로 얼마나 떨어져 있는지를 나타내는 값으로 변환됩니다. 아래는 Standardization을 식과 파이썬 코드로 표현하였습니다. 물론 사이킷런 등의 다양한 파이썬 라이브러리를 활용하여 standardizaiton을 더욱 간결하고 효율적으로 표현할 수 있으므로, 구글링으로 다양한 코드를 만나보시길 바랍니다.
# Standardization
standardized_data = (data - np.mean(data, axis = 0)) / np.std(data, axis = 0)
이번에는 Normalization(정규화)에 대해 알아보겠습니다. Normalization은 "(데이터 - 최솟값) / (최댓값 - 최솟값)"의 식으로 모든 데이터를 0 ~ 1 사이의 값으로 나타내는 척도법으로, 데이터들이 0 ~ 1 사이의 값을 가지기 때문에 [0-1] 변환이라고도 불립니다. Normalization의 식과 파이썬 코드는 아래와 같이 표현합니다. Standardization때와 같이 다른 라이브러리를 사용하여 코드를 훨씬 간결하게 표현할 수 있습니다.
# Normalization
normalized_data = (data - np.min(data, axis = 0)) / (np.max(data, axis = 0) - np.min(data, axis = 0))
· overfitting (과적합)
이제 기계학습의 가장 큰 문제인 overfitting에 대해 알아보겠습니다. overfitting이란 한 마디로 "Training data set에 너무 딱 들어맞는 모델, 학습 데이터를 과하게 잘 학습하는 것"을 말합니다. 학습 데이터에 들어맞는 모델이 왜 문제가 될까요? 먼저 아래 그림을 보겠습니다.
그래프 4.1(좌)은 학습 데이터(+, -)를 구분 짓는 적절한 모델을 가지고 있습니다. 물론 학습 데이터를 완벽히 구분짓지는 않지만, 새로운 데이터가 들어왔을 때 데이터가 (+)인지 (-)인지를 구분하기에 적절한 가설을 가지고 있기 때문에 일반적이고 좋은 모델이라고 할 수 있습니다. 반면 그래프 4.2(우)는 학습 데이터를 완벽히 구분하기 위해 모델이 굽어진 모양을 볼 수 있습니다. 이러한 모델은 학습 데이터만 놓고 보았을 때는 최적의 모델이라고 할 수 있지만, 새로운 데이터들이 들어왔을 때는 cost값이 커질 가능성이 왼쪽에 비해 높습니다. 이렇듯 학습 데이터에만 맞춰 무리하게 모델을 설정한 것은 실제로 사용하기에 어렵기 때문에 특수하고 좋지 않은 모델이라고 할 수 있습니다. 따라서 이와 같은 경우를 우리는 overfitting(과적합)이라고 합니다.
그렇다면 어떻게하면 overfiitting을 줄일 수 있는지 알아보겠습니다. 먼저 가장 좋은 방법은 Training data set(학습 데이터)을 늘리는 것입니다. 학습 데이터가 많으면 많을수록 몇 개의 아웃라이어(outlier, 통계 용어로 검출된 값 중 다른 값들에 비해 지나치게 높거나 낮은 값을 의미하며 그래프 4.1의 데이터 군집 내 혼자 다른 데이터를 말합니다)들에도 다소 둔하게 반응하기 때문에, 평균적이고 일반화된 모델을 만들 수 있기 때문입니다. 반대로 학습 데이터가 적으면 그 몇 개의 아웃라이어들에 민감하게 반응하여(cost에 큰 영향을 끼친다는 뜻입니다), 모델은 cost를 낮게 하기 위해 무리(overfitting)합니다. 그래프 4.2에서 (-) 데이터들 사이의 (+) 데이터와 (+) 데이터들 사이의 (-) 데이터, 이 두 개의 아웃라이어에 민감하게 반응하여 모델을 만드는 것이 overfitting이라고 볼 수 있습니다. 현실의 경우를 예로 들면, 강아지 사진 2개 만을 학습시키고 새로운 사진이 강아지인지 아닌지를 판단하는 것보다, 수많은 강아지 사진을 학습시키고 새로운 사진을 보여주는 것이 훨씬 일반화된 모델로 잘 판단할 것으로 예측할 수 있습니다. 두 번째 방법으로는 Features를 줄이는 것입니다. 중복된 feature를 찾아내 합치거나 핵심 feature만을 선택하는 등으로 feature를 줄여나가면 overfitting을 피할 수 있지만, 과정에서 결과에 중요한 영향을 미치는 feature를 삭제해 잘못된 모델을 만들어낼 수도 있다는 점을 유의해야 합니다. 마지막으로는 일반적으로 사용되는 방법인 Regularization(정규화)입니다. 그래프 4.2를 보면 cost를 최소화하기 위해 모델이 많이 구부려진 것을 볼 수 있는데, Regularization은 이렇게 구부러진 모델을 펴서 일반적인 모델을 만들자는 의미입니다. 이는 기존의 cost fuction에 적절한 값을 곱해 cost를 적절히 늘리는 방법을 이용합니다. 그럼 Regularization을 식으로 표현하여 알아보겠습니다.
식 3.1에서와 같이 Regularization은 cost function에 (lambda)*(∑w^2)값을 더하여 구현합니다. 그런데 (∑w^2) 값은 정해져 있어 사실상 lamda(regularization)에 따라 모델이 바뀌기 때문에 lambda값의 크기가 regularization을 얼마나 많이 적용할 것인지를 판단한다고 해석할 수 있습니다. 아래 그림은 lambda값에 따라 실제로 모델이 얼마나 변하는지를 보여줍니다. 텐서플로우에서는 아래와 같이 아주 간단한 코드로 구현할 수 있습니다.
l2reg = 0.001 * tf.reduce_sum(tf.square(W)) # Regularization, lambda = 0.001
이번 포스트에서는 learning rate가 너무 크거나 작은 경우의 문제점과 그에 따른 조절방법, Data preprocessing(데이터 전처리)과 Feature scailing 방법, 그리고 모델이 학습 데이터에만 너무 딱 맞는 ovefitting에 대해 알아보았습니다. 다음 포스트에서는 만들어진 모델이 얼마나 잘 동작하는지를 확인하는 방법에 대해 알아보겠습니다.
'AI > 모두를 위한 딥러닝' 카테고리의 다른 글
08. 딥러닝의 기본개념, 역사 (0) | 2020.05.08 |
---|---|
07-2. Model evaluation: Training and test data sets (0) | 2020.05.04 |
06-3. Fancy Softmax Classification LAB(2) (0) | 2020.04.25 |
[공지] LAB 포스트 관련 공지사항 (0) | 2020.04.22 |
06-2. Softmax Classification LAB(1) (0) | 2020.04.21 |