CNN 을 이용하여 얼굴보고 남녀 구분하기




안녕하세요? 요즘 딥러닝을 이용하여 이것저것 시도해 보고 있습니다.

다들 해보셨을 MNIST 는 해 보셨을 겁니다.


그런데 하고나면, '그래 잘 되는구나' 라는 생각은 드는데,

정말 내가 원하는 문제를 풀 수 있는지 의구심이 듭니다.


데이터 세트도 제공해 주고, NN도 정해져 있으니까요.





사진을 보고 남자와 여자를 구분해 보자



그래서 저는 직접 데이터 수집부터 트레이닝까지 다 해 보고 싶어졌습니다.

그렇게 밑바닥부터 다른 도움없이 스스로 해냈을때, 비로서 뭔가 할 수 있을 것 같았습니다.



목표는 "남자와 여자를 판별하는 봇 만들기' 로 정했습니다.

그런데 시작과 동시에 커다란 장벽에 부딪혔습니다.


제가 어디서 듣기론 Classifier 문제에서 데이터는 클래스당 최소 1,000 개 내외는 나와야 한다고 했습니다.

그럼, 안경 쓴 사람 + 안 쓴 사람 = 2,000 장의 이미지를 구해야 합니다.



그래서 생각해낸 방법이 구글링 하기 입니다.





삽질의 시작



일단, 저는 매우 게으릅니다. 그래서 dataset, face 등으로 검색을 시도했습니다.

누군가 잘 만들어 정리해 놓은 데이터 세트가 필요했거든요. :)


생각해보면 모순된 이야기네요. 직접 해 보고 싶다면서 데이터세트를 구하는 노가다는 직접 하기 싫었거든요 ㅎ.


그렇게 열심히 검색해서 아래와 같은 이미지들을 주워 모았습니다.





이렇게 남자, 여자 각각 500 여장씩 사진을 모았습니다.

네, 1,000 장은 무리입니다. 일단 사진 모으는건 둘째 치고 라벨링 하는것 자체도 엄청 힘듧니다.


아시다시피 제가 하려는건 지도학습이므로 먼저 제가 정답(남/녀)을 구해 놓아야 하니까요.



그래서 생각해낸 방법이 구글링 하기 입니다.





삽질의 서막



먼저 제가 학습하려는 형태는 이러합니다.

각 사진을 '남자' 와 '여자' 폴더에 각각 저장해 놓습니다.

이후 폴더명을 변경합니다. '남자' 는 '0', '여자' 는 '1' 로 말입니다.


눈치 채셨겠지만, softmax 이후에 tf.argmax() 를 호출하면 index 가 나옵니다.

2개로 분류하는 문제에서는 0과 1 둘중 하나로 나오겠지요.

그렇기 때문에 폴더명을 애초에 라벨로 삼았습니다. 0 과 1 이라는 폴더명으로요.


물론 Train 용과 Eval 용으로 각각 준비합니다. 

구조를 대강 그려보자면,,


- Train

   - 0

   - 1

-Eval

  - 0

  - 1


이런 형태입니다.

Train 과 Eval 에 들어있는 사진들은 당연히 중복되지 않고, 고유한 사진들입니다.



자 이제 NN(Graph) 을 구성해 봅시다.

MNIST 할때 구글에서 받았던 Expert 코드를 수정하기로 합니다.

NN 구성도 대충 따라합니다.



자!! 이제 학습시켜 봅시다!!



결과는.........참담합니다.


Training 결과 Accuracy 가 90 이 넘었는데, Eval 데이터로 돌려보면 56% 정도가 나옵니다.

읭?????

찍어도 확률이 50% 인데 56% 라고????






원인이 뭘까?



원인은 '딥러닝은 사기다' 입니다.

네 사깁니다. MNIST 는 짜고치는 각본입니다.

NN도 MNIST 용으로 철저히 계산된 네트워크이고, 데이터도 거기에 맞게 들어 있는 것입니다.


라고 구글 음모론을 만들기 시작했습니다.

그 당시에 그랬다는 겁니다 :)



그러나..

그럴리가 없잖아..... ㅠㅠ



문제의 원인을 찾기 시작했습니다.

그리고 이런 생각에 다달았습니다.


"컴퓨터는 멍청하다. 딥러닝은 마술이 아니다. 사람이 못하면 컴퓨터도 못한다."


저는 트레이닝 데이터에 의심을 갖기 시작했습니다.

자 생각해 보세요.


어떤 사진이 두 부류로 나뉘어져 있습니다.

그리고 친구에게 보여줍니다.

물어봅시다.


"철수야. 내가 어떤 기준으로 사진을 나누어 놓은것 같니?"


똑똑한 친구는 "응, 남자와 여자로 나눈건가?" 라고 하겠죠.

안타깝지만 철수는 그렇게 똑똑하지 않습니다.


"크기대로 나눈거야? 동양인과 서양인? 노인과 젊은이?"

라고 철수가 말합니다.



이쯤에서 다시 생각해보죠.

Classification 문제의 동작 원리는 수많은 사진을 반복 학습하면서,

그 분류 기준을 컴퓨터가 유추해 내는 것 입니다.



사진 두 장이 있다고 가정해보죠.

두 사진을 다른점이 너무나 많습니다.



어떤 기준같나요?

남자와 여자인가요?


아닙니다. 너무나 많습니다. 사실 모든게 다 다릅니다.

'남자와 여자' 도 맞는 이야긴데, '실내와 야외', '빨간옷과 줄무늬옷', '수염이 있고 없고' 등등등...


이런 상황에서 컴퓨터가 두 부류의 사진만 보고 분류 기준(남자와 여자)를 유추할 수 있으려면 어떻게 해야 할까요?

네 맞습니다. 엄청나게 많은 데이터가 있으면 됩니다.

수천장의 사진들이 '남자와 여자' 라는 차이를 제외하고는 나머지 공통점이 하나도 없으면 됩니다.



그러면, 문제가 트레이닝 데이터가 적었기 때문일까요?

여기서 한발 더 나아가 생각했습니다. 그리고 그 결론은


'불필요한 정보는 방해만 될 뿐이다.'

라는 것입니다.


제가 하려는건 사람의 얼굴 정보에 따른 분류입니다.

머리 말이에요. 머리. 눈, 코, 입, 귀, 머리카락을 포함한 머리요.


나머지 배경들은 방해만 될 뿐입니다.




결론은 "학습 데이터가 매우 중요하다."







올바른 데이터를 수집하자



평소 귀찮은 일을 싫어하는 저는, 이번만큼은 성실히 데이터를 모아보기로 했습니다.

물론 좀 편한 방법으로요.


제가 생각한 수집 시나리오입니다.



1. 이미지 구글링을 합니다.

 - 여기에 팁이 있습니다. 단지 얼굴만 필요하다면 구글 이미지 검색에서 '얼굴' 로 검색하면 되겠지요.

만약 야외에서 촬영한 얼굴 사진이 필요하면 어떻게 할까요?


"야외 얼굴"로 검색하면 이렇게 나옵니다.