1.2 レイヤ

ネットワークを構成するレイヤは、Layerクラスのインスタンスが表現します。Affineレイヤを見てみましょう。

from ivory.core.layer import Layer
from ivory.layers.affine import Affine

assert issubclass(Affine, Layer)
affine = Affine((2, 3))
affine

[1] 2019-06-12 20:00:10 (183ms) python3 (183ms)

<Affine('Affine.1', (2, 3)) at 0x213e04defd0>

レイヤインスタンスは、入力inputs、重みweights、状態states、そして、出力outputsの属性を持ちます。これらは複数持つことができます。

for attr in ["inputs", "weights", "states", "outputs"]:
    for var in getattr(affine, attr):
        print(var)

[2] 2019-06-12 20:00:10 (31.3ms) python3 (214ms)

<Input('Affine.1.x', (2,)) at 0x213e04def28>
<Weight('Affine.1.W', (2, 3)) at 0x213f3d72ba8>
<Weight('Affine.1.b', (3,)) at 0x213f3d72b38>
<State('Affine.1.weight_decay', ()) at 0x213f3d72b70>
<Output('Affine.1.y', (3,)) at 0x213e04def98>

属性には適切な名前がついているのが確認できます。実際に、レイヤインスタンスから直接名前でアクセスできます。

affine.W

[3] 2019-06-12 20:00:10 (8.03ms) python3 (222ms)

<Weight('Affine.1.W', (2, 3)) at 0x213f3d72ba8>

上記でAffine((2, 3))としたので、重みWとバイアスbがそれにふさわしい形状で作成されています。

print(affine.W.shape, affine.b.shape)

[5] 2019-06-12 20:00:10 (12.0ms) python3 (240ms)

(2, 3) (3,)

一方で、入力xと出力yの形状は、

print(affine.x.shape, affine.y.shape)

[6] 2019-06-12 20:00:10 (15.6ms) python3 (256ms)

(2,) (3,)

となり、バッチサイズは含まれていません。

ニューラルネットワークの学習では、損失関数の値を最小化するように重みを調整します。損失関数を含むレイヤはLossLayerという特別なクラスで実装されています。例を見てみます。

from ivory.layers.loss import LossLayer, SoftmaxCrossEntropy

s = SoftmaxCrossEntropy((3,))
print(isinstance(s, LossLayer))
print(s)

[7] 2019-06-12 20:00:10 (31.3ms) python3 (287ms)

True
<SoftmaxCrossEntropy('SoftmaxCrossEntropy.1', (3,)) at 0x213f4b9ffd0>

上記は、ソフトマックス関数と交差エントロピー誤差がセットになったレイヤです。形状が(3,)となっているため、3種類のクラスを分類します。入力は前段レイヤからの入力xとターゲット値tを持ちます。tはone-hot表現ではなく、ラベル表現をとるため、スカラー値になります。

s.inputs

[8] 2019-06-12 20:00:10 (7.00ms) python3 (294ms)

[<Input('SoftmaxCrossEntropy.1.x', (3,)) at 0x213f4b9ff60>,
 <Input('SoftmaxCrossEntropy.1.t', ()) at 0x213f4bbc080>]

「出力」は2つあります。一つは、ソフトマックス関数の出力です。

s.outputs

[9] 2019-06-12 20:00:10 (8.06ms) python3 (302ms)

[<Output('SoftmaxCrossEntropy.1.y', (3,)) at 0x213f4bbc048>]

これは各クラスの確率を与えるため、入力と同じ形状をしています。もう一つは損失である交差エントロピー誤差であり、こちらはスカラー値です。loss属性でアクセスできます。

s.loss

[10] 2019-06-12 20:00:10 (7.00ms) python3 (309ms)

<Loss('SoftmaxCrossEntropy.1.loss', ()) at 0x213f4bbc0b8>