# $${{X.spartial('L')}}={{Y.spartial("L")}}\cdot {{W}}^\mathrm{T}$$ # $${{W.spartial('L')}}={{X}}^\mathrm{T}\cdot {{Y.spartial("L")}}$$ # まずは、MatMalレイヤの動作を確認します。形状を定義します。 N, T, L, M = 20, 3, 3, 4 # ここで$N$はバッチ数、$T$はタイムステップ数、$L$は入力の次元、$M$は出力の次元です。 import numpy as np # isort:skip from ivory.core.model import sequential # isort:skip from ivory.common.util import convert_one_hot # isort:skip net_mat = [("input", L), ("matmul", M, "softmax_cross_entropy")] model_mat = sequential(net_mat) mat = model_mat.layers[0] # ランダムな入力を作成します。 x = np.random.randint(0, L, N) t = np.random.randint(0, M, N) # MatMulレイヤへ入力するために、one-hot表現に変換します。 model_mat.set_data(convert_one_hot(x, L), t) model_mat.forward() print(model_mat.loss) # 逆伝搬を比較します。 model_mat.backward() print(mat.W.g) # type:ignore # 数値微分による勾配と比較します。 print(model_mat.numerical_gradient(mat.W.variable)) # type:ignore
W = Matrix("w", n, m) U = Matrix("u", m, m) B = Vector("b", m) # RNNレイヤの入力と出力の関係は以下のようになります。{{ import sympy as sp }} # $${{Y.s}}_t = {{X.s}}_t\cdot{{W.s}} + {{Y.s}}_{t-1}\cdot{{U.s}} + {{B.s}}$$ # 動作を確かめます。形状(バッチ数、タイムステップ数、入力の次元、出力の次元)を以下の通 # りとします。 from ivory.core.model import sequential # isort:skip N, T, L, M = 2, 10, 3, 4 net = [("input", L), ("rnn", M), ("softmax_cross_entropy")] model = sequential(net) rnn = model.layers[0] print(rnn) # 数値部分のためにビット精度を64ビットにします。 rnn.dtype = 'float64' for p in rnn.parameters: print(p) # レイヤパラメータを設定します。 from ivory.common.context import np # isort:skip w = rnn.W.variable.data = np.random.randn(L, M) # type:ignore u = rnn.U.variable.data = np.random.randn(M, M) # type:ignore b = rnn.b.variable.data = np.random.randn(M) # type:ignore # ランダムな入力を作成します。 x = np.random.randn(N, T, L)
# ## モデル # 一連のレイヤよりなるモデルは`model`モジュールの`sequential`関数で構築することができます。 # このメソッドはレイヤクラス名をスネークケースで記述した「レイヤ表現」を引数に取り # 、`Model`クラスのインスタンスを返します。最終レイヤは損失関数を出力するレイヤである必要 # があります。各レイヤのパラメータには変数が自動で割り当てられます。 from ivory.core.model import sequential net = [("input", 5), ("affine", 10, "relu"), ("affine", 4, "softmax_cross_entropy")] model = sequential(net) model.layers # ここで、最初の`("input", 5)`が、5次元の入力を示すプレースホルダです。上記のよう # に`Model`インスタンスは`layers`属性を持ち、所属するレイヤを返します。各レイヤにはクラス # ごとに連番で名前が付けられています。 # `sequential`関数は、同じパターンの繰り返しを簡潔に書く方法が用意されています。 net = [ ("input", 784), (3, "affine", 100, "relu"), ("affine", 10, "softmax_cross_entropy"), ] model_complex = sequential(net) model_complex.layers # このように、レイヤ表現の最初の要素が整数の場合、その数だけ残りの要素を繰り返します。 # `layers`属性のほかにも、損失に影響を与えるパラメータを取得できます。