順番付きの辞書(OrderedDict)
順番付きの辞書(OrderedDict)は、通常の辞書(dict)とは異なり、要素の追加順序を保持するデータ構造です。通常の辞書では、要素の順序は保証されていませんが、順番付き辞書では要素が追加された順序が維持されます。実はニューラルネットワークでもこの順番を意識しないと実装ができないことがあります。
順番付き辞書は、Pythonの標準ライブラリのcollections
モジュールに含まれており、OrderedDict
というクラスを使用して作成します。OrderedDict
は、通常の辞書のすべての機能を持ちながら、要素の順序を保持するための追加の機能を提供します。
順番付き辞書の例
from collections import OrderedDict dic1 = OrderedDict() dic1["a"] = 1 dic1["c"] = 3 dic1["b"] = 2 for key, value in dic1.items(): print(key, value) print() # dictから逆順でvalueを取り出す方法 layers = list(dic1.values()) print("before:", layers) layers.reverse() # 順序を逆転させる print("orderd:", layers)
出力
a 1 c 3 b 2 before: [1, 3, 2] orderd: [2, 3, 1]
ニューラルネットワークで必要な理由
ニューラルネットワークを実装する際にアフィン関数やReLU関数をレイヤー順に定義することがあります。通常は、この順番通り使えば通常は問題ありません。順伝播の場合は定義した順番に使っていきますが、逆伝播の場合は逆順に使わなければなりません。そのため、OrderedDictを使って逆順にする必要があります。
レイヤの生成
self.layers = OrderedDict() # 順番付きdict形式. self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1']) self.layers['Relu1'] = ReLU() self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2']) self.lastLayer = SoftmaxWithLoss() # 出力層
順伝播と逆伝播の違い
## doutを逆向きに伝える layers = list(self.layers.values()) print("順伝搬", layers) layers.reverse() print("逆伝搬", layers)
出力結果
順伝搬 [<common.layers.Affine object at 0x7f35340fcc10>, <common.layers.ReLU object at 0x7f35340ffeb0>, <common.layers.Affine object at 0x7f35340fca90>] 逆伝搬 [<common.layers.Affine object at 0x7f35340fca90>, <common.layers.ReLU object at 0x7f35340ffeb0>, <common.layers.Affine object at 0x7f35340fcc10>]
順伝搬ではAffine、ReLU、Affineという順なので少しわかりにくいですが、0x7f35340fcc10
を見ると確かに逆になっているのがわかります。