JavaScript for TensorFlow.JS

← Deep Learning Lab 目次へ戻る



1. はじめに

1.1. ブラウザでTensorFlow.JSが動くようにする

ブラウザ(Google Chromeの最新版を推奨)でTensorFlow.JSが動くようにするには、下記のHTMLファイルを作成し、それと同じフォルダに置いた script.js というJavaScriptを書いたファイルにJaveScriptでコードを記述することで行う。実行結果は「開発者ツール(inspect)」のコンソール画面に表示される。

<!DOCTYPE html>
<html>
<head>
  <title>TensorFlow.js Tutorial</title>
    <!-- Import TensorFlow.js -->
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.js"></script>
    <!-- Import tfjs-vis -->
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
    <!-- Import the main script file -->
    <script type="text/javascript" src="script.js"></script>
</head>
<body></body>
</html>

1.2. Deep Learningで頻出するJavaScriptのおさらい

1.2.1. 変数と宣言(var, let, const)

var : 通常の変数宣言(上書き可能)
let : ifやforといったブロックスコープ内でのみ有効(上書き可能)
const : ifやforといったブロックスコープ内でのみ有効(上書き不可能)

 

1.2.2. 非同期処理(async, await)

asyncは指定された処理を非同期で行うことを宣言し、awaitはasyncで指定された処理が実行結果を返す(コールバック)するまで待つことを宣言する。

 

1.2.3. データのマッピング(map)

JavaScriptのmapは配列データに使うメソッドであり、配列データの各要素1つずつに対し指定されたコールバック処理を実行し、その結果を新しい配列として返すことが出来ます。なお、mapと類似するメソッドにfilterとreduceがあるが、ここでは割愛する。

const items = [1,2,3,4,5];
 
const result = items.map(function(value) {
 
    //配列の各要素を2倍
    return value*2;
 
});
 
console.log(result);

// resultには下記の配列が格納される
// [2, 4, 6, 8, 10]

 
さらに、インデックス(配列の先頭要素(0番)から何番目か)の番号も使って下記のようにオブジェクトを要素に持たせることもでき、TensorFlow.JSでの処理に頻出する。

const items = [1,2,3,4,5];
 
const result = items.map(function(value, index) {
 
    //valueとindexを含むオブジェクトを要素とする配列を生成
    return {value, index};
 
});
 
console.log(result);

// resultには下記のvalueとindexを含むオブジェクトを各要素とする配列が格納される
// [{value: 1, index: 0}, {value: 2, index: 1}, {value: 3, index: 2}, {value: 4, index: 3}, {value: 5, index: 4}]

 

1.2.4. 配列の生成(Array.from)

Array.from(x)は下記のように「配列っぽい(インデックス、要素、要素数が記録された)」オブジェクトから正真正銘の配列を生成するメソッドです。

const arrayPpoi = {0: 11, 1: 22, 2: 33, length: 3};
 
const result = Array.from(arrayPpoi);
 
console.log(result);

// resultには下記の配列が格納される
// [11, 22, 33]

 
配列っぽいオブジェクトの各要素に対して処理を行わせるべくmapと合わせて用いた場合は

const arrayPpoi = {0: 11, 1: 22, 2: 33, length: 3};
 
const result = Array.from(arrayPpoi).map((val, i) => {
    return {
        x: val,
        y: i
    }
});
 
console.log(result);

// resultには下記のオブジェクトを要素とする配列が格納される
// [{x: 11, y: 0}, {x: 22, y: 1}, {x: 33, y: 2}]

 
さらに、オブジェクトの中にオブジェクトが入ったような形式の配列もどきの場合は、配列もどきオブジェクトの各要素に対して処理を行わせるべくmapと合わせると下記のようにハンドルできる。

const arrayPpoi = {0: {alpha: 11, bravo:111}, 1: {alpha: 22, bravo: 222} , 2: {alpha: 33, bravo: 333}, length: 3};
 
const result = Array.from(arrayPpoi).map(d => {
    return {
        x: d.alpha,
        y: d.bravo
    }
});
 
console.log(result);

// resultには下記のオブジェクトを要素とする配列が格納される
// [{x: 11, y: 111}, {x: 22, y: 222}, {x: 33, y: 333}]

2. TensorFlow.JSで用いられる関数・クラスの基本

このチャプターでは別ページで示す「TensorFlow.js — Making Predictions from 2D Data」の内容が理解できるよう、その中で出現するTensorFlow.JSで用いられる関数・クラスを中心に説明します。

 

2.1. 行列・テンソル

2.1.1. 行列を作る

下記の方法1から3は全て同じ

 a =  \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \\ \end{bmatrix}

という行列aを作る。

方法1

const a = tf.tensor([[1, 2], [3, 4], [5, 6]]);

方法2

const shape = [3, 2];
const a = tf.tensor([1, 2, 3, 4, 5, 6], shape);

方法3

const a = tf.tensor([[1, 2], [3, 4], [5, 6]], [3, 2], 'int32');

 

2.1.2. 行列の変形

shapeを指定してTensorの再形成 reshape()

const b = a.reshape([2, 3]);

 
 b =  \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ \end{bmatrix}

 
行列の行と列を転置して転置行列を生成する transpose()

const b = a.transpose();

 
 b =  \begin{bmatrix} 1 & 3 & 5\\ 2 & 4 & 6\\ \end{bmatrix}

 

b = a.arraySync();

 
 b =  \begin{bmatrix} 1 & 2\\ \end{bmatrix} ,  \begin{bmatrix} 3 & 4\\ \end{bmatrix} ,  \begin{bmatrix} 5 & 6\\ \end{bmatrix}

 
行列の各値を要素とする配列を得る

b = a.dataSync();

 
 b =  \begin{bmatrix} 1, & 2, & 3, & 4, & 5, & 6\\ \end{bmatrix}

 

2.1.4. 行列の算術計算

行列の二乗を得る

const x = tf.tensor([1, 2, 3, 4]);
const y = x.square();

 
 y =  \begin{bmatrix} 1, & 4, & 9, & 16\\ \end{bmatrix}