画像認識AIをTeachable Machineで自作する【野菜ジュース分類】

今回はTeachable Machineというものを使って、画像の分類モデルを作っていきたい。人工知能のモデルとか聞くとなんか難しいイメージあるけど、これを使えばかなり簡単にできてしまう。

いくつか作ることのできるモデルはあるけど、今回は画像分類のモデルを作っていきたい。使う画像は手頃なのがなくて野菜ジュースになってしまったよ。

Teachable Machineとは

Teachable Machine

Teachable Machineは、機械学習モデルを作成できるサービス。しかもWeb上で使うことができるからいちいち機械学習する環境を自分のパソコンに作って・・・とかやる必要はない。機械学習モデルの作成って結構しんどいイメージあるけど、ブラウザあれば試すことができるのはいいね。

画像・音声・ポーズに対応

Teachable Machineを使ってどんなものが作れるのかというと、画像や音声・ポーズを分類できるようなモデル。

画像を学習させたら、そのデータに基づいた画像の分類をしてくれるモデル、音声なら音声ポーズならポーズということですね。ポーズってなんだ?って感じだけど、みるか限り立っているか座っているかなどを判定できるモデルなんかを作ることができそう。データ次第だろうけど。

使い方

使い方は作りたいモデルに基づいて、データをアップロードしてトレーニングしていくっていう感じだね。

例えば犬と猫を判別したいモデルを作りたいなら犬と猫の画像を用意してトレーニングさせればOK。しかも良いのがこの作ったものをエクスポートすることができるところ。

サイトやアプリで作ったものを使うことができるのは素敵すぎる。そして気になる一文がありますね。

オンラインで無料でホストすることもできます

無料でホストすることができるっていうのはどういうことだ。

公開したモデルはどのような人が使用できますか?

モデルをオンラインで公開する場合、Teachable Machine では、モデルを無料でホストできる URL が生成されます。このリンクは誰とでも共有できます。リンクを共有した人は誰でも、あなたのモデルを自分のプロジェクトで使用できます。

これ凄いですね。自分でサーバーなんかを用意しないで生成されたURLを使えば、アプリやWebサイトなんかで使えてしまうやつ。んー、便利だな、何か良い感じのものを作ってしまえば呼び出すだけで使えてしまうのか。

Teachable Machineを使って画像の分類モデルを作成する

なんとなくできることはわかったからこのTeachable Machineを使ってモデルを作っていきたい。画像・音声・ポーズの3つの種類から選ぶことができるけど、今回は画像分類のモデルを作るとしよう。

分類する画像なんだけど、分類するのは「野菜生活100」「朝のフルーツこれ1本」でいいかな。

これのどっちかを判定するモデルを作る。(良い感じの分類したいものがあまりなかったんや、まあいいだろうこれで。。)

野菜ジュースを学習させる

学習させるためにそれぞれの写真を撮りまくる。iPhoneで連写しまくった結果ライブラリが野菜ジュースで埋め尽くされました。

こんな感じのことを「朝のフルーツこれ1本」でもやって、TechableMachineで学習させよう。

そしたら「モデルをトレーニングする」をクリック

画像の枚数にもよるんだろうけど、速攻で終わりました。そしたらモデルが造られるからパソコンのカメラを使って「野菜生活100」「朝のフルーツこれ一本」の画像を映してみる。さあどうだろうか。

朝のフルーツこれ1本の方は良い感じに認識してくれていますね。野菜生活100も割といけてるけど、裏側とかにするとちょっと混乱しているな。(どっちも裏側はそんな画像撮っていないしなあ・・・)画像の枚数そこまで読み込ませていないから精度はまあこんなもんか、でもこれだけでこんなことがこの精度できてしまうのが凄い。

ちなみにこれはWebカメラでやったけど、ファイルを使ってでもどんな感じか確認できるね。

モデルをエクスポートする

今野菜ジュースを判別するモデルが作られたのだけど、これはダウンロードすることができてしまう。モデルを使用するコードスニペットも掲載されていて素晴らしい。

Keras.h5モデルに変換してくれたりもしてくれるようだから、そっち系でやりたい人はTensorflowを選ぶといいね。

ダウンロードしたモデルを使う

ブラウザ上で野菜ジュースを分類できるのは分かったから、次はコード上で使ってみたい。やっぱりダウンロードできるのなら使わないとな。

とりあえず適当に試すだけのコードをサンプルをちょっといじってやってみる。使い方はGithubに書いてあるからちょいちょい見つつやってみよう。とりあえず動けばいいや。

<div>Teachable Machine Image Model</div>
 <input type="file" id="files" multiple>
<button type="button" onclick="init()">Start</button>
<div id="webcam-container"></div>
<div id="label-container"></div>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8/dist/teachablemachine-image.min.js"></script>
<script type="text/javascript">
    // More API functions here:
    // https://github.com/googlecreativelab/teachablemachine-community/tree/master/libraries/image

    // the link to your model provided by Teachable Machine export panel
    let model, webcam, labelContainer, maxPredictions;

    // Load the image model and setup the webcam
    async function init() {

        const uploaded = document.getElementById('files');
        // 試すだけだしとりあえずmodel・weights・metadataの順序でアップロードする
        model = await tmImage.loadFromFiles(uploaded.files[0], uploaded.files[1], uploaded.files[2])

        maxPredictions = model.getTotalClasses();

        // Convenience function to setup a webcam
        const flip = true; // whether to flip the webcam
        webcam = new tmImage.Webcam(200, 200, flip); // width, height, flip
        await webcam.setup(); // request access to the webcam
        await webcam.play();
        window.requestAnimationFrame(loop);

        // append elements to the DOM
        document.getElementById("webcam-container").appendChild(webcam.canvas);
        labelContainer = document.getElementById("label-container");
        for (let i = 0; i < maxPredictions; i++) { // and class labels
            labelContainer.appendChild(document.createElement("div"));
        }
    }

    async function loop() {
        webcam.update(); // update the webcam frame
        await predict();
        window.requestAnimationFrame(loop);
    }

    // run the webcam image through the image model
    async function predict() {
        // predict can take in an image, video or canvas html element
        const prediction = await model.predict(webcam.canvas);
        for (let i = 0; i < maxPredictions; i++) {
            const classPrediction =
                prediction[i].className + ": " + prediction[i].probability.toFixed(2);
            labelContainer.childNodes[i].innerHTML = classPrediction;
        }
    }
</script>

ダウンロードしたファイルを使って試してやろう。

ちゃんと使えていますね。これできるなら自分でアプリケーション作ってその中に組み込むことも容易そう。それと結構適当に作ったモデルだからちゃんとやるときには本気で学習させた方がいいかもしれんな。

アップロードしたモデルを使う

アップロードして使うこともできるから、アップロードして共有可能なリンクを取得してみる。

アップロードしたら共有可能なリンクを使って、作成したモデルを使うことができるから使ってみる。これは試すだけならほとんどサンプルのコードコピペでいけますね。HTMLファイル作って、共有可能なリンクを取得したものに変更すればOK。

<div>Teachable Machine Image Model</div>
<button type="button" onclick="init()">Start</button>
<div id="webcam-container"></div>
<div id="label-container"></div>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8/dist/teachablemachine-image.min.js"></script>
<script type="text/javascript">
    // More API functions here:
    // https://github.com/googlecreativelab/teachablemachine-community/tree/master/libraries/image

    // the link to your model provided by Teachable Machine export panel
    const URL = "共有可能なリンク";

    let model, webcam, labelContainer, maxPredictions;

    // Load the image model and setup the webcam
    async function init() {
        const modelURL = URL + "model.json";
        const metadataURL = URL + "metadata.json";

        // load the model and metadata
        // Refer to tmImage.loadFromFiles() in the API to support files from a file picker
        // or files from your local hard drive
        // Note: the pose library adds "tmImage" object to your window (window.tmImage)
        model = await tmImage.load(modelURL, metadataURL);
        maxPredictions = model.getTotalClasses();

        // Convenience function to setup a webcam
        const flip = true; // whether to flip the webcam
        webcam = new tmImage.Webcam(200, 200, flip); // width, height, flip
        await webcam.setup(); // request access to the webcam
        await webcam.play();
        window.requestAnimationFrame(loop);

        // append elements to the DOM
        document.getElementById("webcam-container").appendChild(webcam.canvas);
        labelContainer = document.getElementById("label-container");
        for (let i = 0; i < maxPredictions; i++) { // and class labels
            labelContainer.appendChild(document.createElement("div"));
        }
    }

    async function loop() {
        webcam.update(); // update the webcam frame
        await predict();
        window.requestAnimationFrame(loop);
    }

    // run the webcam image through the image model
    async function predict() {
        // predict can take in an image, video or canvas html element
        const prediction = await model.predict(webcam.canvas);
        for (let i = 0; i < maxPredictions; i++) {
            const classPrediction =
                prediction[i].className + ": " + prediction[i].probability.toFixed(2);
            labelContainer.childNodes[i].innerHTML = classPrediction;
        }
    }
</script>

これで試してみるとこんな感じでStartボタン押すとカメラ起動して判別してくれますね。

やっぱり朝のフルーツこれ1本の方が精度高いな。こっちの方が学習させた画像多かったしな関係あるかもなあ。雑に適当に写真連写してやっただけだから、もうちょっと枚数多くしてやればよかったな。

アップロードしたモデルは消すことはできないようだ

アップロードした野菜ジュース分類するモデル非公開や削除できないのかなあ?と思って見てみたけど、どうやらできないようですね。

まとめ

ちょっと試してみたけど、Teachable Machineかなり簡単にモデル作ることができてしまえて凄いですね。ちなみに今回は野菜ジュース2つで画像の分類をやってみたけど、これは別に3つ以上もできる。

組み合わせ次第で色んな分類モデルを作ることができそうですよね。機械学習のこと全然わからなくてもこれで作ってしまって、それを使うっていうことができてしまうんだなあ・・・っていうところ。簡単にできるから、サクッと何か作りたい時なんかに便利だね。