머신러닝

CNN 이미지 인식: Pooling to Deep Stacking

coding art 2021. 7. 9. 18:10
728x90

6-3절 앞 페이지의 마지막 부분에서 9X9 매트릭스에 표현된 이미지 “X”를 식별하기 위해서 3개의 컨볼루셔널 필터를 사용해 적용하여 각 필터의 특징을 그대로 반영한 3개의 7X7 이미지 매트릭스가 성공적으로 생성되었다. 메모리 용량 측면에서 보면 81 픽셀 이미지 데이터에서 49픽셀 이미지 데이터 3세트가 생성되었으므로 원래 이미지의 거의 2배에 가까운 147 픽셀 이미지 데이터를 가지게 된 셈이며 생각보다 증가된 메모리 용량은 그다지 달갑지 않아 보인다. 당연히 메모리 용량을 줄일 수 있도록 처리가 뒤따라야 할 것이다. 이 과정을 subsampling 또는 Pooling 이라고 한다.

 

Pooling의 의미는 특정한 가두리 안에 위치한 픽셀들을 대표할 수 있는 값을 정하는 것이다. 위 결과에서 보듯이 필터링 이전이나 필터링 후의 픽셀 값을 보면 큰 값은 드물고 반면에 작은 값들이 많이 분포하게 된다. 이는 Edge 라고 하는 기하학적인 모양의 명암으로 식별되는 오브젝트는 가느다란 선 모양이므로 이 Edge 즉 라인을 가로지르게 되면 명암 값이 크게 변하게 된다. 따라서 위와 같이 백색 edge 의 경우에 그 주변의 값이 1 이라면 백색 픽셀은 +1 이므로 이미지 픽셀의 최소값과 최대값이 근접해 있게 된다. 이러한 상황은 한 번 필터링 한 경우에도 그다지 변화가 없다. 따라서 적당한 가로 세로 크기의 가두리 매트릭스를 사용하여 Pooling 작업을 통해 최대 값을 뽑아 보면 한 번 필터링 된 이미지의 특성이 어느 정도 큰 변화 없이 유지가 됨과 동시에 얻어지는 이미지 매트릭스의 크기가 작아지게 된다. 이때 사용하는 가두리 매트릭스의 사이즈는 2X2 또는 3X3 매트릭스를 사용하며 스트라이딩 크기는 2로 하는게 보통이다.

현재의 이미지 CNN 작업에서 일차 필터링 후 얻어진 매트릭스 크기가 7X7 이므로 만약 2X2 가두리 매트릭스를 사용한다면 4회 스트라이딩 후 오른쪽 한 줄이 모자라게 되는데 이때는 “padding” 기법이라 하여 없는 한 줄이 있다고 가정하고 “0”을 넣어서 처리하면 된다. 하지만 3X3 가두리 매트릭스를 사용하면 2번 스트라이딩 후 딱 맞으므로 그런 문제는 일어나지 않겠죠?

Pooling 작업 후의 결과를 보면 7X7 이미지 매트릭스가 4X4 로 축소되었으나 여전히 번 대각선 형태의 특징이 유지되고 있음에 주목하자. 메모리 용량 측면에서도 16픽셀이므로 3세트 합쳐서 48픽셀이므로 원 이미지의 81픽셀보다 훨씬 많이 줄었음을 알 수 있다.

3개의 필터링 된 이미지를 대상으로 Pooling 작업한 결과를 살펴보자. 첫번째는 대각선 특성이 잘 유지되었으나 두 번째는 중심의 X자형의 특성이 최종 매트릭스의 크기가 짝수X짝수 형태라 어쩔 수 없이 한 칸 움직일 수밖에 없지만 그래도 특성이 유지되었다고 볼 수 있다. 세 번째도 비슷한 상황인데 다소 마음에 안들기는 하지만 특성이 파손된 것은 아니라 본다.

이와 같은 결과를 얻어내는 과정 중간에 Normalization 과정을 넣어 둘 필요가 있을 수 있다. Normalization 이라는 용어는 확률론에서 확률 값을 01.0 사이에 맞추눈 작업을 의미하기도 한다. 하지만 여기서는 시작이 1.0+1.0에서 시작하여 한 번 필터링을 하게 되면 +1.0 은 그렁 저렁 남아 있으나 1.0 이 많이 사라지고 보다 적은 음수 값으로 처리되어 있음을 알 수 있다. 아직 음수로 남아있는 이 부분을 손질하여 모조리 0.0 으로 처리하게 되면 픽셀 값들이 모조리 01.0 사이에 있게 될 것이다. 바로 이 과정이 Normalization 이다. 뉴럴 네트워크(NN)에서 Sigmoid 대신 ReLU를 적용하면 바로 Normalization을 수행한 셈이 되는 것이다. 요즈음은 Normalization을 잘 사용하지 않는 추세임을 지적해 둔다. NN에서 Wide 폭과 layer들의 Depth가 큰 경우 초반에 ReLUSigmoid 대신 적용하면 안정적으로 NN을 계산할 수 있음을 이미 ReLU:Sigmoid 비율 테스트에서 보았다.

 

앞의 Pooling을 적용하기 전에 ReLU를 적용하고 난 후의 결과를 관찰해 보자. 기하학적 특징의 변화가 별로 없음을 관찰해야 할 것이다. CNN 에서는 필터링 후 항상 ReLU를 적용하면서 강요만 하고 그 이유를 거의 설명하지 않는데 그 이유는 사실 CNN 에 있는 것이 아니라 NN 계산 원리에서 찾아야 한다. CNN 의 마지막 부분에 가면 결국 NN 방식으로 연산을 마무리 짓게 되는데 미리 미리 Sigmoid 대신 ReLU 처리를 해 두면 Deep 한 경우 즉 연산하는 layer 가 늘어나도 그다지 문제를 일으키지 않는다는 점이다.

이렇게 필터링한 이미지에 대해서 ReLU 처리를 해도 이미지 크기는 그대로 유지되며 Pooling 처리를 해도 결과는 앞서 ReLU 처리를 하지 않은 경우와 기하학적으로 추출된 특징들이 동일하게 유지됨을 알 수 있다.

즉 컨볼루션널 필터링, ReLU 적용을 하나의 단위로 보면 이미지 매트릭스 크기가 2X2 정도로 쫄아들 때까지 여러 번 적용하면서 중간에 필요하면 Pooling을 넣을 수 있다.

다음의 Deep Stacking 그림을 보면 최종적으로 기하학작 특징을 그대로 유지하는 2X2 매트릭스가 얻어짐을 알 수 있다. 즉 하나의 알파벳 글자 이미지를 CNN 해나가면 3개의 2X2 매트릭스가 얻어진다는 결론이다.

그렇다면 마지막 남은 단계는 이 매트릭스들을 2개씩 띄어내어 한 줄로 변환 시키자. TensorFlow 에서는 이 과정을 reshaping 이라고 한다. MNIST 문제에서는 28X28 매트릭스를 한 줄짜리 784 매트릭스로 reshaping 하여 처리하기도 한다.

 

이어서 적절한 규모의 Wide Deep NN을 첨부하여 처음에 주어진 알파벳 이미지 데이터 “X”를 다음과 같이 라벨을 부여하여 학습을 시킬 수 있다. 즉 만약 어떤 이미지를 처리했더니만 이 부분의 값이 죄다 1.0 이라면 그 이미지는 처음에 주어진 알파벳 이미지 데이터 “X”와 확률적으로 100% 동일하다는 결론을 내릴 수 있을 것이다.

동일한 과정을 “O”에 적용하여 한 줄짜리 매트릭스에서 1.0 이 되는 위치를 알아낼 수 있을 것이다. 이때에는 알파벳 이미지 데이터 “O”에 대한 작업이므로 “X” 에 해당하는 위치의 값이들은 죄다 1.0 보다 작은 값들이 되어야 할 것이다. 여기까지가 CNN 에서의 학습(tranning) 과정에 해당한다. 그 다음 따르는 과정은 당연히 테스트(test)일 것이다.

그렇다면 오리지널 알파벳 “X” 가 아닌 짝퉁성 “x” 이미지를 이 CNN에 들이대 보면 그래도 뭔가 유사성이 많으므로 예를 들자면 다음과 같은 결과를 얻어 볼 수 있을 것이다. 특히 NN 의 마지막 layer에서 Softmax 로 처리하게 되면 해당 글자별 확률 계산을 얻어 볼 수 있는데 그 값을 다 더하면 물론 1.0 이 되어야 한다. 다음의 경우에서는 “X” 일 가능성이 92%이며 반면에 “O”일 가능성이 51% 로 계산된 결과이다.

컨볼루션널 필터링과 ReLU 처리를 여러번 함과 아울러 중간 중간에 Pooling 작업을 해서 아주 작은 매트릭스로 축소시킨 후 마지막 layerSoftmax를 넣은 NN 으로 학습시키게 되면 거의 99% 의 인식률을 얻어 볼 수 있게 되는 것이다.

MNIST에서처럼 아무러 부띠끄 작업 없이 그냥 입력할 경우에 비해서 CNN 에서는 Convolution 과정을 거쳐 아주 정제된 입력을 만들어 NN 에 입력시키기 때문에 대단히 정교한 결과가 얻어질 수 있는 것이다. 특히 주의할 점은 CNN 과정에서 학습이 일어나는 과정은 NN 에 국한되며 그 앞의 Convolution 과정은 우리가 카메라 사진 촬영 시에 앞부분에 고성능 렌즈를 장착하는 것과 같은 원리이다.

 

 

한편 NN의 마지막 부분 확률해석에 있어서 softmax 처리 부분은 2장의 내용들을 참고하기 바란다.