이 게시글은 책 '구글 BERT의 정석'의 셀프어텐션 설명을 요약 및 정리했습니다.

http://www.yes24.com/Product/Goods/104491152

 

구글 BERT의 정석 - YES24

인간보다 언어를 더 잘 이해하고 구현하는 고성능 AI 언어 모델 BERT이 책은 자연어 응용 분야에서 상당한 성능 향상을 이뤄 주목받고 있는 BERT 모델을 기초부터 다양한 변형 모델, 응용 사례까지

www.yes24.com

 

오늘은 셀프 어텐션에 대하여 알아볼 것입니다.

셀프 어텐션은 트랜스포머를 구성하는 핵심 요소입니다.

셀프 어텐션 -> 멀티 헤드 어텐션 -> 트랜스포머 순서로 향후 게시글을 올릴 예정입니다.

 

셀프 어텐션이 무엇인지 예를 통해서 알아보고, 사용되는 주요 행렬을 알아본 후, 작동 원리를 설명하면서 마무리하겠습니다.

 

목차

1. 셀프 어텐션 감잡기

2. 셀프 어텐션에서 사용되는 주요 행렬

3. 셀프 어텐션의 작동 원리

 

1. 셀프 어텐션 감잡기

셀프 어텐션은 트랜스포머를 구성하는 핵심 요소로, 특수한 형태의 어텐션입니다.

 

아래와 같은 문장이 있다고 가정합시다.

 

A cat ate the fish because it was hungry.

 

이 문장에서 우리는 'it'은 'cat'을 가리킴을 알 수 있습니다. 위 문장에 셀프 어텐션을 적용한다면,  모델은 'it'이 'fish'보다 'cat'과 연관성이 큰 것을 알 수 있습니다. 왜냐하면 이 문장이 모델에 입력되었을 때, 모델이 'it'이라는 단어의 의미를 이해하기 위해 문장 안에 있는 모든 단어와 'it'이라는 단어의 관계를 계산하는 작업을 수행하기 때문입니다.

 

그림으로 표현하면 아래와 같습니다.

그림은 'it'이라는 단어의 표현을 계산하기 위해 'it'을 문장의 모든 단어와 연결하는 작업을 보여줍니다. 이와 같은 연결 작업으로 모델은 'it'이 'fish'보다 'cat'과 연관성이 큰 것을 학습합니다. 

 

이렇게 작동하려면 무엇이 필요할까요? 셀프 어텐션에서 사용되는 주요 행렬에 대하여 알아봅시다.

 

2. 셀프 어텐션에서 사용되는 주요 행렬

문장을 셀프 어텐션에서 사용하려면 임베딩하는 작업이 필요합니다. 셀프 어텐션은 임베딩 된 벡터로부터 쿼리(Q) 행렬, 키(K) 행렬, 밸류(V) 행렬을 생성하고, 이 세 가지 행렬을 이용해서 작동합니다.

 

세 가지 행렬이 어떻게 만들어지는지 아래의 문장을 통해 설명드리겠습니다.

 

I am good

 

이 문장을 임베딩한 결과는 다음과 같습니다.

이 행렬을 X라고 하겠습니다. 행렬 X에서 첫 번째 행은 'I'의 임베딩, 두 번째  행은 'am'의 임베딩, 세 번째 행은 'good'의 임베딩을 의미합니다. 이때 X의 차원은 [문장 길이 x 임베딩 차원]의 형태입니다.

 

이렇게 임베딩 된 행렬로부터 세 개의 가중치 행렬을 행렬 X에 곱하면 쿼리 행렬, 키 행렬, 밸류 행렬이 계산됩니다. 여기서 세 개의 가중치 행렬은 처음에 임의의 값을 가지며, 학습 과정에서 최적의 값을 얻게 됩니다.

 

그림으로 표현하면 다음과 같습니다.

3. 셀프 어텐션의 작동원리

이제 쿼리, 키 밸류 행렬을 셀프 어텐션에 어떻게 사용하는지 보겠습니다.

셀프 어텐션은 총 4단계로 이루어져 있습니다.

 

1단계.

쿼리(Q) 행렬과 키(K) 행렬의 내적 연산을 수행합니다.

이를 해석하자면, Q와 K를 내적한 행렬(QK행렬)의 첫 번째 행은 쿼리 벡터1과 키 벡터 1, 2, 3의 내적을 계산한다는 것을 알 수 있습니다. 두 벡터 사이의 내적을 계산하면 두 벡터가 얼마나 유사한지를 알 수 있습니다. 즉, I의 쿼리 벡터와 I의 키 벡터, am의 키 벡터, good의 키 벡터 사이의 유사도를 계산한 것입니다.

 

QK행렬의 첫 번째 행은 110, 90, 80 입니다. 이를 통해 단어 I는 단어 am과 good보다 자신(I)과 연관성이 더 높은 것을 알 수 있습니다. 내적값이 110으로 첫번째 행에서 가장 높기 때문입니다.

 

2단계.

QK행렬의 키 벡터 차원의 제곱근값으로 나눕니다. 이렇게 하면, 안정적인 경사값을 얻을 수 있습니다.

키 벡터의 차원을 64라고 가정하면 이것의 제곱근인 8로 QK행렬을 나눕니다. 결과는 아래와 같습니다.

3단계.

이전 단계에서 계산한 유사도 값은 비정규화된 형태이기 때문에 소프트맥스 함수를 적용해 정규화 작업을 진행합니다.

4단계.

앞에서 구한 행렬들을 이용하여 어텐션 행렬(Z)를 계산합니다. 어텐션 행렬은 문장의 각 단어의 벡터값을 갖습니다. 3단계에서 계산한 행렬에 밸류 행렬(V)를 곱하면 어텐션 행렬(Z)를 구할 수 있습니다.

Z를 구하면 단어 good의 셀프 어텐션 z3도 구할 수 있습니다.

z3는 밸류 벡터 v(I)의 0.21 비중, 벨류 벡터 v(am)의 0.03 비중, 벨류 벡터 v(good)의 0.76 비중의 합이라는 것을 알 수 있습니다. 이렇게 보면, 단어 good의 셀프 벡터값은 밸류 벡터 v(am)보다 v(I)가 많이 반영된 결과로 볼 수 있습니다. 이는 모델에서 good이 am이 아닌 I와 관련이 크다는 것을 알 수 있습니다. 셀프 어텐션 방법을 적용하면 이렇게 단어가 문장 내에 있는 다른 단어와 얼마나 연관성이 있는지를 알 수 있습니다.

 

정리하자면 다음과 같습니다.

 

1단계. 쿼리 행렬과 키 행렬 간의 내적을 계산하고 유사도를 구한다.

2단계. 1단계에서 구한 QK행렬을 키 행렬 차원의 제곱근으로 나눈다.

3단계. 2단계에서 구한 행렬에 소프트맥스 함수를 적용해 정규화 작업을 진행한다.

4단계. 마지막으로 밸류 행렬을 곱해 어텐션 행렬 Z를 산출한다.

오늘은 LSTM에 대해서 알아봅시다. '밑바닥부터 시작하는 딥러닝2' 책을 공부한 내용으로 설명했습니다.

 

http://www.yes24.com/Product/Goods/72173703

 

밑바닥부터 시작하는 딥러닝 2 - YES24

직접 구현하면서 배우는 본격 딥러닝 입문서 이번에는 순환 신경망과 자연어 처리다! 이 책은 『밑바닥부터 시작하는 딥러닝』에서 다루지 못했던 순환 신경망(RNN)을 자연어 처리와 시계열 데

www.yes24.com

 

 

목차는 아래와 같습니다.

 

1. LSTM 이란?

2. LSTM 대략적인 설명

3. LSTM 구현

 


1. LSTM 이란?

 

LSTM은 RNN의 기울기 소실 문제를 방지하는 신경망입니다. RNN의 Hidden Layer에 기억 셀, Input/Output/Forget Gate를 추가한 형태입니다. 

 

LSTM과 RNN의 차이는 [그림 1]로 설명하겠습니다.

 

RNN의 Hidden Layer에는 Hidden State인 Ht-1과 Input인 Xt, 가중치인 Wt로 구성되어 있습니다. 이들은 Hidden Layer 안에서 선형결합과 하이퍼볼릭 탄젠트 함수를 거친 후 Ht를 내보냅니다.

 

하지만 LSTM의 Hidden Layer에는 기억 셀인 Ct-1과 Input/Output/Forget Gate가 있습니다. 기억 셀은 데이터를 LSTM 계층 내에서만 주고받습니다. 즉, LSTM 계층 내에서만 이동하고 다른 계층으로 출력하지는 않습니다. 또한 기억 셀 Ct에는 시각 t에서의 LSTM의 기억이 저장돼 있습니다. 이것은 과거로부터 시각 t까지에 필요한 모든 정보가 저장돼 있다고 가정합니다. 이 기억을 바탕으로 다음 시각의 LSTM에 Hidden State Ht를 출력합니다. 

 

[그림 1] RNN과 LSTM의 차이

 


 

2. LSTM 대략적인 설명

 

지금부터 LSTM의 게이트에서 일어나는 과정을 대략적으로 설명해보겠습니다.

[그림 2] LSTM 구조

 

1) o : Output Gate

 

Output Gate는 다음 Hidden State Ht의 출력을 담당하는 게이트입니다. Output Gate에서 Hidden State Ht-1과 Input Xt를 연산한 것을 tanh(Ct)에 곱합니다. 이를 통해 tanh(Ct)에서 얼만큼의 양을 Ht로 출력시킬지 결정합니다.

 

계산식은 [식 1]과 같습니다. 가중치와 Xt, Ht-1간의 선형결합에 시그모이드 함수를 씌운 형태입니다. [식 2]는 Output Gate 결과에 tanh(Ct)를 곱해 Hidden State Ht로 생성하는 과정입니다.

 

[식 1] Output Gate
[식 2] Hidden State Ht 구하는 방식

 

2) f : Forget Gate

 

Forget Gate는 이전 단계에서의 기억 셀 Ct-1에서 불필요한 기억을 잊게 해주는 게이트입니다. Forget Gate에서 Ht-1과 Xt를 연산한 것을 Ct-1에 곱합니다. 이를 통해 Ct-1에서 얼만큼의 양을 지워서 Ct로 연산할지 결정합니다.

 

계산식은 [식 3]와 같습니다. [식 4]는 Forget Gate 결과에 Ct-1를 곱해 기억 셀 Ct로 생성하는 과정입니다.

 

[식 3] Forget Gate
[식 5] 기억 셀 Ct를 구하는 방식

 

3) g : 기억 셀에 추가하는 새로운 기억

 

새로 기억해야 할 정보를 기억셀에 추가하기 위해 [그림 2]에서와 같이 tanh 노드를 추가합니다. [그림 2]에서 tanh노드와 이전 단계의 기억 셀 Ct-1을 더하면서 기억 셀에 새로운 '정보'가 추가됩니다.

 

계산식은 [식 5]와 같습니다. 이 g가 Ct-1에 더해짐으로써 새로운 기억이 생깁니다.

 

[식 5] 기억 셀에 추가하는 새로운 기억 g 계산

 

4) i  : Input Gate

 

Input Gate는 g의 각 원소가 새로 추가되는 기억으로써의 가치가 얼마나 큰지를 판단합니다. 새 기억 g를 모두 수용하지 않고, 적절히 부분적으로 선택하는 것이 이 게이트의 목표입니다.

 

계산식은 [식 6]과 같습니다.

 

[식 6] Input Gate 

 

앞에서 구한 i, g, f를 이용해서 이전 단계에서의 기억 셀 Ct-1을 Ct로 변환하는 과정은 [식 7]과 같습니다.

 

[식 7] 기억 셀 Ct를 구하는 방식

 

[그림 2] LSTM 구조

 

 

정리하자면, [그림 2]에서 LSTM은 RNN과 다르게 필요한 정보(기억)를 선별해서 저장하는 과정을 거칩니다.

, 이전 단계에서의 기억셀 Ct-1에 f를 적용해 일부 기억을 잊고, g와 i의 곱을 더해 새로운 기억을 추가합니다. 이후 tanh()을 씌우고 o를 적용해 어느 정도의 데이터를 Hidden State Ht로 출력할지 결정합니다.  

 


 

3. LSTM 구현

 

[식 8]은 LSTM에서 수행하는 계산입니다. [식 8]의 위에서 네 개의 수식은 XWx+hWh+b 형태의 아핀 변환입니다. 이것을 하나의 식으로 정리해 계산할 수 있습니다. 그 과정은 [그림 3]과 같습니다. 

 

[식 8] LSTM 수식

 

[그림 3] 각 식의 가중치들을 모아 4개의 식을 단 한번의 아핀 변환으로 계산

 

[그림 3]은 각 식의 가중치들을 모아 4개의 식을 단 한번의 아핀 변환으로 계산해 A 행렬을 구합니다. 이후 Slice를 이용해 활성화 함수를 적용해서 f, g, i, o 를 생성합니다. 이와 같이 계산하면 원래 개별적으로 총 4번을 수행하던 아핀 변환을 1번의 계산으로 끝마칠 수 있습니다. 이것을 반영해 LSTM을 표현하면 [그림 4]와 같습니다.

 

[그림 4] 4개분의 가중치를 모아 아핀 변환을 수행하는 LSTM의 계산 그래프

 

[그림 4]에서와 같이 처음 4개의 아핀 변환을 한 번에 수행합니다. 그리고 Slice 노드를 통해 4개의 결과를 꺼냅니다. Slice는 아핀 변환의 결과를 균등하게 네 조각으로 나눠서 꺼내주는 노드입니다. Slice 다음에는 활성화 함수를 거쳐 계산을 수행해 기억 셀 Ct, Hidden State Ht를 구합니다.  

 

4. LSTM 구현[파이썬]

 

코드는 '밑바닥부터 시작하는 딥러닝2'의 'Common/time_layers.py' 에 있습니다.

https://github.com/oreilly-japan/deep-learning-from-scratch-2/blob/master/common/time_layers.py

 

*그림은 밑바닥부터 시작하는 딥러닝2를 참고했습니다*

http://www.yes24.com/Product/Goods/72173703

 

밑바닥부터 시작하는 딥러닝 2 - YES24

직접 구현하면서 배우는 본격 딥러닝 입문서 이번에는 순환 신경망과 자연어 처리다! 이 책은 『밑바닥부터 시작하는 딥러닝』에서 다루지 못했던 순환 신경망(RNN)을 자연어 처리와 시계열 데

www.yes24.com

[목차]

1. 정의

2. 알고리즘

   2.1 순전파

   2.2 역전파

3. 기울기 소실 문제

 

1. 정의

 

RNN(Recurrent Neural Network)로, 은닉층에서 나온 결과값이 다시 은닉층으로 돌아가 새로운 입력값과 연산을 수행하는 순환구조입니다. 완전연결층(Fully Connected Layer), CNN(Convolutional Neural Network)은 은닉층에서 나온 결과값이 출력층 방향으로 이동하지만, RNN은 은닉층으로 되돌아가 순환한다는 점에서 큰 차이가 있습니다. 

 

RNN은 [그림 1]과 같은 순환구조를 형성합니다.

 

[그림 1] RNN의 순환구조

 

[그림 1]은 RNN 순환구조를 펼친 형태로 입력값{x0, x1,..., xt}를 순차적으로 입력했을 때 각 입력에 대응해 {h0,...,ht}가 출력됩니다. 이때 RNN계층은 모두 같은 계층이고 출력{h0,..,hk,.,ht}를 각각 k 시점에서의 은닉 상태라고 합니다. 

 

이러한 RNN의 구조는 시계열 데이터, 텍스트 데이터에 적합합니다.

 

가령 'You say goodbye and I say hello'에서 각 단어의 다음에 나올 단어를 예측하고자 할때, 문장에서 임베딩 된 단어를 순차적으로 RNN 에 입력합니다.

 

이후 각 입력에 대응하는 은닉상태로 다음에 나올 단어를 예측합니다. 여기서 은닉상태는 해당 시점까지의 단어 정보를 나타냅니다.

 

순전파와 역전파를 반복하며 모형을 학습시켜 최종적으로 각 단어 다음에 나올 단어를 완벽하게 예측하는 은닉상태를 갖는 것이 RNN의 목적 중 하나입니다. 

 

[그림 2]는 'You say goodbye and I say hello'에서 각 단어 다음에 나올 단어를 예측하며 학습시킨 RNN 언어모델입니다. 

 

[그림 2] RNN의 언어 모델

 

[그림 2]에서 You 라는 단어가 Embedding 계층을 거친 후 RNN에 입력되면, you의 은닉상태 h_you를 출력하고 다음에 올 단어

 

say를 예측합니다. 은닉상태 h_you다음 RNN 계층으로 들어가 say라는 단어가 임베딩된 형태와 연산합니다. 여기서 h_you는 과거의 정보 'you'를 응집한 은닉 상태입니다.

 

다음 RNN 계층에서 나온 say의 은닉상태 h_say는 과거의 정보 'You say'를 응집한 은닉 상태입니다. 이후 h_say를 이용해 다음에 올 단어 goodbye를 예측합니다.

 

이 과정이 RNN 학습, 순전파 과정입니다. 이후 역전파 과정을 거치며 예측 단어와 실제 단어를 비교하면서 가중치와 은닉상태를 업그레이드합니다.

 

2. 알고리즘

   2.1 순전파

 

[그림 3] RNN 순전파 과정

 

[그림3]은 RNN의 순전파 과정입니다. ('You say goodbye and I say hello'에서 다음에 나올 단어를 예측하며 RNN 계층을 학습하는 과정입니다.) 

 

1) say의 은닉상태인 h_sayhello가 임베딩된 벡터(x_hello)RNN계층에 들어간 후 일련의 과정을 통해 hello의 은닉상태인 h_helllo y_hello를 출력합니다.

2) 출력된 은닉상태는 다음 RNN 계층의 입력으로 이동합니다.

3) h_hellohello를 비롯해 say, I 와 같이 그동안 이동해온 단어들의 정보를 갖고있습니다.

4) y_helloh_hello가 변형된 형태로, hello의 다음 단어를 예측한 결과입니다.

 

여기서 일련의 과정은 [그림4]의 식으로, 모형으로 나타내면 [그림3]의 오른쪽 직사각형입니다.

 

[그림 4] RNN 순전파 수식

1) 가중치와 편향인 Wh, Wx, bRNN계층별로 동일합니다.

2) [그림 4]를 보면 h_hello를 구하기 위해 h_sayWh를 곱하고 hello를 임베딩한 단어벡터(x_hello)Wx를 곱한 후 편향(b)을 더했습니다.

3) 이후 하이퍼볼릭탄젠트 함수(tanh)를 씌웠습니다. 

 

   2.2 역전파

 

[그림 5] RNN의 역전파

1) RNN에서 오차역전파는 RNN 계층에서 출력된 결과와 Y값의 차이를 반영해 가중치와 은닉상태를 업그레이드하는 과정입니다.

2) 예를 들면, [그림5]에서 Softmax 이후 나오는 단어들의 예측 확률과 실제값의 오차를 Cross Entropy로 구합니다.

3) 이후 오차를 미분해 기울기{dh_hello, dh_row, dh_say, dw_x, dx_hello, dw_h}를 구하고 각 가중치에 반영해 업그레이드하는 식으로 오차역전파가 진행됩니다.

4) 오차를 미분하는 과정에서 y에 대해 미분하는 과정이 필요합니다.

5) y에 대해 미분하는 식을 나타내면 [그림6]과 같습니다.

 

[그림 6] RNN 역전파 수식

 

3. 기울기 소실 문제

 

1) RNN에서 역전파가 진행되면서 기울기가 소실되는 문제가 발생합니다.

2) 우선 오차역전파를 통해 은닉상태, 가중치, 편향{h, W, b}은 기울기/미분값이 반영되며 업그레이드 됩니다.

3) RNN은 기울기/미분값을 구하는 과정이 [그림 7], [그림 8]과 같이 복잡합니다.

4) 만약 RNN 계층이 많다면, 오차역전파가 진행될수록 기울기가 소실되는 문제가 발생합니다.

 

수식으로 증명하면서 기울기가 어떻게 소실되는지 보여드리겠습니다.

 

[그림 7] 기울기 전개식 (1)

 

1) [그림 7]은 h_roww_h로 미분하는 과정입니다.

2) Say의 은닉상태인 h_say는 이전 단계의 RNN계층인 you, say, goodbye, and, I 의 영향을 받습니다.

3) 따라서 h_roww_h로 미분하려면 h_you, h_say, h_goodbye, h_and, h_I를 모두 반영해야 됩니다.

4) [그림 7]을 정리하면 [그림 8]과 같습니다.

 

[그림 8] 기울기 전개식 (2)

 

1) [그림 8]에서 h_roww_h로 미분하면 가중치, 은닉상태를 계속 곱하고 더하는 패턴이 보이는 것을 알 수 있습니다.

2) 만약 RNN 계층이 여러 개라면, 오차역전파 과정이 진행되며 기울기가 곱하고 더하는 과정이 반복될 것입니다.

3) 여기에서 기울기가 감소하는 문제가 발생합니다.

4) 그렇게 되면 오차역전파 과정이 꽤 진행되었을 때 업데이트할 기울기가 아주 작은 문제가 발생할 수 있습니다.

 

이것을 기울기 소실이라고 하며, 이를 해결하기 위해 LSTM을 이용합니다.

 

LSTM은 다음 시간에....

 

참고자료: https://ratsgo.github.io/natural%20language%20processing/2017/03/09/rnnlstm/

 

RNN과 LSTM을 이해해보자! · ratsgo's blog

이번 포스팅에서는 Recurrent Neural Networks(RNN)과 RNN의 일종인 Long Short-Term Memory models(LSTM)에 대해 알아보도록 하겠습니다. 우선 두 알고리즘의 개요를 간략히 언급한 뒤 foward, backward compute pass를 천천

ratsgo.github.io

 

이 게시글은 '밑바닥부터 시작하는 딥러닝2'을 공부한 내용 바탕으로 정리했습니다.

http://www.yes24.com/Product/Goods/72173703

 

밑바닥부터 시작하는 딥러닝 2 - YES24

직접 구현하면서 배우는 본격 딥러닝 입문서 이번에는 순환 신경망과 자연어 처리다! 이 책은 『밑바닥부터 시작하는 딥러닝』에서 다루지 못했던 순환 신경망(RNN)을 자연어 처리와 시계열 데

www.yes24.com

RNN을 본격적으로 설명하기 전에 언어모델로서 RNN이 왜 필요한지 설명드리겠습니다.

 

1과 2에서 언어모델을 설명한 후, 3에서 언어모델로 적합한 기법이 RNN임을 강조하며 필요성을 설명드리겠습니다.

언어모델을 이미 아는 분이시면 3으로 바로 넘어가주세요 :)

 

순서는 아래와 같습니다.

 

 

1. 언어모델이란?

2. 수식으로 표현한 언어모델

3. 언어모델 관점, RNN의 필요성

 

 

1. 언어모델이란?

 

 

언어모델은 문장에 대해서, 그 문장이 얼마나 자연스러운지를 확률로 평가하는 것입니다.

예를 들면, '나는 학교에 간다'라는 문장에는 높은 확률을 출력하고 '나는 학교에 갈매기'에는 낮은 확률을 출력하는 것이 일종의 언어모델입니다.

 

언어모델은 기계번역과 음성인식에 대표적으로 이용됩니다. 하지만 새로운 문장을 생성하는 용도로도 사용할 수 있습니다. 왜냐하면 언어모델은 단어 순서가 얼마나 자연스러운지를 확률적으로 평가할 수 있기 때문입니다. 따라서 해당 확률분포에 따라 다음 순서에 올 적합한 단어를 샘플링할 수 있습니다.

 

이제 언어모델을 수식으로 설명하겠습니다.

 

 

2. 수식으로 표현한 언어모델

 

 

w1,...,wm이라는 m개의 단어로 된 문장이 있을 때, 단어가 w1,...,wm순서로 등장할 확률을 P(w1,...,wm)이라고 합니다. 

이 확률은 동시확률이라고도 합니다. 우리는 이 확률을 구해서 문장의 자연스러운 정도를 계산합니다.

 

동시확률 P(w1,...,wm)은 사후 확률을 사용해 [식 1]과 같이 분해하여 쓸 수 있습니다. [식 1]의 사후확률은 타깃 단어보다 왼쪽에 있는 모든 단어를 조건으로 했을 때의 확률입니다. 이러한 사후확률을 총곱해서 나온 것이 언어모델의 동시확률입니다.

[식 1]

 

 

3. 언어모델 관점, RNN의 필요성

 

 

Word2Vec의 CBOW 모델을 언어 모델에 적용했을 때 나타나는 문제점(단어의 순서를 반영하지 않는 점)과 신경 확률론적 언어모델(NPLM)에서 제안한 모델의 문제점(단어가 늘어날수록 가중치가 증가하는 점)을 해결하기 위해 등장한 것이 RNN 언어모델입니다.

 

 

1) CBOW 모델을 이용한 언어모델

 

 

CBOW 모델을 억지로 언어모델에 적용하려면 맥락크기를 특정 값으로 한정하여 근사적으로 나타냅니다. [식 2]는 맥락을 왼쪽 2개의 단어로 한정합니다. 

[식 2]

맥락 크기를 특정 값으로 한정하여 나타내면, 맥락 바깥의 정보는 반영되지 않습니다.

 

그리고 문제점이 더 있습니다. 바로 CBOW 모델에서는 맥락 안의 단어 순서가 무시된다는 점입니다.

 

만약 맥락크기가 2일때,  'I say goodbye, you say hello' 문장에서 'you' 예측에는 어떻게 CBOW 모델을 사용할까요? 맥락인 'say, goodbye'를 이용하고 [그림 1]과 같습니다. 

[그림 1]

[그림 1]에서 모델의 은닉층에서는 'say'와 'goodbye' 단어 벡터들이 더해지므로 맥락의 단어 순서는 무시됩니다. 

 

 

2) NPLM(Neural Probabilistic Language Model) 에서 제안한 언어모델

 

 

[그림 2]

맥락의 단어 벡터 순서를 고려하기 위해 [그림 2]와 같이 은닉층에서 단어 벡터를 연결하는 방식이 있습니다.  하지만 이 방식을 취하면, 맥락크기에 비례해서 가중치가 늘어나는 문제점이 생깁니다.

 

 

3) RNN의 필요성

 

 

RNN은 맥락이 아무리 길어도 그 맥락의 정보를 기억하는 구조로, 순서가 있는 시계열 데이터에도 유연하게 대응할 수 있습니다. 따라서 주어진 문장의 정보를 습득하며 학습한 후, 다음에 올 단어를 예측할 수 있습니다. 

오늘은 역전파에 대하여 알아보겠습니다.

 

순서는 아래와 같습니다.

 

1. 로지스틱 회귀란?

2. 로지스틱 회귀를 단일층 신경망으로 구현하기

3. 로지스틱 손실 함수를 경사 하강법에 적용하기

 

입력층과 출력층으로만 구성된 단일층 신경망에서 역전파가 어떻게 진행되는지 알아보고자 합니다. 따라서 로지스틱 회귀를 구현하며 단일층 신경망에서의 역전파를 알아보겠습니다.

 

이 게시물은 Do it! 딥러닝 입문 책을 정리하였습니다.

 

http://www.yes24.com/Product/Goods/78896574

 

1. 로지스틱 회귀란?


로지스틱 회귀의 목적은 종속 변수(Y)와 독립 변수(X) 사이 관계를 구체적인 함수로 나타내서 예측 모델로 사용하는 것입니다. 독립 변수의 선형 결합으로 종속 변수를 설명한다는 관점에서는 선형 회귀 분석과 유사합니다.

*선형 결합: 일차식과 같습니다.

 

하지만 로지스틱 회귀는 종속 변수가 범주로 구성된 데이터를 대상으로 합니다. 입력 데이터가 주어졌을 때 로지스틱 회귀를 적용한 결과는 특정 분류로 나뉘기 때문에 일종의 분류 기법이라고도 합니다. 종속 변수의 범주가 2개인 경우 로지스틱 회귀라고 부르고 2개 이상인 경우 다항 로지스틱 회귀라고 부릅니다.

 

이번 시간에 저희는 종속 변수의 범주가 2개인 경우 사용하는 로지스틱 회귀를 공부합니다.

 

(출처: 위키백과 로지스틱 회귀)

 

로지스틱 회귀식은 [수식 1] 과 같습니다.

 

[수식 1] 로지스틱 회귀식

 

[수식 1]의 (1) 에 따르면 종속 변수 Y가 0과 1의 범주를 가질 때 Y가 1일 확률을 p라고 합니다.

(2)에 따르면 맨 오른쪽 항은 가중치 w1, w2와 편향 b를 입력값 x1, x2와 선형 결합한 일차식입니다.

그럼 확률 p는 어떻게 구할까요? (2)를 풀어낸 결과, 식 (3) 으로 구하는 것을 알 수 있습니다.

 

2. 로지스틱 회귀를 단일층 신경망으로 구현하기


[그림 1]은 로지스틱 회귀를 단일층 신경망으로 구현한 것입니다.

 

* 단일층 신경망: 은닉층이 없고 입력층과 출력층으로만 구성된 신경망입니다.

 

로지스틱 회귀에서 저희의 목적은 y가 0인지 1인지 예측하는 것입니다. [수식 1]의 (3)을 이용해서 y가 1인 확률을 구하고 임계 함수를 적용하여 y를 0 또는 1로 분류할 것입니다.

 

 

[그림 1] 로지스틱 회귀 단일층 신경망

 

[그림 1]을 통해 식으로 살펴보았던 로지스틱 회귀가 어떻게 신경망으로 구현되는지 단계별로 설명하겠습니다.

 

Step1. 입력층에 입력값 x1과 x2가 들어갑니다.

 

Step2. 출력층에서 입력값들과 가중치 w1, w2 그리고 편향 b을 선형 결합합니다. 그 결과를 z라고 합니다.

 

Step3.  z에 로지스틱 함수를 적용합니다. (이것은 시그모이드 함수라고도 합니다.)

          z와 같은 가중합을 출력값 형태인 a로 변환하는 함수를 활성화 함수라고 합니다. 활성화 함수에는 시그모이드

          함수, 소프트 맥스 함수 등이 해당됩니다.

 

* 가중합: 각 입력값과 가중치를 곱한 후 이 결과들과 절편을 합한 것을 의미합니다.

* 활성화 함수: 입력값들의 가중합을 출력값으로 변환하는 함수입니다.

 

Step4.  Step3의 결과로 y=1일 확률이 나오고 이것을 a라고 합니다. 마지막으로 a에 임계함수를 적용하여 0.5보다 크면 1, 작으면 0으로 분류합니다.

 

이로써 로지스틱 회귀 과정을 알아보았습니다. 그런데 궁금한 점이 하나 있습니다. 가중치와 절편은 어떻게 구할까요?

 

3번 항목에서 가중치와 절편을 업데이트하는 방법을 차근차근 배워봅시다.

 

3. 로지스틱 손실 함수를 경사 하강법에 적용하기


로지스틱 회귀와 같이 분류하는 알고리즘의 목표는 무엇일까요? 바로 올바르게 분류된 데이터의 비율을 높이는 것입니다. 그럼 알맞게 분류된 데이터의 비율을 높이는 방향으로 가중치와 절편을 업데이트 해야겠죠? 여기에 꼭 필요한 개념이 있는데요. 바로 손실 함수와 경사 하강법입니다.

 

* 손실 함수: 예측값과 실제값의 차이를 함수로 정의한 것을 말합니다. 손실 함수는 신경망의 가중치, 절편을 수정하는 기준이되는 함수입니다. 제곱 오차(예측값과 실제값 차이의 제곱합), 크로스 엔트로피 등이 손실 함수로 사용됩니다.

* 경사 하강법: 어떤 손실 함수가 정의되었을 때, 손실 함수의 값이 최소가 되는 지점을 찾아가는 방법입니다.

 

[그림 2]를 통해 로지스틱 회귀의 가중치와 절편을 업데이트 하는 과정을 단계별로 설명하겠습니다.

 

[그림 2] 로지스틱 회귀 역방향 계산

 

Step1. 로지스틱 회귀의 손실함수 L은 [수식 2]와 같습니다.  y는 실제값, a는 시그모이드 함수(활성화 함수)가 출력한 값 입니다. 

 

[수식 2] 로지스틱 회귀의 손실함수

 

Step2. Step1에서 정의한 손실함수(L)를 가중치(w)와 절편(b)에 대해 각각 미분한 기울기를 구할 것입니다. 이후 가중치와 절편을 업데이트 하겠습니다. 기울기를 직관적으로 구하기 어렵기 때문에 미분의 연쇄법칙을 이용하겠습니다. 

 

[수식 3] 미분의 연쇄법칙

 

[수식 3]의 왼쪽항은 손실함수를 가중치에 대해 미분한 기울기, 오른쪽항은 미분의 연쇄법칙으로 정리한 것입니다.

 

[수식 4] 기울기 식

 

[수식 4]는 [수식 3]의 오른쪽항을 구성하는 기울기를 구한 식입니다. 

 

[수식 5] 손실함수를 가중치, 절편에 대해 미분

 

[수식 5]는 미분의 연쇄법칙을 이용해서 기울기를 계산한 결과입니다. 

참고로 손실 함수에 대한 미분이 연쇄 법칙에 의해 진행되는 구조를 보고 그레디언트(기울기)가 역전파된다고 말합니다.

 

Step3.  로지스틱 회귀의 가중치 업데이트를 위해 손실 함수(L)를 가중치(w)에 대해 미분한 식을 가중치에서 뺍니다. 절편(b)도 마찬가지로 계산하면 됩니다. 계산식은 [수식 6]입니다.

 

[수식 6] 가중치 업데이트

이거 새 게시물을 추가하는 법이 독특하네요.. 한참 찾았습니다..ㅠㅠ

 

저의 두 번째 게시물은 "MNIST 데이터를 CNN에 적용하여 분류하기"입니다.

 

MNIST 데이터는 [그림 1]처럼 손으로 쓴 숫자 이미지로 구성되어 있습니다.

 

[그림 1] MNIST 데이터 시각화

 

저는 이 데이터를 이용해서 실제 숫자를 예측해보겠습니다. 

 

MNIST 데이터는 Kaggle에서 다운로드하였습니다.

 

링크: https://www.kaggle.com/c/digit-recognizer/data

 

Digit Recognizer | Kaggle

 

www.kaggle.com

 

train, test, sample_submission 데이터로 구성되어 있으며 sample_submission 데이터는 제출용이니 생략합니다.

 

우선 train 데이터의 관측값은 0-9 중 숫자 하나를 손으로 적은 이미지로, 42000개의 관측값을 갖습니다.

 

이 이미지는 높이 28, 너비 28 픽셀로 총 784 픽셀입니다. 각 픽셀에는 하나의 픽셀 값이 연결되어 해당 픽셀의 밝기 또는 어두움을 나타내며 숫자가 높을수록 어두워집니다. 이 픽셀 값은 0에서 255(포함) 사이의 정수입니다.

 

train 데이터의 맨 앞 열은 이미지에 있는 숫자를 나타내고 나머지 784개의 열은 해당 이미지가 갖고 있는 784개의 픽셀을 의미합니다.

 

따라서 맨 앞 열은 label 변수로 0-9 값을 갖고 나머지 784개의 열은 0에서 255 값을 갖습니다.

 

test 데이터는 label을 제외한 변수를 갖고 있으며 28000개의 관측값을 갖습니다.

 


MNIST 데이터 실습은 아래 항목으로 구성됩니다.

 

1. Colab으로 파일 불러오기

 

 1-1. 구글 마운트 하기

 1-2. 파일 불러오기

 

2. 데이터가 어떻게 생겼을까

 

3. 데이터를 전처리 하기

 

 3-1. train에서 label은 target, 나머지는 x_train으로 분리합니다.

 3-2. 데이터 표준화를 합니다.

 3-3. CNN모델 입력 형태로 차원을 변환합니다.

 

4. 모델 형성하기

 

5. 전체 코드

 


 

 

그럼 시작하겠습니다.

 

저는 Google Colaboratory를 이용하기 때문에 Colab 환경에 맞춰서 진행하겠습니다.

 

1. Colab으로 파일 불러오기

 

Colab으로 파일을 불러오는 방식은 다양합니다. 저는 Google Mount를 평소에 사용하기 때문에 이걸로 가겠습니다.

 

1-1. 구글 마운트 하기

 

 

위와 같이 코드를 치면 authorization code를 입력하는 란이 나옵니다. 위의 파란색 url에 접속하면 code를 받을 수 있습니다. code를 복사하여 입력란에 붙여 넣고 Enter를 치면 됩니다.

 

1-2. 파일 불러오기

 

위와 같이 입력하면 csv파일을 불러올 수 있습니다.

 

 

2. 데이터가 어떻게 생겼을까

 

train, test 데이터의 size를 알 수 있습니다. 

 

이번에는 train 데이터 42000개 중 0부터 3번째 데이터를 이미지로 직접 나타내 보겠습니다.

 

 

 

3. 데이터를 전처리하기

 

3-1. train에서 label은 target, 나머지는 x_train으로 분리합니다.

 

 

3-2. 데이터 표준화를 합니다.

 

 

픽셀이 0~255의 정수 값을 갖기 때문에 255로 나눠서 표준화하였습니다.

 

3-3. CNN모델 입력 형태로 차원을 변환합니다.

 

 

 

4. 모델 형성하기

 

[그림 2]에서는 이번 실습 때 사용하는 CNN 모델 프로세스를 자세히 보여줍니다.

 

[그림 2] CNN 프로세스

 

직접 코드로 구현해봅시다.

 

아래의 코드를 봅시다.

 

우선 모델 형성에 필요한 패키지를 설치하고요.

 

 

모델 층을 쌓는 코드에는 중간중간 설명을 적겠습니다. (하단에 정리한 코드 올려놓았습니다.)

 

model=keras.Sequential([

 

Sequential은 신경망 층을 쌓을 때 사용합니다.

앞으로 나오는 각 코드를 우리는 하나의 계층이라고 하겠습니다.

 

keras.layers.Conv2D(32, kernel_size=(3,3), input_shape=(28,28,1), padding='SAME', activation=tf.nn.relu)

 

첫 번째 층은 컨볼루션층입니다

맨 앞(32): Kernel(Filter) 수입니다.

kerel_size: Kernel의 크기를 지정합니다.

input_shape: 샘플 수를 제외한 입력 형태를 정의합니다. (행, 열, 채널 수)로 정의합니다.

                   (채널은 색상(R, G, B)을 의미하고 사용하는 데이터는 흑백 이미지이기 때문에 채널 수가 1입니다.)

Padding: padding이 'SAME'이면 출력 데이터 사이즈와 입력 데이터 사이즈가 동일합니다.

Activation: 활성화 함수를 설정합니다.

 

keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2), padding='SAME')

 

다음은 MaxPooling 계층입니다.

pool_size: Pooling 영역의 크기입니다.

strides: Pooling 영역이 이동하는 간격을 의미합니다.

 

keras.layers.Conv2D(64, kernel_size=(3,3), padding='SAME', activation=tf.nn.relu),

keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2), padding='SAME')

 

위의 코드를 반복합니다. (본 실습에서는 컨볼루션층을 두 번 거칩니다.)

 

keras.layers.Flatten()

 

앞에서는 Image data의 Feature Maps를 추출했습니다. 이번에는 실제 숫자로 분류하는 작업을 해보겠습니다.

Flatten 계층을 이용하여 3차원의 데이터를 1차원으로 변환합니다.

 

keras.layers.Dense(1024, activation='relu')

 

이후 완전 연결 계층 (Dense)를 적용합니다.

units: 1024는 완전 연결 계층을 거친 후 나오는 출력 데이터의 수를 의미합니다. 

 

keras.layers.Dense(10, activation='softmax')

 

마지막 완전 연결 계층은 units이 10이고 활성화 함수가 Softmax 입니다.

 

0에서 9 사이의 숫자를 예측하기 때문에 10개의 클래스로 분리됩니다.

따라서 이 계층을 지난 후 나오는 출력 데이터의 수가 10이 되어야 하구요.

 

활성화 함수로 Softmax를 쓰면 각 클래스로 예측될 확률을 알 수 있습니다.

예를 들면, 1로 분류될 확률이 0.1, 2로 분류될 확률이 0.3 등 (확률의 전체 합은 1이겠죠?!)

 

keras.layers.Dropout(0.25)

 

마지막으로 Dropout 계층입니다.

Dropout 계층은 과적합(over-fitting)을 막기 위한 방법으로 신경망이 학습 중일 때, 무작위로 신경망을 빼서 모델 학습을 방해함으로써, 과적합을 방지합니다.

 

[그림 3] CNN 모델 계층 정보

 

[그림 3]는 형성한 모델의 각 계층을 지나면서 출력되는 Output의 차원을 보여줍니다.

(Output Shape에서 확인 가능합니다.)

 

5. 전체 코드

 

다음과 같습니다.

 

from google.colab import drive
drive.mount('/content/drive')

import pandas as pd
test=pd.read_csv('/content/drive/MyDrive/test.csv')
train=pd.read_csv('/content/drive/MyDrive/train.csv')
sample_sub=pd.read_csv('/content/drive/MyDrive/sample_submission.csv')

print("Train Data Size: ", train.shape)
print("Test Data Size: ", test.shape)

import matplotlib.pyplot as plt
import numpy as np
plt.style.use('seaborn')
fig, ax = plt.subplots(1,4, figsize=(10,10))
fig.tight_layout(pad=0.0)

for col in range(4):
    im_0 = np.array(train.drop("label", axis=1). iloc [col]). reshape(28,28)
    ax [col]. imshow(im_0, cmap="gray")
    ax [col]. axis("off")

target = train ['label']
x_train = train.drop('label', axis = 1)

x_train=x_train/255
test=test/255

x_train = np.array(x_train). reshape((-1,28,28,1)) 
x_train.shape

test = np.array(test). reshape((-1,28,28,1))
test.shape

from tensor flow.keras.utils import to_categorical
target = to_categorical(target, num_classes = 10)
target.shape

import tensorflow as tf
from tensorflow import keras

model=keras.Sequential([
keras.layers.Conv2D(32, kernel_size=(3,3), input_shape=(28,28,1), padding='SAME', activation=tf.nn.relu),
keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2), padding='SAME'),
keras.layers.Conv2D(64, kernel_size=(3,3), padding='SAME', activation=tf.nn.relu),
keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2), padding='SAME'),
keras.layers.Flatten(),
keras.layers.Dense(1024, activation='relu'),
keras.layers.Dense(10, activation='softmax'),
keras.layers.Dropout(0.25)])

model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])

 

model.summary() #각 계층별 출력 데이터의 차원을 확인하실 수 있습니다.

 

model.fit(x_train, target, epochs=5) #모델 학습

 

pred=np.argmax(model.predict(x_train), axis=-1) #분류한 결과를 확인하실 수 있습니다.

 


 

출처 1: https://www.kaggle.com/mhmdsyed/digital-recognizer-simple-cnn-model

 

Digital Handwriting Recognizer ✍️ |

Explore and run machine learning code with Kaggle Notebooks | Using data from Digit Recognizer

www.kaggle.com

출처 2: https://dsbook.tistory.com/71?category=780563 

 

합성곱 신경망, Convolutional Neural Network (CNN)

완전 연결 계층, Fully connected layer (JY) Keras 사용해보기 1. What is keras? 케라스(Keras)는 텐서플로우 라이버러리 중 하나로, 딥러닝 모델 설계와 훈련을 위한 고수준 API이다. 사용자 친화적이고 모델의

dsbook.tistory.com

제가 블로그가 처음이라서 출처를 어떻게 남기는지, 직접 말씀드려야 하는지 잘 모르겠습니다.. 

만약 이 방법이 틀렸음 알려주신다면 감사드리겠습니다!

피드백, 질문 언제든지 환영입니다!!

 

다음은 RNN 이론을 올리겠습니다!

CNN은 Convolutional Neural Networks의 줄임말로 알다가도 모르는 기법이다.

그래서 이론을 확실히 하기 위해서 CNN 개념 및 원리를 올려본다.

 

최대한 알기 쉽게 설명하도록 하겠다. 피드백은 언제나 환영이다. 댓글도 Welcome이다.

 

이 글의 항목은 아래와 같다.

 

 

1. CNN의 NN, Neural Networks(신경망) 이란 무엇인가?

2. CNN이란 무엇인가?

 

 

 

1. CNN의 NN, Neural Networks(신경망) 이란 무엇인가?

 

 

  [그림 1]은 신경망의 원리를 잘 보여주는 예시로, 이 예시를 바탕으로 신경망을 설명하겠다.

 

[그림1] Neural Network 원리

 

  Step.1 Inputs은 데이터를 넣는 곳으로 만약 데이터 [1,2,3,4,5]를 신경망에 넣고 싶으면 Inputs에 [1,2,3,4,5]를 할당하면 된다. (x1=1, x2=2,..., x5=5) 

 

  Step.2 w1부터 w5는 가중치이다. 가중치와 Inputs의 각 원소를 곱한다.

     (x1*w1, x2*w2,..., x5*w5)

 

  Step.3 Step.2에서 구한 가중치와 원소의 곱을 모두 합한다.

     (x1*w1+x2*w2+...+x5*w5)

 

  Step.4 Step.3에 활성화 함수를 씌워서 출력한다. 활성화 함수는 Activation Function이며, 시그모이드, 렐루, 소프트 맥스 등이 사용된다.   

 

 

 

2. CNN이란 무엇인가?

 

 

2번 섹션은 세 개의 항목으로 나눴다.

 

2-1. 합성곱(Convolution)을 알아보자

2-2. CNN의 프로세스를 통째로 알아보자

2-3. CNN의 프로세스를 세부적으로 알아보자

 

1번 섹션에서는 1차원 데이터를 신경망에 적용했다. 그렇다면 이미지와 같은 2차원 데이터는 어떻게 신경망에 적용할까? 

 

정답은 지금부터 알아볼 CNN이다.

 

CNN은 Convolutional Neural Networks의 약자로, 핵심은 신경망에서 사용된 연산을 합성곱으로 교체한 것이다.

 

새로운 개념이 나왔다.

 

합성곱이 무엇일까? 2-1 섹션에서 차근차근 알아보자.

 

 

2-1. 합성곱(Convolution)을 알아보자

 

 

합성곱은 곱셈과 덧셈으로 이루어진 연산이다.

 

[그림 2]에서 행렬 A와 행렬 B를 합성곱 하여 행렬 C를 만들었다.

 

행렬 A와 행렬 B의 차원이 다른데 어떻게 곱셈이 가능할까?

 

정답: 행렬 A 위에서 행렬 B를 이동시키며 겹치는 원소들끼리 곱하고 더한다.

 

[그림2] 합성곱의 원리

 

[그림 2]를 단계별로 설명해보겠다.

 

Step 0. 행렬 A 위에 행렬 B를 올려놓는다.([그림 2]의 빨간색 네모 위에 행렬 B를 올려놓는다)

 

Step 1. 행렬 A의 빨간색 네모와 행렬 B의 각 원소를 곱하고 모두 더하면 행렬 C의 첫 번째 원소 7이 나온다.

(실제 계산: 1*1+0*0+2*0+0*2+2*1+1*3+0*0+2*0+1*1=7)

 

Step 2. 이제 행렬 B를 오른쪽으로 이동시킨다.

행렬 A와 겹치는 부분의 각 원소를 곱하고 모두 더한다. 행렬 C의 두 번째 원소 6이 나온다.

 

Step 3. 이번에는 행렬 B를 대각선 아래로 이동시킨다.

행렬 A와 겹치는 부분의 각 원소를 곱하고 모두 더한다. 행렬 C의 세 번째 원소 7이 나온다.

 

Step 4. 마지막으로 행렬 B를 왼쪽으로 이동시킨다.

[그림 2]에서 행렬 A의 파란색 네모와 행렬 B의 각 원소를 곱하고 모두 더하면 행렬 C의 네 번째 원소 10이 나온다.

 

Step 5. 이렇게 행렬 B가 행렬 A 위를 다 돌고 나면 행렬 C가 완성된다. 이 과정에서 사용된 연산이 바로 합성곱이다.

 

 

2-2. CNN의 프로세스를 통째로 알아보자

 

 

[그림 3]은 CNN의 원리로, 컴퓨터에서 CNN을 통해 이미지를 숫자 2로 분류하는 과정을 보여준다.

 

[그림 3]으로 CNN의 프로세스를 설명해보겠다.

 

우선 Input Data에 들어간 이미지 데이터가 가진 특징들을 추출하는 Feature Extraction 작업을 거친다.

이후 자동차 이미지면 자동차, 숫자 2 이미지이면 숫자 2 등으로 분류하는 Classification 작업을 거친다.

 

[그림 3]은 이미지를 0에서 9 사이의 숫자 중 하나로 분류하는 과정이다.

 

[그림 3] CNN의 원리

 

좀 더 알아보자.

 

Step 1. Image Data에 Padding을 하여 Input Data에 넣는다. 여기서 Padding은 '덧댄다'는 의미로, 합성곱 작업을 거치면 결과의 차원이 줄어드는 문제를 방지하기 위하여 Input Data의 모서리에 0이나 다른 숫자를 덧대는 작업을 한다.

(Padding 은 2-3 섹션에서 자세히 알아보자)

 

Step 2. 특성 맵(Feature map)을 추출하기 위하여 Input Data와 Filter를 합성곱(Convolution) 한 후 Relu라는 활성화 함수를 씌운다. [그림 3]에는 네 개의 Filter가 있다. Input Data와 네 개의 Filter를 각각 합성곱 한 후 활성화 함수를 적용하면 네 개의 특성 맵(Feature Maps)이 나온다.

 

Step 3. Feature Maps의 차원의 복잡성을 줄이면서 유의미한 정보는 유지하기 위해 Max Pooling을 이용한다.

(Pooling은 2-3 섹션에서 자세히 알아보자)

 

Step 4. Flatten을 통하여 3차원의 Feature Maps(Step 3의 결과)를 1차원의 형태로 변형시킨다.

 

Step 5. Step 4의 결과를 완전 연결 신경망에 적용한 후 0에서 9 사이의 숫자일 확률을 구하기 위해 Softmax 함수를 적용한다. CNN에 입력한 이미지 데이터가 0일 확률부터 9일 확률까지 알 수 있다.

 

Step 6. Step5의 결과에 최대의 확률을 가진 값을 구하는 argmax함수를 적용한다. [그림 3]의 Output에서 2로 분류된 것을 알 수 있다.

 

 

2-3. CNN의 프로세스를 세부적으로 알아보자

 

 

1) Padding

 

CNN에서 이미지의 특징을 추출하기 위하여 Filter와 합성곱 하는 과정을 거친다.

이후 차원이 축소되면서 정보가 손실되는 경향을 보이는데, 차원이 줄어드는 것을 예방하기 위해 사전 작업으로 이미지 데이터에 Padding(덧대기)를 한다. 

 

[그림 4]는 Padding 예시이다.

 

[그림4] Padding 예시

 

Padding은 두 가지 방법이 있다. 하나는 [그림 4]와 같이 데이터의 테두리에 0을 덧대는 방법, 다른 하나는 데이터의 테두리 값을 복사하여 덧대는 방법이 있다. 

 

[그림 4]처럼 테두리에 0을 덧대면 합성곱 이후에도 차원이 유지됨을 알 수 있다.

 

 

2) Filters

 

CNN에서 Input Data와 Filter를 합성곱 한 후 Input Data의 특성 맵(Feature Map)이 추출된다.

 

Filter가 어떤 값을 가지느냐에 따라서 추출되는 특성 맵이 달라지고 Input Data를 얼마큼의 간격으로 이동하느냐에 따라서도 달라지는데 이 간격을 'Stride'라고 한다. 또한 n개의 Filter를 이용하면 n개의 특성 맵이 추출된다. 

 

참고로 CNN에서 Filter와 Kernel은 같은 의미이다.

 

 

이해를 돕기 위해 [그림 5]를 보며 설명하겠다.  

 

[그림 5] Filter 적용 예시

 

[그림 5]는 Padding을 씌운 Input Data와 Filter의 합성곱을 나타낸다. 이때 Filter의 수는 한 개라서 하나의 특성 맵이 추출되고 Filter가 Input Data 위를 이동하는 간격은 2이다. 

 

[그림 5]에서 Input Data의 빨간색 네모와 Filter와 연산하여 Feature Map의 빨간 부분이 계산되고 2칸을 이동한 Input Data의 주황색 네모와 Filter와 연산하여 Feature Map의 주황색 부분이 계산된다. 이런 식으로 반복하면 하나의 Feature Map이 완성된다. 

 

 

3) Pooling

 

Pooling은 특성 맵을 스캔 하여 최댓값을 고르거나 평균값을 계산하는 것을 의미한다. 보통 연구자들은 최댓값을 고르는 Pooling 방식(Max Pooling)을 선호한다. 그 이유는 Input Data에서 각 Filter가 찾고자 하는 부분은 Feature Map의 가장 큰 값으로 활성화되는데 Max Pooling 방식은 Feature Map의 차원은 줄이면서 유의미한 정보이자, 가장 큰 특징은 유지시키는 성질이 있기 때문이다. 

 

[그림 6]은 Max Pooling의 예시이다.

 

[그림 6] Max Pooling 예시

 

하나의 Feature Map이 있으면 이 위를 풀링 영역이 지나가면서 최댓값을 가져온다. 풀링 영역은 사용자가 지정할 수 있으며 보통 2x2를 크기로 지정한다. 그리고 이동 간격(Stride)은 풀링 영역의 한 모서리 크기로 지정한다.

 

[그림 6]에서 첫 번째 풀링 영역에서 최댓값 5를 뽑아내고 두 칸 이동한 두 번째 풀링 영역에서 최댓값 8을, 왼쪽 대각선 아래로 이동한 세 번째 풀링 영역에서 최댓값 5를, 두 칸 이동한 네 번째 풀링 영역에서 최댓값 4를 뽑아낸다.

 

 

다음 게시물에서는 MNIST DATA가 CNN에서 어떻게 굴러가는지 Python 실습을 통해 알아보자

+ Recent posts