본문 바로가기
AI/자연어처리

[생활속의 IT] 자연어 처리#9 - Keras 모델 생성(2/3)

by 생활속의 IT램프 2020. 4. 2.

[이전 글 보기]

2020/03/22 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#1 - 아나콘다 설치하기

2020/03/22 - [AI/자연어처리] - [생활속의 IT] 자연어 처리 - 참고) Jupyter의 개념

2020/03/23 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#2 - 크롤러 만들기

2020/03/23 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#3 - 직방의 지리정보 Geohash 이해하기

2020/03/24 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#4 - 직방 아파트ID 얻기

2020/03/24 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#5 - 직방 부동산 평가 크롤링하기

2020/03/26 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#6 - 직방 부동산 평가데이터 전처리(1/2)

2020/03/28 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#7 - 직방 부동산 평가데이터 전처리(2/2)

2020/03/31 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#8 - Keras 모델 생성(1/3)

 

 

저번 포스트에서는 Keras에서 딥러닝 모델을 설계하는 방법으로

크게 Sequantial과 Functional 방식이 있다고 했습니다.

 

이번 포스트는 모들을 학습시키기에 앞서 필요한 여러 파라미터들이 있는데

각 파라미터들이 갖는 의미를 살펴보도록 하겠습니다.

 

1. 비용함수

 

2. 오버피팅과 해결방안

 

3. 역전파 알고리즘

 

----------------------------------------------------------------------------------------------------------

1. 비용함수

 

딥러닝이건 머신러닝이건 모델이 실제를 잘 반영하도록, 그래서 오정답이 최소화되도록 훈련하는 것이 목표입니다.

"잘" 훈련되었다는 기준을 어떻게 정할까요?

 

여러 기준이 있지만 그 중 대표적으로 중요한 파라미터로 비용함수가 있습니다.

비용함수는 예측값과 실제값에 오차가 발생했을 경우 그 오차의 크기를 정해주는 함수라고 볼 수 있습니다.

비용함수 값이 최소가 될 때 모델이 가장 잘 훈련되었다고 볼 수 있죠.

 

그런데 비용함수에는 종류가 있습니다.

즉 예측값과 실제값이 다를 때 이 다른것을 어떤 산식에 넣느냐에 따라 값이 조금씩 달라지게 됩니다.

실제로 Keras를 이용하여 모델을 설계하고 Compile할 때 앞서 설명한 비용함수의 종류를 선택하도록 되어 있습니다.

그래서 비용함수에 대해 간략히 설명하고자 합니다. 

 

(1) MSE(Mean Squre Root)

  - 예측값과 실제값의 오차에 대한 제곱합을 의미합니다. 마치 통계에서 분산을 구할때와 비슷하죠.
    (분산은 평균값과 개별 값 차이에 대한 제곱합으로 구합니다)

    MSE는 가장 기본적인 비용함수이면서 제일 많이 사용합니다. 

 

  - 코드는 아래와 같이 compile 단계에서 loss 파라미터로 지정해줍니다.

    (옵티마이저는 뒤에 이어서 설명하겠습니다)

1

2

3

from keras import losses

 

model.compile(loss=losses.mean_squared_error, optimizer='sgd')

 

(2) hinge

  - 서포트 벡터 머신이라고 하는 이진 분류기에서 쓰이는 비용함수입니다.

  - 클래스 분류를 잘 했냐 못했냐에 따라 0 이상의 값이 매겨지는 비용함수입니다.

    제곱이나 Log 등의 함수가 쓰이지 않고 단순히 예측값과 실제값의 차이분을 반영하게 됩니다.

    

 

 

(3) Cross Entropy

  - 페이지 뒤로가기를 누르고 싶게 생겼지만 실제로는 그리 어렵지는 않은 비용함수입니다.

    특징으로는...

 

     Log함수를 이용하며
     모델이 연속적 값을 예측하는 것이 아닌 분류를 예측할 때 쓰이는 비용함수 입니다.

 

   가령 모델에 사진을 입력하여 고양이인지, 개인지, 코끼리 인지 3개로 분류한다고 했을 때

    모델은 각각의 확률을 계산하게 됩니다. (ex: 고양이: 0.7 / 개: 0.2 / 코끼리: 0.1)

    입력된 사진이 만약 개였다면 모델이 크게 잘못 예측한 셈이 됩니다. (확률을 0.2라 했으므로)

    이때 확률에 Log 값을 취하는데 Log(0.2)를 계산하면 손실이 매우 크게 나타나게 되어

    정답을 잘못 예측한 카테고리의 확률이 줄어들도록 유도하는 비용함수입니다. 

 

 이 외에도 여러 비용함수가 있지만 주료 사용하는 것은 MES와 Cross Entropy입니다.

Cross Entropy의 원리는 그렇고 Keras에서는 이진 분류 모델과 다항분류 모델에 대해 

비용함수를 조금 다르게 선택할 수 있습니다.

 

특히 자연어 처리에서 긍정/부정로 이진 분류시 우리가 사용할 비용함수는 binary_cross_entropy 함수입니다.

 

 

2. 오버피팅과 해결방안

 

딥러닝에 대해 조금이라도 들어본 사람은 딥러닝을 위해 많은 학습데이터가 필요하다는 말을 들었을 겁니다.

그런데 학습 데이터가 많다고 해서 성능이 무조건 좋아지는 것은 아닙니다.

 

그 이유가 바로 오버피팅이라는 것 때문입니다.

오버피팅이란 모델이 학습 데이터에만 최적화되어 실제 적용시에 성능이 떨어지는 것을 의미합니다.

오버피팅을 이해하기 전에 Bias와 Variance 라는 것을 알아야 합니다. 

 

Bias와 Variance란?

Bias란 모델이 예측하는 값에 대한 평균과 실제 값과의 차이를 의미합니다.

Bias가 작다는 것은 그만큼 실제값과의 오차가 적고 모델이 정확하다는 것이지요.

그렇다면 Bias만 무조건 높이면 좋을 것 같지만 의외로 꼭 그렇지는 않습니다.

바로 Variance 라는 것 때문입니다.

 

Variance란 예측값끼리 얼마나 분산되어 있냐를 의미합니다.

중요한 것은 Variance는 실제값과는 상관없이

모델이 만들어낸 "예측값끼리" 모여있는 or 분산된 정도를 나타내는 수치라는 겁니다. 

아래 그림을 보겠습니다.

점선은 학습한 모델이 예측하는 선이고 점은 실제 값입니다.

먼저 왼쪽에 있는 그림은 예측값(점선)과 실제값(점)이 잘 맞지 않습니다. 따라서 오차가 크고 Bias가 높다고 합니다.

반면 예측값들 끼리는 잘 흩어지지 않고 직선상에 잘 모여있습니다. 따라서 Variance는 작다고 볼 수 있습니다.

 

가운데 있는 그림은 예측값과 실제값이 적당히 들어맞아 Bias가 적당하다 볼 수 있습니다.

예측값들 또한 크게 흩어지지 곡선상에 존재한다고 볼 수 있습니다. 따라서 Variance도 적당해 보입니다.

 

반면에 오른쪽에 있는 그림은 예측값과 실제값이 100% 일치합니다. 따라서 Bias는 0 입니다.

그러나 예측값끼리 이리저리 많이 흩어져 있어 분산이 높습니다. 이 경우 Variance가 높다고 합니다.

 

머신러닝을 잘 모르는 사람이 봐도 아무리 모델이 100% 정확하더라도

오른쪽 그림처럼 모델의 학습 곡선이 너무 구불구불하면 뭔가.. 불안정해 보입니다.

실제로 모델이 학습을 너무 잘해서 학습 데이터에만 100% 맞추게 되면 실제와는 잘 맞지 않는 현상이 나타납니다.

그래서 Bias와 Variance 모두를 잘 잡아내는게 머신러닝에서 굉장히 중요합니다.

 

문제는 Bias와 Variance는 trade-off 관계라는 것입니다.

Bias와 Variance를 둘 다 100% 좋게 가져가는 것이 불가능합니다.

Bias를 좋게 가져가면(오른쪽 그림처럼) Variance가 낮아지고..

Variance를 좋게 가져가면(왼쪽 그림처럼) Bias가 낮아지고...

 

그래서 결국 중간에 있는 그림처럼 가져갈 수밖에 없습니다.

그럼 원점으로 돌아가서 오버피팅이 무엇이냐? 

 

오버피팅은 Bias가 낮고 Variance가 높은 상태를 의미합니다. 

 

 

오버피팅의 해결방안

 

그럼 오버피팅을 잡으려면 Trade-off 관계를 감안하여 Bias를 희생하고(높이고) Variance를 낮춰야 겠네요.

오버피팅은 학습을 너무 많이 해서 생기므로 기본적으로 학습량을 조절하여 Bias를 희생합니다.

사실 오버피팅을 해결할 수 있는 방안은 여러가지가 있습니다만 

가장 기본적인 해결방안은 학습량을 조절하는 것입니다.

 

어떻게 학습량을 조절할까요?

바로 이전에 설명한 비용함수라는 것을 이용하게 됩니다.

 

대표적으로 많이 쓰이는 비용함수는 MSE (잔차제곱합 Mean Square Root)이며 

예측값과 실제값과의 차이를 제곱한 값을 씁니다. 

이 비용함수를 이용해서 학습량을 어떻게 조절할까요?

 

우리가 모델을 훈련시킬 때는 학습을 위한 학습데이터 셋과 검증을 위한 Validation(검증) 데이터 셋을 함께 쓰게 되는데

학습이 진행됨에 따라 학습 데이터셋이 그리는 비용함수값과

검증 데이터셋이 그리는 비용함수 그림이 다르게 나타납니다.

아래 그림을 보겠습니다.

 

(1) 처음 학습이 진행될때는 Training 데이터셋, 검증 데이터셋에서 모두 비용함수 값이 낮아집니다.

(2) 그러다가 어느 순간부터는 모델이 Training 데이터셋에 적응하면서 오버피팅이 발생하는데

    검증 데이터셋이 잘 안맞기 시작합니다. 

(3) 학습이 더 진행할수록 이 격차는 벌어집니다.

(4) 최종적인 비용함수는 비용함수(Training) 값과 비용함수(검증) 값을 더한 값입니다.

    따라서 최종 비용함수가 최저가 되는 곳에서 학습을 멈춰야 가장 낮은 비용함수값을 얻게 됩니다.

 

그림으로 표현하면 아래와 같이 학습 조기종료를 통해 오버피팅을 방지한다는 의미입니다.

왼쪽: 학습이 지나칠 경우 고 분산이 되어 오버피팅 발생 / 오른쪽: 학습정도를 조절하여 오버피팅 방지

 

우리가 Training 데이터와 검증 데이터를 나누어 학습시키는 이유는 바로

적절한 구간에서 학습을 멈추어 오버피팅을 잡기 위해서입니다.

 

이는 딥러닝 뿐만 아니라 회귀분석, 클러스터링, 의사결정 나무 등 전통적인 머신러닝을 적용할 때에도

적용되는 방식입니다.

 

중요한 것은 어떤 비용함수를 고르던 간에

비용함수가 최저가 되는 곳에서 학습이 멈추어 오버피팅을 막는다는 것입니다. 

다만 비용이라는 것을 어떻게 정의할지가 조금씩 다른 겁니다.

 

 

3. 역전파 알고리즘

 

지금까지 대표적으로 많이 쓰이는 비용함수(=손실함수)와 오버피팅을 알아보았습니다.

그런데 원론적인 질문으로 비용함수는 왜 쓰는 걸까요? 오버피팅을 막기 위해서?

 

조기에 학습을 종료하여 오버피팅을 막는 용도로 이용되기도 하지만

궁극적으로는 비용함수 값이 가장 낮을 때를 모델이 잘 훈련되었다는 기준으로 삼고

가장 잘 만든 모델을 생성하기 위해 비용함수가 제일 낮아지도록 훈련을 하기 위함입니다.

 

이제 마지막으로 볼 차례는 그럼 어떻게 모델을 훈련시키냐 입니다.

즉 훈련을 해서 비용함수가 높게 나왔는데, 어떻게 비용함수를 줄이도록 다시 훈련을 시키냐? 에 대한 물음입니다.

 

딥러닝 모델의 경우 학습 과정이 순전파와 역전파로 나뉘는데

순전파는 답을 푸는 과정, 역전파는 정답을 확인하고 이해하는 과정이라고 볼 수 있습니다.

자세한 내용은 https://wikidocs.net/37406 사이트를 참고해보세요.

 

참고로 딥러닝에서 순전파와 역전파는 아래와 같은 사이클을 갖고 반복하게 됩니다. 

 

이 역전파 과정을 통해 신경망의 가중치를 업데이트하게 되는데 역전파에 쓰이는 알고리즘이 여러 가지가 있습니다.

이 알고리즘을 옵티마이저라고도 하는데 어떤 종류가 있는지 보도록 하겠습니다.

 

(1) 경사 하강법(Gradient Descent) 개념

역전파 알고리즘의 목표는 무엇일까요?

바로 비용함수의 최저점을 찾는 것입니다.

그래서 비용함수 f가 여러 개의 가중치 W1, W2, ... Wn으로 이루어진 함수라고 했을 때

수학적으로는 f(W1, W2, ... Wn) 으로 나타낼 수 있습니다.

따라서 f 값을 가장 작게 만드는 W1 부터 Wn 까지의 가중치 값을 찾아내는 것이 역전파 알고리즘의 목표입니다.

 

여기서 가장 대표적인 알고리즘이 경사하강법이라 알려진 Gradient Descent 입니다. 

Gradient Descent는 편미분을 통해 기울기를 따라 조금씩 조금씩 최저점을 향해 찾아갑니다. 

기울기가 클 수록 이동하는 단위는 커집니다. 

아래 그림처럼 말이죠. 

 

기울기를 따라 계속 이동하다가 기울기가 0이 되는 지점에서는 더이상 이동하지 않아 비용함수가 수렴하게 됩니다.

그 값을 최저점으로 인식하고 학습을 멈추게 됩니다.

 

그런데 이 알고리즘에는 두 가지 문제점이 있습니다.

첫 번째는 조금씩 이동한다는 것이 어느 정도가 적당할지 알 수 없고

두 번째로는 국소 최저점에 머물 수 있다는 것입니다.

 

첫 번째 문제점을 보겠습니다.

Gradient Descent 알고리즘에는 "조금씩" 이라는 값을 사용자가 정해주도록 하고 있습니다.

얼만큼 이동해가며 최저점을 찾을지를 말입니다.

아래 그림에서 왼쪽은 "조금씩"을 상대적으로 작게, 오른쪽은 상대적으로 크게 잡은 것입니다.

 

 

적당히 잘 잡게 된다면 잘 수렴하게 될테지만, 재수없으면 수렴하지 못하고 진동치는 구간이 생길 수 있습니다.

그래서 학습률은 작게 잡으면 좋겠지만 작게잡으면 학습시간이 오래걸린다는 단점이 있습니다.

 

원래 인공지능 분야의 어려운 점 중 하나가 가장 좋은 해가 무엇인지 알 수 있는 방법이 없다는 것입니다.

비단 이 학습률을 조정하는 것 뿐 아니라 딥러닝의 layer를 몇 층으로 할지, 노드 개수는 몇 개로 할지 등등

실험적으로만 확인할 수 있을 뿐 Best해를 알 수 없다는 것이 인공지능의 어려운 점 중 하나입니다.

어쨌든 그래서 이동하는 크기도 실험적으로 확인해봐야 합니다.

 

두 번째 문제점은 진짜 최저점을 찾지 못하고 국소 최저점에 머물 수 있다는 것입니다.

비용함수 그래프는 위 사진처럼 2차함수가 아닙니다. 사실 그래프가 어떻게 생겼는지는 알 수 없습니다.

그래서 다만 기울기를 따라가며 수렴하는 값을 찾는건데

그 위치가 아래 그림처럼 진짜 최저점이 아닐 수 있다는 것입니다.

 

이렇게 국소 최저점에 멈춰서면 글로벌 최저점을 찾지 못하는 것이죠.

이를 해결하기 위해 다른 알고리즘들이 등장하는데 뒤에 이어서 설명하겠습니다. 

 

(2) 경사 하강법의 유형

역전파 알고리즘은 순전파를 통해 문제를 푼 후 역전파로 정답을 확인하는 과정으로 비유했었는데 

경사 하강법같은 경우 정답을 얼마나 자주 확인하냐에 따라 3가지 알고리즘으로 구분이 됩니다.

 

 

○ 확률적 경사하강법(Stochastic Gradient Descent, SGD)

    - 문제를 풀고(순전파) 해답을 확인(역전파) 할 때 데이터 세트 중 임의의 1개를 선택하여 진행합니다.

      장점은 당연히 빠르다는 것입니다. 그리고 국소 최저점에 빠질 위험이 낮습니다.

      왜냐하면 한 지점에서 기울기를 따라 쭉 가는 것이 아니라 이 지점, 저지점 랜덤하게 자리를 골라

      학습하기 때문에 특정 지점에 국한될 가능성은 적습니다.

    

    - Keras에서는 SGD를 파라미터로 제공하고 있습니다. 

 

○ 미니 배치 경사하강법

   - SGD의 단점은 1문제 풀고 정답 확인하는 행위를 반복한다는 것인데 국소 최저점에 빠질 가능성은 낮지만

    이리저리 튀면서 학습하기에 노이즈를 학습하게 될 가능성이 있습니다.

    학습 모델에서 예상되는 예측값이 분산되어 있다는 것은... 이전 포스트에서 설명했습니다.

    

    그렇습니다. 즉 오버피팅될 가능성이 있는 것이죠.

    미니배치는 그 단점을 완화하여 임의의 데이터 몇 개를 가지고 문제를 푼 후 정답을 확인합니다.

    그래서 널리 활용되는 기법이기도 합니다만 아쉽게도 Keras에서는 제공하지 않습니다.

 

○ 배치 경사하강법

  - 배치 경사하강법은 문제집를 다 풀고 정답을 확인하는 겁니다.

    딥러닝 학습은 순전파와 역전파를 반복한다고 했으므로 정답 확인하고 다시 문제집 전체를 다 풀고

    또 정답 확인하고...

    이것을 정답 확인이 완벽해질 때까지 (비용함수가 수렴할 때까지) 반복하는 겁니다.

    전체 데이트세트를 가지고 말이죠.

    당연히 시간이 오래걸립니다. 그래서 효율이 낮은 것이 단점입니다. 

    그리고 Keras에서는 이 알고리즘을 제공하지 않습니다.

 

 

(3) 경사하강법의 업그레이드 알고리즘들

 지금까지 배치, 미니배치, 확률적 경사하강법을 소개했습니다.

 그리고 Keras에서는 확률적 경사하강법인 SGD를 파라미터로 제공한다고 말씀드렸습니다.

 

그런데 이 3가지 말고도 다른 알고리즘들이 존재하기에 간략히 설명하겠습니다.

실제로 많이 쓰이기에 딥러닝에 관심 있다면 알아두시면 좋겠습니다.

 

 

모멘텀 - 속도유지

 

  - 모멘텀은 물리학에서는 운동량을 의미하는데 정확히는 질량 * 속도를 의미하는 물리량입니다. 

    역전파에서 모멘텀은 속도를 의미한다고 보면 되는데 

    기울기를 따라 내려오면서 이동하는 폭을 크게한다고 보면 됩니다. 실제로 파라미터에 변수 v 가 추가되어 있습니다. 

    경사하강법 자체도 기울기에 따라 이동하는 폭이 커지긴 하는데

    기울기가 갑자기 작아지면 이동하는 폭도 그만큼 작아집니다. 반면에 모멘텀은 가속도를 반영하기에 

    기울기가 갑자기 작아지더라도 속도를 유지하여 이동하는 폭도 커지게 되죠.

 

    이것은 중요한 장점 하나를 지닙니다. 바로 국소 최소점을 극복할 수 있다는 것입니다. 

위 그림처럼 오르막길을 갑자기 만나더라도 관성의 힘으로 넘어갈 수 있다는 것입니다.

그런데 아쉽게도 Keras에서는 모멘텀 알고리즘을 제공하지 않습니다.

 

 

○ Adagrad - 나이가 듦에 따라 폭을 천천히

 

  - 일반적인 경사하강법은 너무 느리기에 학습을 좀 더 빨리 진행하기 위한 방법으로 탄생했습니다.

    비용함수 F는 여러 개의 가중치로 이루어진 함수인데

    Adagrad는 만약 특정 Wi 가중치가 많이 움직였다면 F에 Wi가 큰 영향을 줄 가능성이 크며

    최저점에 많이 왔을 것이라고 가정합니다. 

    따라서 Wi는 폭을 줄여 천천히 움직이게 합니다. 반면에 아직까지 많이 움직이지 않은 파라미터 Wj는

    크게크게 움직이도록 폭을 조절해 주는 방식입니다.

  - Keras에서 파라미터로 제공해주고 있는 알고리즘입니다. 

 

 

○ RMSprop - 나이가 들어도 걸어야지

 

  - RMSprop은 Adagrad의 단점을 개선하기 위해 등장했습니다. Adagrad의 단점은 많이 움직였다고 판단한
    파라미터의 보폭을 줄였는데 최저점이 아님에도 보폭이 급격히 줄어들어 움직이지 않는 경우가 발생한다는 겁니다. 

    RMSProp은 인공지능의 대가 제프리 힌튼 교수가 만든 방법입니다.

    (인공지능을 침체기에서 구한 영웅이 힌튼 교수입니다)

 

   RMSProp은 많이 움직인 파라미터의 보폭이 급격히 줄어들지 않게끔 해주어 최저점을 찾도록 해줍니다.

 - Keras에서 파라미터로 제공해주고 있는 알고리즘입니다. 

 

 

○ Adam - 속도 + 나이반영

 

  - Adam은 속도를 가진 모멘텀과 나이를 반영한 RMSProp을 합친 알고리즘입니다.

    즉 속도도 가지면서 많이 이동한 파라미터의 폭은 조금씩 줄어들도록 한 것입니다.

  - Keras에서는 Adam도 파라미터로 제공해주고 있습니다.

 

 

지금까지 설명한 알고리즘 외에도 Keras에서는 몇 가지를 더 제공하고 있는데 대부분 여기서 크게 벗어나지 않습니다.

참고로 많은 블로그에서 참조하고 있는 하용호님의 알고리즘 발달 계보를 첨부합니다.

설명을 읽고 보시면 어느정도 이해가 가시리라 믿습니다.

 

빨간색 표시는 Keras에서 제공하는 알고리즘이다. 이 외에도 adamax라는 알고리즘도 제공하고 있다.

 

댓글