方法によってNodejsとPuppeteerステップでML 5を使う方法


この記事では、ML 5とNODEJSを使って簡単なモデルを訓練し、保存します.
ML5 は非常に使いやすいですし、舞台裏では、高レベルの機械学習ライブラリですTensorFlow JS .
ML 5の1つの制限は、ブラウザ内で使用するように開発されたことです.ドキュメントのML 5によると、最終的にネイティブにNodeJSをサポートしますが、この記事を書く瞬間に、ML 5は実行するブラウザを必要とします.
それはとても使いやすいので、パイプラインでもnodejsスクリプトでも使いたいかもしれません.
ありがたいことに、我々はpuppeteer その制限を克服するために.
Peopeteerを知らない人のために、それはプログラムによってnodejsを使って制御されることができるクロムに基づくヘッドレスのないブラウザです.
我々がすることは、ML 5スクリプトで単純なHTMLページをつくって、それからPutpeteerを呼び出してそれを走らせることです.
本稿では画像分類モデルを訓練する.通常のML 5スクリプトとしてブラウザを使って開発します.それから、我々はちょうどPlpeteTeerでそのページを開くノードスクリプトを作成する必要があります、それはML 5スクリプトが完了するまで待ちます、そして、それは出力をダウンロードします.
このアプローチの他に、それがまだ若干の制限をするかもしれない非常に単純です.例えば、多くのクラスと多くのトレーニングサンプルがあるならば、ブラウザーでロードされることができるイメージの数は、有限です.
また、我々が訓練するモデルはMobileNetに基づいています.

ML 5スクリプト


使用例transfer learning , 私たちは2種類のスケートボードを区別するために分類モデルを訓練します.

私がここで使用しているモードを訓練するためのJavaScriptコードは、大いに幻想的に基づいています.

セットアップ


まず、プロジェクトを初期化します
mkdir myproject
cd my project
npm init
走るときnpm init 我々はいくつかの簡単な質問をするでしょう.何を変更する必要がある場合は、常に編集することができますあなたがいっぱいについてあまり心配しないでくださいpackage.json .
では、使用する依存関係のカップルをインストールしましょう.最初のものはpuppeteer , 我々のヘッドレスブラウザと2番目の1つですserve , 非常に単純なHTTPサーバ.我々は、PitpeteerによってロードされるHTMLファイルを提供するためにそれを使用します.
npm install puppeteer
npm install serve
今、我々はモデルを訓練するためにスクリプトを保持するHTMLファイルを作成するつもりです.
mkdir public
cd public
touch public/index.html
ファイルを編集するpublic/index.html コードを追加する
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Getting Started with ml5.js</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://unpkg.com/[email protected]/dist/ml5.min.js"></script>
  </head>
  <body>
    <h1>Hello ml5</h1>
    <script>
      /* We will add the code to train our model here */
    </script>
  </body>
</html>
さあ、サーバーを動かして検証しましょう
./node_modules/serve/bin/serve.js ./public/
ブラウザを開きますhttp://localhost:5000 そして、あなたはテキストML 5を見るべきです.
また、スクリプトのタグで属性' src 'を使用してスクリプトをインポートすることもできます
<head>
...
...
<script src="script.js"></script>
...
</head>
この例では、HTMLで画像をプリロードします.画像はすぐ後に行く<body><script> . より現実的な環境ではinclude the images dynamically .
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Getting Started with ml5.js</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://unpkg.com/[email protected]/dist/ml5.min.js"></script>
</head>
<body>
  <!-- images to train the classifier -->
  <img src="./longboard1.jpg" id="longboard1" />
  <img src="./longboard2.jpg" id="longboard2" />
  <img src="./longboard3.jpg" id="longboard3" />
  <img src="./longboard4.jpg" id="longboard4" />
  <img src="./longboard5.jpg" id="longboard5" />
  <img src="./longboard6.jpg" id="longboard6" />

  <img src="./skateboard1.jpg" id="skateboard1" />
  <img src="./skateboard2.jpg" id="skateboard2" />
  <img src="./skateboard3.jpg" id="skateboard3" />
  <img src="./skateboard4.jpg" id="skateboard4" />
  <img src="./skateboard5.jpg" id="skateboard5" />
  <img src="./skateboard6.jpg" id="skateboard6" />

  <!-- images to test -->
  <img src="./d.jpg" id="longboard" />
  <img src="./skateboard.jpg" id="skateboard" />
  <script>
     /* We will add the code to train our model here */
  </script>
</body>
</html>
今、我々は、CADのロングボード分類器を訓練するために使用するコードを記述する必要があります.以下の手順は次のとおりです.
  • 事前に訓練されたモデル(MobileNet)から分類器を取得します.
  • 画像をクラシファイアに追加します.
  • クラスを新しいクラスで処理します.
  • 訓練されたモデルをダウンロードしてください.
  • 下にコードがあります.それはかなりコメントされます、しかし、あなたがより多くの情報を必要とするならば、あなたはml5.featureExtractor documentation .
    <<!DOCTYPE html>
    <html lang="en">
      <head>
        <title>Getting Started with ml5.js</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script src="https://unpkg.com/[email protected]/dist/ml5.min.js"></script>
      </head>
    
      <body>
        <!-- images to train the classifier -->
        <img src="./longboard1.jpg" id="longboard1" />
        <img src="./longboard2.jpg" id="longboard2" />
        <img src="./longboard3.jpg" id="longboard3" />
        <img src="./longboard4.jpg" id="longboard4" />
        <img src="./longboard5.jpg" id="longboard5" />
        <img src="./longboard6.jpg" id="longboard6" />
    
        <img src="./skateboard1.jpg" id="skateboard1" />
        <img src="./skateboard2.jpg" id="skateboard2" />
        <img src="./skateboard3.jpg" id="skateboard3" />
        <img src="./skateboard4.jpg" id="skateboard4" />
        <img src="./skateboard5.jpg" id="skateboard5" />
        <img src="./skateboard6.jpg" id="skateboard6" />
    
        <img src="./longboard.jpg" id="longboard" />
        <img src="./skateboard.jpg" id="skateboard" />
        <script>
          let classifier
    
          const featureExtractor = ml5.featureExtractor("MobileNet", modelLoaded)
    
          // Once the model is loaded
          function modelLoaded() {
            console.log("Model Loaded!")
    
            classifier = featureExtractor.classification()
    
            // Retrain the network. You can use a for loop too :)
            classifier.addImage(document.getElementById("longboard1"), "longboard")
            classifier.addImage(document.getElementById("longboard2"), "longboard")
            classifier.addImage(document.getElementById("longboard3"), "longboard")
            classifier.addImage(document.getElementById("longboard4"), "longboard")
            classifier.addImage(document.getElementById("longboard5"), "longboard")
            classifier.addImage(document.getElementById("longboard6"), "longboard")
    
            classifier.addImage(
              document.getElementById("skateboard1"),
              "skateboard"
            )
            classifier.addImage(
              document.getElementById("skateboard2"),
              "skateboard"
            )
            classifier.addImage(
              document.getElementById("skateboard3"),
              "skateboard"
            )
            classifier.addImage(
              document.getElementById("skateboard4"),
              "skateboard"
            )
            classifier.addImage(
              document.getElementById("skateboard5"),
              "skateboard"
            )
    
            //addImage accepts a third argument that is a callback.
            classifier.addImage(
              document.getElementById("skateboard6"),
              "skateboard",
              imagesLoaded
            )
          }
    
          // Function that will be called once the images are loaded
          // It trains the model with the new categories
          function imagesLoaded() {
            console.log("do train", classifier.hasAnyTrainedClass)
    
            // train argument is a callback that has as argument the current lossValue.
            // When lossValue is null, it means the training is finished
            classifier.train(lossValue => {
              console.log("Loss is", lossValue)
              if (lossValue == null) {
                trainFinished()
              }
            })
          }
    
          // Called once the classifier is trained with the new classes
          function trainFinished() {
            // Get a prediction for that image
            console.log("train finished")
    
            // Examples to test the classifier
            // Examples to test the classifier
            classifier.classify(
              document.getElementById("longboard"),
              (err, result) => {
                console.log("is longboard?", result, result[0].label) // Should output 'longboard'
              }
            )
            classifier.classify(
              document.getElementById("skateboard"),
              (err, result) => {
                console.log("is skateboard?", result, result[0].label) // Should output 'skateboard'
              }
            )
            // Saves two files model.json and model.weights.bin
            classifier.save()
            // This is the signal to tell puppeteer we are done with the
            done = document.getElementById("done").style.display = "block"
          }
        </script>
        <p id="done" style="display: none;">Done!</p>
      </body>
    </html>
    
    今までやってきたことは、普通のML 5を使っていることとかなり似ています.今、それは魔法のための時間です.

    NODEJSスクリプト


    スクリプトは非常に簡単ですが、それは私たちのローカルサーバーのページに移動し、ファイル(私たちのモデル)をダウンロードすることができますし、モデルは、HTMLでid“done”を持つ要素を表示することによって署名されて訓練されるまで待ちます.
    //index.js
    const puppeteer = require("puppeteer")
    
    ;(async () => {
      const browser = await puppeteer.launch()
      const page = await browser.newPage()
    
      // Navigate to the page that trains the model
      await page.goto("http://localhost:5000")
    
      // if you want to trigger some function in the page use evaluate
      console.log(await page.evaluate("ml5.version")) // prints "0.5.0"
    
      // Display browser console messages on screen
      page.on("console", msg => console.log(">", msg.text()))
    
      // This allows to save the model when classifier.save() is called.
      // downloadPath is the folder in which the model will be saved.
      await page._client.send("Page.setDownloadBehavior", {
        behavior: "allow",
        downloadPath: "./",
      })
    
      //Wait till element with id="done" is visible
      //By default puppeteer will wait 30s and then throw error. `timeout = 0` disables the timeout.
      await page.waitForSelector("#done", { visible: true, timeout: 0 })
    
      console.log("DONE!")
      browser.close()
    })()
    
    スクリプトを実行する
    node index.js
    
    あなたが走る必要があることに注意することは重要ですserve ノードスクリプトを実行している間、ポート5000で.
    すべてがうまくいくならば、あなたは「done !」というテキストを見るべきですつの新しいファイルmodel.json and model.weights.bin .
    The source code mentioned in this article is available in this github repository

    ラッピング


    我々は、ML 5を使用して転送学習を使用して画像の分類モデルを訓練したし、ノードのスクリプトを使用して、我々はこのタスクを実行することができましたが、いくつかの行のコードでは、素晴らしいです!