CNN으로 Captcha 뚫기

Sim Captcha

captcha sms 사용자가 사람인지 컴퓨터인지 가려내기 위해 고안된 방법이다. 시간이 지나면서 위에 보이는 것과 같이 간단한 것부터 사람마저 풀기 힘든 captcha 까지 여러 종류가 생겼다.

하지만 이번에는 매우 간단한 simple captcha를 CNN을 사용해서 뚫어보자. mnist에 지쳤다면, 너무나 잘 제공된 데이터 때문에 허무하다면 직접 해보자. 내가 사용할 데이터는 위의 보이는 것처럼 간단한 captcha 로 글자가 아닌 숫자를 사용했다. 사실 너무 간단한 숫자라서 MNIST보다 난이도도 떨어진다. 그래도 일단 해본다.

Process

아쉽게도 캡챠 데이터는 쉽게 얻을 수 있는 게 아니다. 라벨이 된 데이터는 당연히 없고 이미지 조차 찾기 힘들다. Scratch부터 시작해야 한다. 다음의 과정을 거쳐 캡챠를 학습해보자.

  1. 이미지 얻기
  2. 라벨링하기
    1. 한 글자씩 쪼개어 라벨링 후 따로 저장
  3. 학습하기

먼저 파이썬을 통해 500개의 캡차 이미지를 받았다. 4글자로 이루어진 매우 쉬운 데이터이다. 500개의 이미지를 사용한 이유는 라벨링을 직접 해야하기 때문이다.

다음 한글자씩 쪼개서 라벨링 후 저장한다. 아래는 라벨링을 하는 과정, 6을 입력하는 6으로 라벨이 되고 두번째 그림처럼 저장이 된다. 이렇게 500개의 이미지를 직접 라벨링한다.. 모든 것을 파이썬으로 작업했기 때문에 그나마 빠른 라벨링이 가능했다.

다음 학습을 하면 되는데 위의 그림에서 보듯이 grayscale 이미지이고 매우 단순한 데이터라서 lenet을 간단히 모방해 학습을 했다. 데이터가 매우 간단해서 그런지 15 epoch으로도 거의 1에 가까운 정확도를 보이고 오버피팅도 일어나지 않는다. 사실 이건 SVM 같은 statistical learning으로도 문제 없는 데이터인 듯 하다.

마지막으로 캡챠 이미지로 분류를 해보았다. 어려운 건 테스트 자체가 아니라 각각의 숫자를 학습시키게 하는 것이다. 이 부분은 OpenCV에 매우 익숙해져야할 부분이다. 결과는 val_acc가 1이라 틀리면 안되는 그런 상황이다. CNN 자체를 만드는 것은 이미지를 수집하고 라벨링하는 것에 비하면 매우 쉬운 과정이었던 거 같다.

참조

DL4CV – Adrian