Translate

2018年5月23日水曜日

TensorFlow.js をちょっと触りだけでも理解しておこうと

Core Concepts in TensorFlow.js
https://js.tensorflow.org/tutorials/core-concepts.html

を勝手に翻訳してみた。
以下、翻訳した日本語だが参照の際は
at your own risk
でお願いします。

-----

TensorFlow.js のコアコンセプト


TensorFlow.js は、マシンインテリジェンスのためのオープンソースの WebGL アクセラレーションされた JavaScript ライブラリです。それはあなたの指先に高いパフォーマンスを発揮する機械学習のビルディングブロックをもたらし、ブラウザでニューラルネットワークをトレーニングしたり、トレーニング済みのモデルを推論モードで実行することができます。TensorFlow.jsのインストール/設定のガイドについては、”TensorFlow.js Getting Started”を参照してください。
TensorFlow.js は、機械学習用の低レベルビルディングブロックと、ニューラルネットワークを構築するための高レベルのKeras風のAPIを提供します。ライブラリのいくつかの主要なコンポーネントを見てみましょう。

テンソル


TensorFlow.js において中心となるデータ単位は、テンソルです。数値の集合は、1つ以上の次元の配列に整形されています。Tensor インスタンスは配列形状を定義する属性 shape を保有しています(すなわち、それぞれの次元の配列がどんなにたくさんの値であるか)。
主なTensorコンストラクタは次のtf.tensor関数です。

// 2x3 Tensor
const shape = [2, 3]; // 2 rows, 3 columns
const a = tf.tensor([1.0, 2.0, 3.0, 10.0, 20.0, 30.0], shape);
a.print(); // print Tensor values
// Output: [[1 , 2 , 3 ],
//          [10, 20, 30]]

// The shape can also be inferred:
const b = tf.tensor([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]);
b.print();
// Output: [[1 , 2 , 3 ],
//          [10, 20, 30]]

:しかし、低階数の Tensor を構築するために、我々は、コードの可読性を高めるために、次のの関数を使用することをお勧めします: tf.scalar , tf.tensor1d , tf.tensor2d , tf.tensor3d , tf.tensor4d
次のサンプルでは tf.tensor2d を使って上記と同じテンソルを作成します。

const c = tf.tensor2d([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]);
c.print();
// Output: [[1 , 2 , 3 ],
//          [10, 20, 30]]

TensorFlow.js には、すべての値が0(tf.zeros)に設定した、またはすべての値が1(tf.ones)に設定したテンソルを作成するための便利な関数も提供します。

// 3x5 Tensor with all values set to 0
const zeros = tf.zeros([3, 5]);
// Output: [[0, 0, 0, 0, 0],
//          [0, 0, 0, 0, 0],
//          [0, 0, 0, 0, 0]]

TensorFlow.js においては、テンソルは不変です。一旦作成されると、その値を変更することはできません。そのような場合、代わりに新しいテンソルを生成する演算を実行します。

変数


Variable はテンソル値で初期化されます。しかし、 Tensor とは異なり、変値は変更可能です。次の assign メソッドを使用して、既存の変数に新しいテンソルを割り当てることができます。

const initialValues = tf.zeros([5]);
const biases = tf.variable(initialValues); // initialize biases
biases.print(); // output: [0, 0, 0, 0, 0]

const updatedValues = tf.tensor1d([0, 1, 0, 1, 0]);
biases.assign(updatedValues); // update values of biases
biases.print(); // output: [0, 1, 0, 1, 0]

変数は主に、モデルトレーニング中に値を格納してから更新するために使用されます。

オペレーション(Ops)


テンソルを使用するとデータを格納できますが、操作(ops)ではそのデータを操作できます。TensorFlow.jsは、テンソルで実行できる線形代数と機械学習に適したさまざまな操作を提供します。テンソルは不変なので、これらの演算子は値を変更しません。代わりに、ops は新しいテンソルを返します。

使用可能なオプションには、以下のような単項演算 square が含まれます。

const d = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]);
const d_squared = d.square();
d_squared.print();
// Output: [[1, 4 ],
//          [9, 16]]

そして add , suv そして mul といったバイナリ ops が含まれています。

const e = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]);
const f = tf.tensor2d([[5.0, 6.0], [7.0, 8.0]]);

const e_plus_f = e.add(f);
e_plus_f.print();
// Output: [[6 , 8 ],
//          [10, 12]]

TensorFlow.js には連鎖可能なAPIがあります。ops の結果で opsを呼び出すことができます:

const sq_sum = e.add(f).square();
sq_sum.print();
// Output: [[36 , 64 ],
//          [100, 144]]

// All operations are also exposed as functions in the main namespace,
// so you could also do the following:
const sq_sum = tf.square(tf.add(e, f));

モデルとレイヤ


概念的にはモデルは、ある入力が与えられた出力を生成する関数です。
TensorFlow.js には、モデルを作成する2つの方法があります。opsを直接使用して、モデルが行う作業を表すことができます。例えば:

// 関数定義
function predict(input) {
  // y = a * x ^ 2 + b * x + c
  // tf.tidy の詳細は次のセクションで
  return tf.tidy(() => {
    const x = tf.scalar(input);

    const ax2 = a.mul(x.square());
    const bx = b.mul(x);
    const y = ax2.add(bx).add(c);

    return y;
  });
}

// 定数定義: y = 2x^2 + 4x + 8
const a = tf.scalar(2);
const b = tf.scalar(4);
const c = tf.scalar(8);

// 2 というinputからoutputを予測
const result = predict(2);
result.print() // Output: 24

また、高レベル API tf.model を使用して、レイヤからモデルを構築することもできます。これは、ディープラーニングの一般的な抽象化です。次のコードは、 tf.sequential モデルを構成します。

const model = tf.sequential();
model.add(
  tf.layers.simpleRNN({
    units: 20,
    recurrentInitializer: 'GlorotNormal',
    inputShape: [80, 4]
  })
);

const optimizer = tf.train.sgd(LEARNING_RATE);
model.compile({optimizer, loss: 'categoricalCrossentropy'});
model.fit({x: data, y: labels)});
TensorFlow.jsには、さまざまな種類のレイヤが用意されています。いくつかの例: tf.layers.simpleRNN, tf.layers.gru, tf.layers.lstm

メモリ管理: dispose と tf.tidy


TensorFlow.js は GPU を使用して数学演算を高速化するため、テンソルと変数を扱うときはGPUメモリを管理する必要があります。
TensorFlow.js は、これを支援するために二つの機能を提供します:dispose tf.tidy

dispose


dispose を呼び出しテンソルまたは変数を消去し、そのGPUメモリを解放することができます:

const x = tf.tensor2d([[0.0, 2.0], [4.0, 6.0]]);
const x_squared = x.square();

x.dispose();
x_squared.dispose();

tf.tidy


多くのテンソル操作を行う場合、 dispose を使用することは面倒です。TensorFlow.js では、別の関数として tf.tidy を提供し、GPUでサポートされているテンソル以外は JavaScriptでは通常のスコープと同様の役割を果たします。
tf.tidy 関数を実行し、作成された中間テンソルをパージして、GPUメモリを解放します。内部関数の戻り値はパージしません。

// tf.tidy は、あとで整理するための関数をとります
const average = tf.tidy(() => {
  // tf.tidy は、返却されるテンソル以外の、この関数内のテンソルに
  // よって使用されるすべてのGPUメモリをクリーンアップします。
  //
  // 下のような短い操作シーケンスでも、いくつかの中間的なテンソルが
  // 作成されます。 だからあなたの演算 ops をきちんと整理するのは
  // 良い習慣です!
  const y = tf.tensor1d([1.0, 2.0, 3.0, 4.0]);
  const z = tf.ones([4]);

  return y.sub(z).square().mean();
});

average.print() // Output: 3.5

tf.tidy を使用することで、アプリケーションのメモリリークを防ぐことができます。また、メモリの再利用時期をより慎重に管理するために使用することもできます。

重要な2つの注意


  • tf.tidy に渡される関数は同期している必要があり、Promiseも返されません。UI を更新するコードを保持するか、リモートからのリクエストを tf.tidy の外部に出すことをお勧めします。
  • tf.tidy は変数をクリーンアップしません。変数は通常、機械学習モデルのライフサイクル全体にわたって持続するため、TensorFlow.js は、それらが tidy で作成されていてもそれらをクリーンアップしません。ただし、手動で dispose を呼び出すことはできます。


その他のリソース


ライブラリの包括的なドキュメントについては、TensorFlow.js APIリファレンスを参照してください。
機械学習の基礎について詳しくは、次のリソースを参照してください。


-----

やはり、TensorFlowにKerasの簡単さを取り入れた
構成になってるなあ..

非同期処理の塊であるJavaScriptエンジンでは
tidy()で別スレッドへとばしてメインスレッドを汚さないように
動かすんだ..

に、してもこのドキュメント、
Python の TensorFlow や Keras を一度でも触ったことのある人を
前提にしていて、読みにくい..

Google のドキュメンテーションって、
いっつもターゲットを間違えているんだよなあ..

TensorFlow.js がこれまでのmobileやLiteと違って
学習処理も実装できるように作っている以上、
何も知らない人間を前提にスべきだと思う..

..とここで日本語で書いても、Googleにはつたわらないんだろうけど..




2018年5月22日火曜日

どうでもいい話「昔の邪推がニアピンだった件」

まえに以下の記事を書いた。

Keras の概要を読んで、邪推する
https://fight-tsk.blogspot.jp/2017/01/keras.html

ここで
「Kerasの狙いは
Java機械学習標準ライブラリ狙い
か!」

と書いたのだけど、結局コレはハズレだった。



が、TensorFlow.js の本家サイトを読んでいて
今日ふとこんな記述をみつけた。

TensorFlow.js Layers API for Keras Users
https://js.tensorflow.org/tutorials/tfjs-layers-for-keras-users.html


以下上記リンク先の最初のブロックをぬきだしたものです。

The Layers API of TensorFlow.js is modeled after Keras. As you might have noticed from the tutorials and examples, we strive to make the Layers API as similar to Keras as reasonable given the differences between JavaScript and Python. This makes it easier for users with experience developing Keras models in Python to migrate to TensorFlow.js Layers in JavaScript.

TensorFlow.jsの Layers API はKerasの後にモデル化されています。チュートリアルやサンプルから気づいたかとおもいますが、JavaScript と Python の違いを考慮して、Layers API を Keras に似せるように努めています。これにより、PythonでKerasモデルを開発した経験を持つユーザがJavaScriptのTensorFlow.jsレイヤに移行することが容易になります。



Java ではなく JavaScript だったか..


今朝こんな記事を読んだし..


崖っぷちのJava
なくなるJava SE無償版、ユーザーはどうなる
http://tech.nikkeibp.co.jp/atcl/nxt/column/18/00294/051700002/




..Java、オワコン感はんぱないなあ..

2018年5月21日月曜日

TensorFlow.js(0.11.1) の Getting Started を翻訳してみる

今年のTensorFlow DevSummit の目玉のひとつである
TensorFlow.js をそろそろやってみようかな、
とおもいまずGetting Started ページを読んでみることにした。

といっても現時点(v0.11.1時点)はTensorFlow.jsトップページの下半分
になっている。

以下、勝手に翻訳した文章だが、参照される方は
at your own risk で参照してください。

----

Getting Started

JavaScriptプロジェクトで TensorFlow.js を取得するには、 scriptタグを使用する方法と、NPMからインストールし、ParcelWebPackRollup などのビルドツールを使用する方法の2つの方法があります。

script タグ経由

HTMLファイルに以下のコードを追加します:

<html>
  <head>
    <!-- TensorFlow.js のロード -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.11.1"> </script>

    <!-- 下のscriptタグ内にコードを挿入します。外部の.jsファイルを使用することもできます -->
    <script>
      // 'import'ステートメントがないことに注目してください。 
      // ひとつ上のscriptタグのため、 'tf'はindex-pageで利用できます。

      // 線形回帰モデルの定義
      const model = tf.sequential();
      model.add(tf.layers.dense({units: 1, inputShape: [1]}));

      // トレーニング用モデルの準備:損失値とオプティマイザを指定します
      model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});

      // トレーニング用合成データを生成します
      const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
      const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);

      // データを使ってモデルをトレーニングします
      model.fit(xs, ys).then(() => {
        // モデルが以前に見たことがないデータポイントについて推論を行うには、
        // モデルを使用します:
        // ブラウザの開発ツールを開いて出力を確認してください
        model.predict(tf.tensor2d([5], [1, 1])).print();
      });
    </script>
  </head>

  <body>
  </body>
</html>

あなたのブラウザでHTMLファイルを開くと、コードが実行されます!

 NPM経由


yarn または npm を使って TensorFlow.js をプロジェクトに追加します。注意: ES2017構文( `import`など)を使用しているため、このワークフローでは、コードをブラウザが理解できるものに変換するために bundler/transpiler を使用していることを前提としています。 Parcel を使用してコードを構築する方法については、 を参照してください。Parcel など、好きなビルドツールを自由に使うこともできます。
yarn add @tensorflow/tfjs
npm install @tensorflow/tfjs


あなたのメイン js ファイルには、次のように記述します:

  import * as tf from '@tensorflow/tfjs';

  // 線形回帰モデルの定義
  const model = tf.sequential();
  model.add(tf.layers.dense({units: 1, inputShape: [1]}));

  // モデルのトレーニングの準備:損失値およびオプティマイザの指定
  model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});

  // トレーニング用合成データの生成
  const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
  const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);

  // データを使ってモデルをトレーニング
  model.fit(xs, ys).then(() => {
    // モデルが以前に見たことがないデータポイントについて推論を行うには、
    // モデルを使用します:
    model.predict(tf.tensor2d([5], [1, 1])).print();
  });




詳細は、 チュートリアルサンプルドキュメントを参照してください。

助けが必要ですか?連絡を取りたいですか?

ライブラリを使用してバグが発生した場合 は、GitHubリポジトリに問題を提出してください。また 、TensorFlow.jsを使用について質問をしたり、技術的な助けを借りたり、何をしているのかを聞いたりする共有するコミュニティメーリングリストもあります。TensorFlow.jsのニュースを最新に保つには、twitterで私たちをフォローしてください。または announcement only のメーリングリストに参加してください。
 ------

過去のTensorFlow mobileやTensorFlow Lite は、
inference(推論)ブロック、つまり予測だけをJavaScriptで実行させようとしていたけど、
TensorFlow.js は TensorFlow本体をJavaScriptコードで書かせるというものだ。

なので上記のサンプルはありものの(pre-madeな)回帰分析を
使ってトレーニングさせるところをGetting Started で選んでいる。

HTMLのscriptタブで実装する場合は
HTMLファイルがパースされるクライアントPC上で実行されるが
どうもクライアントPCにNVIDIAドライバとGPUが乗っていれば
それを使うらしい..

とすると、
DockerホストがGPU搭載機であれば、
NVIDIAドライバをホストにインストール済みで、
nvidia docker2 がインストール済みで、
tensorflow/tensorflow-gpu をDockerfileとかでnode/npm動作するように加工しておけば
コンテナでもGPUが使えるわけだ..


node公式かtensorflow公式コンテナで誰か作ってくれるまで
待つとしようかな..














Docker CE for Windows 18.06.0-ce-win72 をインストールしたら「アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。」というエラーが表示される件

普段Docker CE for Windows stable版(18.03.1-ce-win65)をつかっているのだけど 数日前に起動時に 最新版がリリースされたというダイアログメッセージが表示されるようになった。 ..ので、docker-machineで作成したVM...