ITエンジニア ノイのブログ

ITエンジニアのノイです。 YouTubeで ITエンジニアのお勉強という学習用の動画を公開しています。チャンネル登録お願いします!https://m.youtube.com/channel/UCBKfJIMVWXd3ReG_FDh31Aw/playlists

順番付きの辞書(OrderedDict)

順番付きの辞書(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を見ると確かに逆になっているのがわかります。

youtu.be