Theano 0.8.0: Tutorial: 最初の一歩 – 代数

Theano 0.8.0: Tutorial: 最初の一歩 – 代数 – Algebra(翻訳/要約)

* Theano 0.8.0: Tutorial: Baby Steps – Algebra の簡単な要約です。

 

2つのスカラを加算する

Theano で始めるにあたりどのような作業をしているのか感覚を掴むために、単純な関数を作ってみましょう: 2つの数字を一緒に加算します。どのようにするかをここに示します :

>>> import numpy
>>> import theano.tensor as T
>>> from theano import function
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
>>> z = x + y
>>> f = function([x, y], z)

そして関数を作成したのでそれを使うことができます :

>>> f(2, 3)
array(5.0)
>>> numpy.allclose(f(16.3, 12.1), 28.4)
True

これを幾つかのステップにブレークダウンします。最初のステップは加算したい量を表す2つのシンボル (Variables) を定義します。今から、Variable という用語を “シンボル” を意味するものとして使用します。(換言すれば、x, y, z はすべて Variable オブジェクトです。)関数の出力 f は 0 次元の numpy.ndarray です。

もし貴方が指示に従ってインタープリタにタイピングしているならば、function 命令を実行するときにわずかの遅延があることに気がついたかもしれません。裏では、f は C コードにコンパイルされています。

 

step 1

>>> x = T.dscalar('x')
>>> y = T.dscalar('y')

Theano では、全てのシンボルが型付けられなければなりません。特に、T.dscalar は “double (d) の 0-次元配列(スカラ)” を割り当てる型です。これは Theano の です。

dscalar はクラスではありません。従って、x も y も実際には dscalar のインスタンスではありません。それらは TensorVariable のインスタンス です。x と y は、けれども、それらの 型フィールドには theano 型 dscalar が割り当てられます :

>>> type(x)
<class 'theano.tensor.var.TensorVariable'>
>>> x.type
TensorType(float64, scalar)
>>> T.dscalar
TensorType(float64, scalar)
>>> x.type is T.dscalar
True

T.dscalar を文字列引数で呼び出すことにより、浮動小数点スカラ量を表す Variable を与えられた名前で作成できます。引数を提供しない場合にはシンボルに名前がつけられません。名前は必須ではありませんが、デバッグの助けにはなります。

Theano の内部構造に関してはすぐに更に説明されるでしょう。また グラフ構造 を研究することで更に学べるでしょう。

 

Step 2

2番目のステップは x と y をその合計 z に結合します :

>>> z = x + y

z は x と y の加算を表すもう一つの Variable です。z に関係づけられた計算を pretty-print するためには pp 関数が使用できます。

>>> from theano import pp
>>> print(pp(z))
(x + y)
 

Step 3

最後のステップは x と y を入力として取り z を出力として与える関数を作成します :

>>> f = function([x, y], z)

function への最初の引数は、関数への入力として提供される Variable のリストです。
2つ目の引数は一つの Variable か Variable のリストです。どちらの場合でも、2つ目の引数は関数を適用した時に出力として見ることを望むものです。そして f は通常の Python 関数のように使用されます。

Note : ショートカットとして step 3 はスキップできます、そして variable の eval メソッドが使用できます。eval() メソッドは function() のように柔軟ではありませんがここまでチュートリアルでカバーしたことの全てを行なうことができます。function() を import することを要求しないという追加のメリットもあります。eval() がどのように動作するかをここに示します :

>>> import numpy
>>> import theano.tensor as T
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
>>> z = x + y
>>> numpy.allclose(z.eval({x : 16.3, y : 12.1}), 28.4)
True

eval() に、シンボリック theano variable をそれらを置き換える値にマップする辞書を渡しました、そしてそれは式の数値を返しました。variable 上で最初に呼び出した時は eval() は遅いでしょう – 裏で式をコンパイルするために function() を呼び出す必要があります。同じ variable 上の後続の eval() の呼び出しは速いでしょう、何故なら variable はコンパイルした関数をキャッシュするからです。

 

2つの行列を加算する

これをどのように行なうか既に推測できるでしょう。実際に、前の例から変更は x と y を行列の型で初期化する必要があることだけです :

>>> x = T.dmatrix('x')
>>> y = T.dmatrix('y')
>>> z = x + y
>>> f = function([x, y], z)

dmatrix は double の行列のための型です。そして 2D 配列上の新しい関数を使用できます :

>>> f([[1, 2], [3, 4]], [[10, 20], [30, 40]])
array([[ 11.,  22.],
       [ 33.,  44.]])

variable は NumPy 配列です。NumPy 配列を直接に入力として使用することもできます :

>>> import numpy
>>> f(numpy.array([[1, 2], [3, 4]]), numpy.array([[10, 20], [30, 40]]))
array([[ 11.,  22.],
       [ 33.,  44.]])

スカラを行列に、ベクトルを行列に、スカラをベクトルに加算する等々が可能です。これらの演算の挙動は broadcasting で定義されています。

次の型が利用可能です :

  • byte: bscalar, bvector, bmatrix, brow, bcol, btensor3, btensor4
  • 16-bit integers: wscalar, wvector, wmatrix, wrow, wcol, wtensor3, wtensor4
  • 32-bit integers: iscalar, ivector, imatrix, irow, icol, itensor3, itensor4
  • 64-bit integers: lscalar, lvector, lmatrix, lrow, lcol, ltensor3, ltensor4
  • float: fscalar, fvector, fmatrix, frow, fcol, ftensor3, ftensor4
  • double: dscalar, dvector, dmatrix, drow, dcol, dtensor3, dtensor4
  • complex: cscalar, cvector, cmatrix, crow, ccol, ctensor3, ctensor4

前のリストは完全なものではありません、そして NumPy 配列と互換な全ての型へのガイドはここで見つかります : テンソル作成

 

以上