モバイル&ワイヤレスブロードバンドでインターネットへ
tfjs-vis は、 TensorFlow.js (tfjs) のために用意されたブラウザ向け可視化ライブラリーです。
https://www.tensorflow.org/
今回は、この tfjs-vis で sin 波をグラフ表示してみます。
なぜ sin 波?、かといいますと、時系列データを扱うリカレントニューラルネットワーク recurrent neural networks (RNN) の入門の題材として、 sin 波の時系列データが用いられることも多いからです。次回以降、実際に tfjs でこのモデルを構築してみる予定です。
そのようなこともあって、 sin 波データ生成には tfjs の API を使用しています。また、このデータにノイズを入れていきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>sin サンプル</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"> </script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis"></script>
<script>
var _debug;
var _dct = 0;
function _debugStart(){
_debug = document.getElementById("DEBUG");
_debug.textContent = "";
_debugHTML("DEBUG START");
}
function _debugHTML(_deHTML){
_debug.insertAdjacentHTML("afterbegin", "<div><em>" + ++_dct + " : </em>" + _deHTML + "<div>");
}
console.log = function(_dobj){
_debugHTML(_dobj);
};
</script>
</head>
<body>
<div id="sinChart"></div>
<div id="DEBUG"></div>
<script>
_debugStart();
_debugHTML("tfjs-vis START");
function tensor_sin(T=100, ampl=0.05){
return tf.tidy(() => {
const L = 2 * T + 1;
const noise = tf.randomUniform([L], -1.0, 1.0);
const an = tf.mul(noise, tf.scalar(ampl));
noise.dispose();
const x = tf.range(0, L);
const xp = tf.mul(x, tf.scalar(2.0 * Math.PI));
x.dispose();
const sx = tf.sin(tf.div(xp, tf.scalar(T)));
xp.dispose();
const sn = tf.add(sx, an);
return sn;
});
}
const T = 100;
const f = tensor_sin(T, 0.1);
const n = tensor_sin(T, 0.0);
const array = f.dataSync();
const arr = n.dataSync();
const sinValues = [[], []];
for (let i = 0; i < 2*T; i++) {
sinValues[0].push({"x": i, "y": array[i]});
sinValues[1].push({"x": i, "y": arr[i]});
}
const sinContainer = document.getElementById("sinChart");
tfvis.render.linechart(
sinContainer,
{
values: sinValues,
series: ["noiseあり", "noiseなし"]
},
{
zoomToFit: true,
width: 300,
height: 300,
xLabel: "time",
yLabel: "value"
});
_debugHTML("tfjs-vis E N D");
</script>
</body>
</html>
tfjs を利用する場合、データを事前にテンソル (Tensor) というユニットへセットします。
使用している API をいくつかみてみます。
https://js.tensorflow.org
tf.randomUniform() は、一様分布のランダムな値で初期化したテンソルを作成します。
tf.scalar() は、スカラー値のテンソルを作成します。
テンソルの四則演算には、 tf.mul() の乗算、 tf.div() の除算、 tf.add() の加算、 tf.sub() の減算、それぞれを使用します。
tf.range() は、順番に並べた数値で初期化したテンソルを作成します。
tf.sin() は、 sin の値で初期化したテンソルを作成します。
dispose() と tf.tidy() は、メモリ管理のための関数です。 dispose() は、個々のテンソルの GPU メモリ解放を、 tf.tidy() は、JavaScript のスコープにおいて作成された中間的なテンソルの GPU メモリ解放を行います。
dataSync() は、テンソルの値をJavaScript 変数へ同期的に渡します。
tfjs では、テンソルを扱うための API が多く用意されていますが、それですべてが行えるとは限りません。JavaScript でデータ操作後にテンソルを作成するなどの工夫が必要な場面もあるかもしれません。
今回の場合、JavaScript の配列に sin の値をセットして、テンソルを使わない方法もあったのですが、今後 tfjs を利用する場合にテンソルの扱いは必須となりますので、あえて取り組んでみました。
続いて、
https://js.tensorflow.org
/api_vis
通常は、学習の可視化のため、損失 loss と正確度 accuracy の推移をグラフ出力して、学習の進み具合を確認するために利用されます。
さて、今回使用している環境は、Android スマホのテキストエディタアプリ QuickEdit Text Editor Pro です。プレビュー機能で HTML ドキュメントの JavaScript コードを実行することで確認しています。 QuickEdit Text Editor Pro で TensorFlow.js の CODE SAMPLE FOR SCRIPT TAG SETUP をプレビュー で記事投稿した方法です。文法 Error の Debug はできませんが、console.log を出力するためのコードを追加しています。
RNN について、今回参照している書籍です。なお、本書での実装は Python です。