티스토리 뷰

뉴런 네트워크에 대해 정의하면서, 다시 손으로 쓴 숫자를 인식하기 위한 문제로 돌아와 봅시다. 우리는 이 문제를 크게 두개의 문제로 나누어 생각할 수 있습니다. 첫째로, 많은 숫자가 포함된 이미지를 여러개의 조각난 이미지로 나누는 것입니다. 각각의 조각난 이미지는 하나의 숫자를 가지고 있습니다. 예를 들어, 다음과 같은 이미지는




다음과 같이 여섯 개의 이미지로 나누어 질 수 있습니다.



우리와 같은 인간들은 이 분리 문제를 쉽게 해결할 수 있으나, 이를 정확히 나누는 컴퓨터 프로그램에게는 꽤 도전적입니다. 일단 한번 이미지가 분리되고 나면, 프로그램은 각 이미지를 판별해야 합니다. 그래서, 예를 들면, 우리는 위에 있는 이미지중 첫번 째 이미지의 숫자를 판별하는 프로그램을 작성하고자 합니다.



첫번째 이미지는 위와같이 5가 쓰여진 이미지 입니다.


우리는 각각의 이미지의 숫자를 판별하는것에 대한 두번째 문제를 해결할 프로그램을 작성하는것에 초점을 맞추려고 합니다. 왜냐하면 분리 문제는 한번 숫자 판별 문제를 해결하고 나면 해결하는데 그리 어렵지 않기 때문입니다. 분리 문제를 해결하는데는 많은 접근 방법이 있습니다. 한 접근 방법은 이미지를 분리하는 여러가지 다른 방법들을 시도해 보는 것 입니다. 각각의 숫자를 식별하는 프로그램을 이용해서 분리를 시도한 이미지에 점수를 매기는 것이지요. 분리를 시도한 이미지는 숫자 식별 프로그램에 의해 점수가 매겨집니다. 각 분리된 이미지의 숫자를 식별하는데 어려움을 겪는다면 이미지는 낮은 점수를 받게 되겠지요. 이 아이디어와 다른 다양한 방법들은 이러한 분리 문제를 꽤나 잘 해결할 수 있습니다. 그러니 분리문제에 대해 걱정하는것 보다는 우리는 더 흥미롭고 어려운 문제를 푸는, 각각의 손으로 쓴 숫자를 인식하는 네트워크를 작성하는데 집중하고자 합니다.


각각의 숫자를 인식하기 위해서는, 우리는 3층 뉴런 네트워크를 사용해야 합니다.



네트워크의 입력 레이어는 입력 픽셀들의 변환된 값들을 가지고 있습니다. 다음 차례에서 이야기 하겠지만, 우리의 네트워크를 위한 학습 자료는 $28\times 28$크기의 많은 손글씨 이미지들로 이루어져 있습니다. 그러니 입력 레이어는 $784=28\times 28$크기의 뉴런들을 가지게 될겁니다. 간략하게 나타내기 위해서 저는 위 그림처럼 대부분의 뉴런들을 생략하였습니다. 입력 픽셀들은 흑백값입니다. 0.0은 흰색, 1.0은 검정을 나타냅니다. 0.0 에서 1.0으로 숫자가 증가할 수록 점점 어두워 지는 값을 가지게 됩니다.


네트워크의 두번째 층은 은닉층 입니다. 우리는 은닉층의 뉴런들의 갯수를 n으로 나타내기로 합시다. 그리고 n에 여러 다른 값을 넣어서 실험을 해볼겁니다. 위에 보여드린 예는 단지 15개의 뉴런만을 가진 은닉층을 가지고 있습니다.


위 네트워크의 출력층은 10개의 뉴런을 가지고 있습니다. 첫번째 뉴런이 발화하면, 즉 1에 가까운 값을 가지게 되면, 이는 네트워크가 숫자는 0이다 라고 생각하고 있슴을 나타냅니다. 두번째 뉴런이 발화하면 이는 네트워크가 숫자는 1이다 라고 생각하고 있음을 나타냅니다. 나머지도 마찬가지 입니다. 정확히 말하면, 우리는 출력 뉴런들을 첫번째 뉴런부터 열번째 뉴런까지 차례로 보면서 어떤 뉴런이 가장 크게 발화되었는지를 확인함으로써 숫자를 판별합니다. 만약 그 뉴런이 여섯번째 뉴런이라면, 네트워크는 입력 숫자가 6이라고 추측하는겁니다. 그리고 다른 뉴런들도 마찬가지 입니다.


여러분은 아마 왜 우리가 10개의 뉴런을 사용하는지 궁금해 하실겁니다. 어쨌거나 네트워크로 우리가 하고자 하는것은 입력 이미지에 해당하는 숫자가 어떤것인지 밝혀내는것 입니다. 그냥 겉으로 보면 이 목적을 이루기 위해서는 단지 네개의 뉴런만으로도 가능해 보입니다.  뉴런의 출력을 0에 가까운지 1에 가까운지에 따라 각 뉴런을 이진 출력으로 본다면 네개의 뉴런으로는 $2^4=16$만큼의 수를 표현할 수 있습니다. 그렇기 때문에 10까지의 숫자를 표현하는데 충분하고도 남습니다. 그렇다면 우리는 왜 10개의 뉴런을 사용해야 할까요? 비효율적이지 않을까요? 궁극적으로 타당한 이유를 대자면 경험적인 이유 때문입니다: 우리는 두개의 네트워크 디자인을 모두 시도해 볼 수 있습니다. 시도해 보니, 네개의 뉴런을 사용한 네트워크보다는 열개의 뉴런을 사용했을때 학습이 훨씬 더 잘 이루어 졌습니다. 하지만 이러한 결과는 왜 열개의 뉴런을 사용한 네트워크가 네개의 뉴런을 사용한 네트워크보다 훨씬 결과가 좋았는지에 대한 궁금증을 남기는군요. 우리가 네개의 출력 대신에 열개의 출력을 사용해야 한다는 것을 자세히 알려줄 경험적 사례가 있을까요?


왜 우리가 이것을 하는지 이해하기 위해서는, 첫번째 원리로 부터 뉴런 네트워크가 무엇을 하는지에 대해 생각해 보는것이 도움이 됩니다. 우리가 열개의 뉴런을 사용할때의 경우를 생각해 봅시다. 입력된 이미지의 숫자가 0인지 아닌지 결정하는 출력 뉴런들 중 첫번째 뉴런을 한번 봅시다. 이 뉴런은 입력층으로 부터 가져온 정보들에 가중치를 곱하여 의사결정을 내리게 됩니다. 은닉층의 뉴런들의 하는일은 뭔가요? 일단, 그냥 논의를 해보기 위해 은닉층의 첫번째 뉴런이 다음과 같은 이미지가 드러나는지 아닌지 감지한다고 가정해 봅시다.



이 이미지와 겹치는 픽셀들에 가중치를 무겁게 두고 나머지는 가볍게 둠으로써 이 이미지가 드러나는지 않는지 감지할 수 있습니다. 비슷한 방법으로 은닉층의 두번째, 세번째, 네번째 뉴런이 다음과 같은 이미지가 드러나는지 아닌지 감지한다고 해봅시다.



아마 보이시겠지만, 이 네장의 이미지를 모두 겹치면 앞에서 본 숫자 0 이미지가 됩니다.



그러므로 이 네개의 뉴런들이 모두 발화할때 우리는 이 숫자가 0이라고 말 할 수 있습니다. 당연히, 이미지가 0이라고 결정짓기 위해 사용하는 근거는 이것만 있지는 않습니다. 우리는 다른 방법으로도 0이라는 숫자를 얻어낼 수 있습니다. 하지만 최소한 이 상황에서는 우리가 입력 이미지가 0이었다고 잘 판단했다 말할 수 있겠군요.


뉴런 네트워크가 이런 식으로 작동한다고 가정하면, 네개보다 열개의 뉴런을 가지는 것이 왜 좋은지에 대한 그럴듯한 설명할 할 수 있습니다. 만약 우리가 네개의 출력을 가지고 있다면, 첫번째 출력 뉴런은 숫자의 가장 중요한 비트가 무엇인지 결정하려고 할겁니다. 그리고 저 가장 중요한 비트를 위와같은 간단한 도형과 관련짓는 쉬운 방법은 없습니다. 숫자의 부분적인 형태가 출력의 가장 중요한 비트와 큰 관련이 있을거라는 그 어떤 좋은 역사적, 경험적 이유가 있을거라고는 상상하기 힘듭니다.


이제 제가 말한 모든것들은 경험적인 것들 입니다. 그 무엇도 3층 뉴런 네트워크가 제가 설명한 방법대로 작동할 것이라고 말하지 않습니다. (은닉층의 뉴런이 숫자의 부분적 형태를 감지한다는 설명) 아마 현명한 학습 알고리즘은 우리에게 단지 네개의 뉴런만을 사용할 수 있도록 해줄 가중치를 찾을 것 입니다. 하지만 경험적으로는 제가 설명한 방법은 잘 작동합니다. 그리고 좋은 뉴런 네트워크 구조를 설계하는데 시간을 절약해 줄 것입니다.


연습

위의 삼층 네트워크에 새로운 층을 추가함으로써 숫자의 이진수 표현을 결정할 수 있는 방법이 있습니다. 새로운 층은 전에 있던 출력 층으로 부터 나온 숫자를 아래 나온것 처럼 이진수 표현법으로 변환하는 역할을 합니다. 새 출력 층에 알맞는 가중치들과 $bias$들을 찾아보세요. 첫번째 세개의 층이 세번째 층의 올바른 출력이 이루어 졌을때 그 값이 최소한 0.99가 되고 나머지는 0.01이 되는 층이라고 가정하세요.



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday