RBM を実装しようとしていて、MNIST データセットでテストしています。しかし、収束しないようです。
28x28 の可視ユニットと 100 の非表示ユニットがあります。サイズ 50 のミニバッチを使用しています。エポックごとに、データセット全体をトラバースします。学習率は 0.01、運動量は 0.5 です。重みは、平均 0.0 および stdev 0.01 のガウス分布に基づいてランダムに生成されます。可視バイアスと非表示バイアスは 0 に初期化されます。アクティブ化としてロジスティック シグモイド関数を使用しています。
各エポックの後、すべてのミニバッチの平均再構築エラーを計算します。取得したエラーは次のとおりです。
epoch 0: Reconstruction error average: 0.0481795
epoch 1: Reconstruction error average: 0.0350295
epoch 2: Reconstruction error average: 0.0324191
epoch 3: Reconstruction error average: 0.0309714
epoch 4: Reconstruction error average: 0.0300068
チェックする重みのヒストグラムをプロットしました (左から右: 非表示、重み、可視、上: 重み、下: 更新):
エポック 3 後の重みのヒストグラムエポック 3 後 の重みのヒストグラム http://baptiste-wicht.com/static/finals/histogram_epoch_3.png
エポック 4 後の重みのヒストグラムエポック 4 後 の重みのヒストグラム http://baptiste-wicht.com/static/finals/histogram_epoch_4.png
しかし、少し奇妙に見える隠れた偏見を除けば、残りは問題ないようです。
私はまた、隠された重みをプロットしようとしました:
エポック 3 後の重み
エポック 3 後の重み http://baptiste-wicht.com/static/finals/hiddens_weights_epoch_3.png
エポック 4 後の重み
エポック 4 後の重み http://baptiste-wicht.com/static/finals/hiddens_weights_epoch_4.png
(それらは、その関数を使用して 2 色でプロットされます。
static_cast<size_t>(value > 0 ? (static_cast<size_t>(value * 255.0) << 8) : (static_cast<size_t>(-value * 255.)0) << 16) << " ";
)
そして、ここでは、それらはまったく意味がありません...
さらに進むと、再構築エラーはもう少し減少しますが、0.025 を超えないようにしてください。しばらくして勢いを変えても、上がったり下がったりするけど面白くない。さらに、エポックが増えると、重みは意味をなさなくなります。私が見たほとんどの実装例では、完全なデータ セットを 2 ~ 3 回繰り返した後、重みがある程度意味を成していました。
また、可視ユニットから画像を再構築しようとしましたが、結果はほぼランダムに見えます。
実装で何が問題なのかを確認するにはどうすればよいですか? 重みはある範囲内にあるべきですか?データ内で何かが本当に奇妙に見えますか?
完全なコード: https://github.com/wichtounet/dbn/blob/master/include/rbm.hpp