본문 바로가기
machine learning

[TENSORFLOW] CNN-CONVOLUTION

by 유주원 2017. 5. 8.

2017/04/19 - [machine learning] - [TENSORFLOW] Image AutoEncoder


이번 포스팅에서는 이미지나 오디오 등의 데이터에 대해 많이 쓰이는 CNN 모델에 대해 알아 볼 것이다.

기존 neural network의 경우에는 입력 데이터 차원이 클 수록 수많은 weight 파라미터를 가져야 한다는 단점이 있었다. 예를 들어 아래의 그림은 256x256의 이미지를 나타내며 각 픽셀이 10개의 output neuran에 매핑되고 있다. 아래의 방식을 기존에 학습한 neural network에 적용해 본다면 256x256x10 개의 weight 파라미터를 지녀야 할 것이다.

CNN에서는 공유 파라미터라는 개념을 도입해서 위와 같은 부하를 방지하고 있다.  

똑같은 256x256 이미지를 입력으로 받고 있지만 CNN에서는 convolution이라는 개념을 도입시킨다. 필터와 같은 개념으로 생각할 수 있는데, 256x256 이미지를 5x5나 3x3의 가중치로 쓱싹쓱싹 문질러서 새로운 이미지를 만드는 형태를 말한다. 이렇게 필터를 거쳐서 재탄생 이미지들을 feature map이라고 부르기도 한다.

5x5나 3x3이 256x256 이미지를 대표하는 공유 파라미터가 되는 것이며, 우리는 이러한 5x5나 3x3의 여러 형태의 mask를 이용해서 feature map들을 만들어서 각각의 시각으로 이미지 특징을 관찰해 볼 수가 있다.


아래의 코드를 통해 image들을 전처리하고 mask를 만들어 보고 mask 씌운 feature map들을 확인해 보자.

우선 image autoencoder를 만들때 사용했던 CIFAR 데이터를 다시 사용하자. read_data 함수를 통해 CIFAR 데이터를 읽은 후 읽은 이미지 데이터에 대해 전처리를 실행하자.


1차원으로 저장되어 있을 이미지 데이터를 3 x 32 x 32 행렬로 변환해 준다.( RGB 각각의 데이터로 나누기 위함) 행렬 변환이 끝났다면 이제 해당 RGB 데이터들의 평균을 구해 grayscale로 변환을 해준 후, 가장자리의 불필요한 데이터들을 자른다.(crop) 위의 코드에서는 좌우상하 각각 4 pixel씩 잘라냈다. 이렇게 자른 이미지를 다시 1차원 행렬로 변환해 준다. 여기서는 24 * 24를 1차원 행렬로 변환했으니 1* 576의 행렬이 만들어 진다. 

마지막 전처리 작업으로 1차원으로 만들어진 이미지 행렬에 대해 normalization 작업을 진행한다. 전체 픽셀의 평균값을 뺀다음 표준편차로 나눔으로써 normalization 작업을 완료한다.  

이렇게 전처리가 완료된 이미지를 show_some_examples 함수를 통해 확인해 볼 수 있으며, 아래의 그림과 같이 나타날 것이다.

이제 샘플 데이터들을 확인하고 전처리도 완료했으니 CNN을 convolution할 준비를 해보자.

weight 파라미터를 5x5 행렬에 input은 1개가 들어오고 output은 32개를 출력하도록 만들자. 우리는 자동차 이미지에 대해서 convolution을 진행해 볼 것이다. data[4,:]를 통해 자동차 이미지를 가져온 후 이미지로 뿌려주기 위해 24*24 행렬로 변환하자. 변환 후 plt.imshow를 통해 아래의 자동차 그림을 확인해 볼 수가 있다.

24x24의 input tenfor를 만들고, 32개의 bias도 선언한다. 입력 값 x에 W 가중치를 통과시키는 convolution을 만들어 conv 변수에 저장한다. strides라는 파라미터를 살펴보면, 첫번째와 네번째 값은 항상 1로 고정하고, 나머지 두 값은 x,y 축으로의 이동 step을 의미한다. 여기서는 mask를 x축으로 1만큼 y축으로 1만큼 이동시키겠다는 뜻이다. 만약 mask를 2x2만큼 움직이고 싶다면 1,2,2,1 이렇게 strides를 정의해 주면 된다. padding은 mask를 씌우게 되면 가장자리 값들이 사라지게 되서 점점 이미지가 작아지게 되는데 이를 방지하기 위해 가장자리의 값들을 채우는 것을 말한다. 여기서는 SAME이라는 값을 줌으로써 입력크기와 출력크기가 동일하게 되도록 zero padding이 실행되었다.

convolution 실행 이후에는 bias 값들을 더한 후 activation function인 relu를 씌운다. 

이제 session run을 통해 위의 동작들을 확인해 보자.

우선 랜덤으로 5x5 mask 값들을 32개를 만들었으며, show_weights를 통해 이 값들을 확인해 보자.

우리는 위의 만들어진 mask들을 차 이미지에 씌울 것이다. 각각의 mask 들이 차 이미지를 훑고 지나간 후의 feature map들을 확인해 보자.

bias를 더하고 relu를 씌운 상태의 feature map들을 확인해 보자.

이런식으로 계층을 계속 이어나가면서 이미지의 특징 데이터들을 찾아나가게 된다. 이번 포스팅에서는 convolution에 대해서만 살펴봤으며 다음 포스팅에 이어서 pooling과 fully-connection을 진행함으로써 최종적으로 image classification을 하는 과정을 살펴보겠다.

CNN_POOLING

FULLY-CONNECTION