머신러닝 이미지 분류 (MobileNet 활용)

제가 요즘 머신러닝(machine learning)에 대해 공부하고 있는 데요…
재미삼아 따라해봤던 코드가 잘 작동되는 것에 감동받아서 여러분과 같이 공유하고자 합니다.

아래에 작동 결과를 보겠습니다.
카메라 앞에 여러 가지 물건이나 생물체를 가져다 놓으면 컴퓨터가 그것의 이름을 말해 줍니다. 만약 기기에 카메라가 없다면 실행되지 않습니다.

  • 웹브라우저가 카메라의 접근을 물어오면 허용해 주시기 바랍니다. (개인정보는 보호되며, 서버에 저장되지 않습니다.)
  • 모바일 기기는 CPU 성능이 좋은 것으로 접속해 주시기 바랍니다. (이미지 처리에 상당한 부하가 걸리네요. 가급적 PC 또는 노트북으로 접속바랍니다.)

프로그램 코드는 제가 짠 것이 아니구요, ml5 강좌(https://youtu.be/yNkAuWz5lnY)에 있던 것을 옮겨 온 다음, 제 서버에 맞게 조절만 했습니다.

머신러닝을 실제로 구현하기 위해서는 엄청난 양의 데이터를 미리 학습시켜 주어야 하는데요,
모든 사람이 그래야 할 필요는 없고요... 그냥 이미 구축된 데이터를 활용하면 됩니다.
위 경우에는, 복잡한 중간과정을 자바스크립트 라이브러리로 대체한 것이 가장 큰 장점이네요.
html 태그를 포함한 프로그램 소스를 아래에 공개합니다. 코드가 30 줄만으로 끝난다는 것이 더 놀랍습니다.

<div id="myContainer"></div>
<div style="display: none;">
    <script src="https://github.com/processing/p5.js/releases/download/v1.5.0/p5.min.js"></script>
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
    <script>
        let video;
        let classifier;
        let myCanvas;
        let flippedVideo;
        function preload()
        {
            classifier = ml5.imageClassifier('MobileNet', video);
        }
        function setup()
        {
            frameRate(10);
            video = createCapture(VIDEO);
            video.size(320, 240);
            video.hide();
            myCanvas = createCanvas(640, 480);
            myCanvas.parent("myContainer");
            textAlign(LEFT, CENTER);
            textSize(36);
            strokeWeight(4);
            stroke(0);
            fill(255, 255, 0);
        }
        function draw()
        {
            flippedVideo = ml5.flipImage(video);
            classifier.classify(flippedVideo, gotResult);
        }
        function gotResult(error, results)
        {
            if(error)
            {
                text(error, 20, 400);
            }
            image(flippedVideo, 0, 0, width, height);
            for (let i = 0; i < min(results.length, 2); i++)
            {
                text((i + 1) + ": " + results[i].label + " (" + (round(results[i].confidence*100)/100) + ")", 20, 400 + 40*i);
            }
        }
    </script>
</div>