Tensorflow.jsを使用したフロントエンド開発者向けの機械学習
公開: 2022-03-10機械学習は、データサイエンティストやPython開発者の領域に属しているように感じることがよくあります。 ただし、過去2年間で、JavaScriptを含むさまざまなプログラミング言語でアクセスしやすくするためにオープンソースフレームワークが作成されてきました。 この記事では、Tensorflow.jsを使用して、いくつかのサンプルプロジェクトを通じて、ブラウザーで機械学習を使用するさまざまな可能性を探ります。
機械学習とは何ですか?
コードに飛び込む前に、機械学習とは何か、およびいくつかのコアコンセプトと用語について簡単に説明しましょう。
意味
一般的な定義は、コンピューターが明示的にプログラムされていなくてもデータから学習できることです。
これを従来のプログラミングと比較すると、コンピューターにデータのパターンを識別させ、何を探すべきかを正確に指示しなくても予測を生成できるようになります。
不正検出の例を見てみましょう。 何が取引を不正にするかを知るための設定された基準はありません。 詐欺は、国、アカウント、顧客を標的に、いつでも実行される可能性があります。 これらすべてを手動で追跡することはほとんど不可能です。
ただし、長年にわたって収集された不正な費用に関する以前のデータを使用して、このデータのパターンを理解するための機械学習アルゴリズムをトレーニングして、新しいトランザクションを与えることができるモデルを生成し、不正であるかどうかを予測することができます。何を探すべきかを正確に伝えます。
コアコンセプト
次のコードサンプルを理解するには、最初にいくつかの一般的な用語を説明する必要があります。
モデル
データセットを使用して機械学習アルゴリズムをトレーニングする場合、モデルはこのトレーニングプロセスの出力です。 これは、新しいデータを入力として受け取り、予測を出力として生成する関数に少し似ています。
ラベルと機能
ラベルと機能は、トレーニングプロセスでアルゴリズムにフィードするデータに関連しています。
ラベルは、データセット内の各エントリを分類する方法と、ラベルを付ける方法を表します。 たとえば、データセットがさまざまな動物を説明するCSVファイルである場合、ラベルは「猫」、「犬」、「ヘビ」などの単語になります(各動物が何を表すかによって異なります)。
一方、機能は、データセットの各エントリの特性です。 私たちの動物の例では、「ひげ、ニャー」、「遊び心のある、吠え声」、「爬虫類、横行」などのようなものである可能性があります。
これを使用すると、機械学習アルゴリズムは、将来の予測に使用する機能とそのラベルの間の相関関係を見つけることができます。
ニューラルネットワーク
ニューラルネットワークは、人工ニューロンの層を使用して脳の働きを模倣しようとする一連の機械学習アルゴリズムです。
この記事では、それらがどのように機能するかについて詳しく説明する必要はありませんが、詳細を知りたい場合は、次の非常に優れたビデオをご覧ください。
機械学習で一般的に使用されるいくつかの用語を定義したので、JavaScriptとTensorflow.jsフレームワークを使用して何ができるかについて話しましょう。
特徴
現在、次の3つの機能を利用できます。
- 事前にトレーニングされたモデルを使用して、
- 転移学習、
- 独自のモデルを定義、実行、および使用します。
最も単純なものから始めましょう。
1.事前トレーニング済みモデルの使用
解決しようとしている問題によっては、特定のデータセットで、特定の目的のために、コードで活用およびインポートできるモデルがすでにトレーニングされている場合があります。
たとえば、画像が猫の写真であるかどうかを予測するWebサイトを構築しているとします。 人気のある画像分類モデルはMobileNetと呼ばれ、Tensorflow.jsで事前トレーニングされたモデルとして利用できます。
このためのコードは次のようになります。
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Cat detection</title> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"> </script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]"> </script> </head> <body> <img alt="cat laying down" src="cat.jpeg"/> <script> const img = document.getElementById('image'); const predictImage = async () => { console.log("Model loading..."); const model = await mobilenet.load(); console.log("Model is loaded!") const predictions = await model.classify(img); console.log('Predictions: ', predictions); } predictImage(); </script> </body> </html>
まず、HTMLのヘッドにTensorflow.jsとMobileNetモデルをインポートします。
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/1.0.1/tf.js"> </script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]"> </script>
次に、体内に、予測に使用される画像要素があります。
<img alt="cat laying down" src="cat.jpeg"/>
そして最後に、 script
タグ内に、事前にトレーニングされたMobileNetモデルをロードし、 image
タグで見つかった画像を分類するJavaScriptコードがあります。 確率スコア順に並べられた3つの予測の配列を返します(最初の要素が最良の予測です)。
const predictImage = async () => { console.log("Model loading..."); const model = await mobilenet.load(); console.log("Model is loaded!") const predictions = await model.classify(img); console.log('Predictions: ', predictions); } predictImage();
以上です! これは、Tensorflow.jsを使用してブラウザーで事前トレーニング済みモデルを使用できる方法です。
注: MobileNetモデルが他に何を分類できるかを確認したい場合は、Githubで利用可能なさまざまなクラスのリストを見つけることができます。
知っておくべき重要なことは、事前にトレーニングされたモデルをブラウザにロードするのに時間がかかる場合があるため(場合によっては最大10秒)、ユーザーに影響が及ばないようにインターフェイスをプリロードまたは調整することをお勧めします。
Tensorflow.jsをNPMモジュールとして使用する場合は、次の方法でモジュールをインポートすることで使用できます。
import * as mobilenet from '@tensorflow-models/mobilenet';
CodeSandboxでこの例を自由に試してみてください。
事前にトレーニングされたモデルの使用方法を確認したので、次に使用できる2番目の機能である転移学習を見てみましょう。
2.転移学習
転移学習は、事前にトレーニングされたモデルをカスタムトレーニングデータと組み合わせる機能です。 つまり、すべてを最初から作成しなくても、モデルの機能を活用して独自のサンプルを追加できます。
たとえば、アルゴリズムは画像分類モデルを作成するために数千の画像でトレーニングされており、独自の画像分類モデルを作成する代わりに、転送学習により、新しいカスタム画像サンプルを事前にトレーニングされたモデルと組み合わせて新しい画像分類子を作成できます。 この機能により、よりカスタマイズされた分類器を非常に高速かつ簡単に作成できます。
これがコードでどのように見えるかの例を提供するために、前の例を再利用して、新しい画像を分類できるように変更してみましょう。
注:最終結果は、ここでライブで試すことができる以下の実験です。
以下は、このセットアップの最も重要な部分のいくつかのコードサンプルですが、コード全体を確認する必要がある場合は、このCodeSandboxで見つけることができます。
Tensorflow.jsとMobileNetをインポートすることから始める必要がありますが、今回はKNN(k最近傍)分類器も追加する必要があります。
<!-- Load TensorFlow.js --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script> <!-- Load MobileNet --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet"></script> <!-- Load KNN Classifier --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/knn-classifier"></script>
分類器が必要な理由は、(MobileNetモジュールのみを使用するのではなく)これまでに見たことのないカスタムサンプルを追加するためです。したがって、KNN分類器を使用すると、すべてを組み合わせて、組み合わせたデータに対して予測を実行できます。
次に、猫の画像をvideo
タグに置き換えて、カメラフィードからの画像を使用できます。
<video autoplay width="227" height="227"></video>
最後に、いくつかのビデオサンプルを記録し、予測を開始するためのラベルとして使用するいくつかのボタンをページに追加する必要があります。
<section> <button class="button">Left</button> <button class="button">Right</button> <button class="test-predictions">Test</button> </section>
それでは、JavaScriptファイルに移動して、いくつかの重要な変数を設定することから始めましょう。
// Number of classes to classify const NUM_CLASSES = 2; // Labels for our classes const classes = ["Left", "Right"]; // Webcam Image size. Must be 227. const IMAGE_SIZE = 227; // K value for KNN const TOPK = 10; const video = document.getElementById("webcam");
この特定の例では、頭が左または右に傾いている間にWebカメラ入力を分類できるようにする必要があるため、 left
とright
のラベルが付いた2つのクラスが必要です。
227に設定された画像サイズは、ピクセル単位のビデオ要素のサイズです。 Tensorflow.jsの例に基づいて、MobileNetモデルがトレーニングされたデータの形式と一致させるには、この値を227に設定する必要があります。 新しいデータを分類できるようにするには、後者が同じ形式に適合する必要があります。
本当に大きくする必要がある場合は可能ですが、KNN分類器にデータを供給する前に、データを変換してサイズを変更する必要があります。
次に、Kの値を10に設定します。KNNアルゴリズムのK値は、新しい入力のクラスを決定するときに考慮するインスタンスの数を表すため、重要です。
この場合、値10は、いくつかの新しいデータのラベルを予測するときに、トレーニングデータから10個の最近傍を調べて、新しい入力を分類する方法を決定することを意味します。
最後に、 video
要素を取得します。 ロジックについては、モデルと分類子をロードすることから始めましょう。
async load() { const knn = knnClassifier.create(); const mobilenetModule = await mobilenet.load(); console.log("model loaded"); }
次に、ビデオフィードにアクセスしましょう。
navigator.mediaDevices .getUserMedia({ video: true, audio: false }) .then(stream => { video.srcObject = stream; video.width = IMAGE_SIZE; video.height = IMAGE_SIZE; });
その後、サンプルデータを記録するためにいくつかのボタンイベントを設定しましょう。
setupButtonEvents() { for (let i = 0; i < NUM_CLASSES; i++) { let button = document.getElementsByClassName("button")[i]; button.onmousedown = () => { this.training = i; this.recordSamples = true; }; button.onmouseup = () => (this.training = -1); } }
Webカメラ画像のサンプルを取得して再フォーマットし、MobileNetモジュールと組み合わせる関数を作成しましょう。
// Get image data from video element const image = tf.browser.fromPixels(video); let logits; // 'conv_preds' is the logits activation of MobileNet. const infer = () => this.mobilenetModule.infer(image, "conv_preds"); // Train class if one of the buttons is held down if (this.training != -1) { logits = infer(); // Add current image to classifier this.knn.addExample(logits, this.training); }
そして最後に、いくつかのWebカメラ画像を収集したら、次のコードを使用して予測をテストできます。
logits = infer(); const res = await this.knn.predictClass(logits, TOPK); const prediction = classes[res.classIndex];
そして最後に、Webカメラのデータはもう必要ないので破棄できます。
// Dispose image when done image.dispose(); if (logits != null) { logits.dispose(); }
繰り返しになりますが、完全なコードを確認したい場合は、前述のCodeSandboxで見つけることができます。
3.ブラウザでモデルをトレーニングする
最後の機能は、モデルを完全にブラウザで定義、トレーニング、および実行することです。 これを説明するために、アイリスを認識する古典的な例を作成します。
このために、オープンソースのデータセットに基づいて、アイリスをSetosa、Virginica、Versicolorの3つのカテゴリに分類できるニューラルネットワークを作成します。
始める前に、ここにライブデモへのリンクがあり、完全なコードを試してみたい場合は、ここにCodeSandboxがあります。
すべての機械学習プロジェクトの中核はデータセットです。 実行する必要のある最初のステップの1つは、このデータセットをトレーニングセットとテストセットに分割することです。
この理由は、トレーニングセットを使用してアルゴリズムをトレーニングし、テストセットを使用して予測の精度をチェックし、モデルを使用する準備ができているか、調整する必要があるかを検証するためです。
注:簡単にするために、トレーニングセットとテストセットをCodeSanboxにある2つのJSONファイルに分割しました。
トレーニングセットには130個のアイテムとテストセット14が含まれています。このデータがどのように見えるかを見ると、次のようになります。
{ "sepal_length": 5.1, "sepal_width": 3.5, "petal_length": 1.4, "petal_width": 0.2, "species": "setosa" }
私たちが見ることができるのは、がく片と花びらの長さと幅の4つの異なる特徴と、種のラベルです。
これをTensorflow.jsで使用できるようにするには、このデータをフレームワークが理解できる形式に整形する必要があります。この場合、トレーニングデータの場合、130サンプルで[130, 4]
になります。虹彩。
import * as trainingSet from "training.json"; import * as testSet from "testing.json"; const trainingData = tf.tensor2d( trainingSet.map(item => [ item.sepal_length, item.sepal_width, item.petal_length, item.petal_width ]), [130, 4] ); const testData = tf.tensor2d( testSet.map(item => [ item.sepal_length, item.sepal_width, item.petal_length, item.petal_width ]), [14, 4] );
次に、出力データも整形する必要があります。
const output = tf.tensor2d(trainingSet.map(item => [ item.species === 'setosa' ? 1 : 0, item.species === 'virginica' ? 1 : 0, item.species === 'versicolor' ? 1 : 0 ]), [130,3])
次に、データの準備ができたら、モデルの作成に進むことができます。
const model = tf.sequential(); model.add(tf.layers.dense( { inputShape: 4, activation: 'sigmoid', units: 10 } )); model.add(tf.layers.dense( { inputShape: 10, units: 3, activation: 'softmax' } ));
上記のコードサンプルでは、シーケンシャルモデルをインスタンス化することから始め、入力レイヤーと出力レイヤーを追加します。
内部で使用されていることがわかるパラメーター( inputShape
、 activation
、 units
)は、作成しているモデル、使用されているデータのタイプなどによって異なる可能性があるため、この投稿の範囲外です。
モデルの準備ができたら、データを使用してモデルをトレーニングできます。
async function train_data(){ for(let i=0;i<15;i++){ const res = await model.fit(trainingData, outputData,{epochs: 40}); } } async function main() { await train_data(); model.predict(testSet).print(); }
これがうまく機能する場合は、テストデータをカスタムユーザー入力に置き換え始めることができます。
main関数を呼び出すと、予測の出力は次の3つのオプションのいずれかのようになります。
[1,0,0] // Setosa [0,1,0] // Virginica [0,0,1] // Versicolor
予測は、3つのクラスの1つに属するデータの確率を表す3つの数値の配列を返します。 1に最も近い数が最も高い予測です。
たとえば、分類の出力が[0.0002, 0.9494, 0.0503]
の場合、配列の2番目の要素が最も高いため、モデルは新しい入力がVirginicaである可能性が高いと予測しました。
Tensorflow.jsの単純なニューラルネットワークは以上です。
アイリスの小さなデータセットについてのみ説明しましたが、より大きなデータセットに移動したり、画像を操作したりする場合、手順は同じです。
- データの収集;
- トレーニングセットとテストセットの分割。
- Tensorflow.jsがデータを理解できるようにデータを再フォーマットします。
- アルゴリズムの選択;
- データのフィッティング;
- 予測。
作成したモデルを保存して別のアプリケーションにロードし、新しいデータを予測できるようにする場合は、次の行を使用して行うことができます。
await model.save('file:///path/to/my-model'); // in Node.js
注:モデルを保存する方法の詳細については、このリソースを参照してください。
制限
それでおしまい! Tensorflow.jsを使用して現在利用できる3つの主要な機能について説明しました。
終了する前に、フロントエンドで機械学習を使用する際の制限について簡単に説明することが重要だと思います。
1.パフォーマンス
事前にトレーニングされたモデルを外部ソースからインポートすると、アプリケーションのパフォーマンスに影響を与える可能性があります。 たとえば、一部のオブジェクト検出モデルは10MBを超えるため、Webサイトの速度が大幅に低下します。 ユーザーエクスペリエンスについて考え、アセットの読み込みを最適化して、知覚されるパフォーマンスを向上させてください。
2.入力データの品質
モデルを最初から作成する場合は、独自のデータを収集するか、オープンソースのデータセットを見つける必要があります。
あらゆる種類のデータ処理を実行したり、さまざまなアルゴリズムを試す前に、入力データの品質を確認してください。 たとえば、テキストの感情を認識する感情分析モデルを構築しようとしている場合は、モデルのトレーニングに使用しているデータが正確で多様であることを確認してください。 使用するデータの品質が低い場合、トレーニングの出力は役に立たなくなります。
3.責任
オープンソースの事前トレーニング済みモデルを使用すると、非常に高速で簡単になります。 ただし、それは、それがどのように生成されたか、データセットが何で作成されたか、またはどのアルゴリズムが使用されたかさえも常に知っているとは限らないことも意味します。 一部のモデルは「ブラックボックス」と呼ばれます。これは、特定の出力をどのように予測したかが実際にはわからないことを意味します。
構築しようとしているものによっては、これが問題になる可能性があります。 たとえば、機械学習モデルを使用してスキャン画像に基づいて誰かが癌にかかっている確率を検出する場合、偽陰性の場合(モデルは実際に癌にかかったときに癌にかかっていないと予測しました)、いくつかの実際の法的責任である可能性があり、モデルが特定の予測を行った理由を説明できる必要があります。
概要
結論として、JavaScriptとTensorflow.jsのようなフレームワークを使用することは、機械学習を開始してさらに学ぶための優れた方法です。 本番環境に対応したアプリケーションはおそらくPythonのような言語で構築する必要がありますが、JavaScriptを使用すると、開発者はさまざまな機能を試して基本的な概念をよりよく理解してから、最終的に別の機能の学習に時間を費やすことができます。言語。
このチュートリアルでは、Tensorflow.jsを使用して可能なことのみを取り上げましたが、他のライブラリやツールのエコシステムは成長しています。 より指定されたフレームワークも利用可能であり、Magenta.jsを使用した音楽など、他のドメインでの機械学習の使用や、guess.jsを使用したWebサイトでのユーザーナビゲーションの予測を行うことができます。
ツールのパフォーマンスが向上するにつれて、JavaScriptで機械学習対応のアプリケーションを構築する可能性はますますエキサイティングになる可能性があります。コミュニティがツールにアクセスできるようにするために努力しているため、今がツールについて学ぶ良い機会です。
その他のリソース
詳細については、次のリソースをご覧ください。
その他のフレームワークとツール
- ml5.js
- ml.js
- brain.js
- Keras.js
- PoseNet
- Tensorflowプレイグラウンド
例、モデル、データセット
- Tensorflow.jsモデル
- Tensorflow.jsの例
- データセット
インスピレーション
- 教えられる機械
- AI実験
- AIJS.rocks
- 作成可能性
読んでくれてありがとう!