をSGD。目標は、solver.step()
を実行した後に重みの更新を一致させることと、手動で重みを更新することによるものです。 使用MNISTデータを次のようにカフェのPythonのマニュアルは、私が代わりに<code>solver.step()</code>機能を使用してのカフェのpythonで、手動でのpythonで重みを更新するために、SGD機能を実装しようとしています
セットアップがあります。 solber.prototxtのランダムシードをrandom_seed: 52
として設定します。 momentum: 0.0
、base_lr: 0.01
、lr_policy: "fixed"
を確認してください。上記はSGD更新方程式を単純に実装することができるように行われています(勢い、正則化などはありません)。式は単純です: - :
のTest1: 前方伝播および後方を計算するカフェの前方の()と後方()を使用 W_t + 1 = W_tムー* W_t_diff
以下は二つの試験です伝搬。私は5回の反復のためにこれを実行
solver.net.layers[k].blobs[0].data[...] -= solver.net.layers[k].blobs[0].diff
solver.net.layers[k].blobs[1].data[...] -= solver.net.layers[k].blobs[1].diff
:私は重みを含む層毎 :として
for k in weight_layer_idx:
solver.net.layers[k].blobs[0].diff[...] *= lr # weights
solver.net.layers[k].blobs[1].diff[...] *= lr # biases
次に、重量/バイアスを更新します。
試験2:実行中のcaffeのsolver.step(5)
。
ここで、2回のテストが2回の繰り返しの後に正確に同じウェイトを返すようになると期待しています。
Iは、上記の各試験後の重み値を保存し、二つの試験により重みベクトルとの間のノルム差を計算し、私は彼らが、ビット正確でないことがわかります。私は行方不明になるかもしれない何かを見つけられますか?続い
は参考のため全体のコードである:
import caffe
caffe.set_device(0)
caffe.set_mode_gpu()
import numpy as np
niter = 5
solver = None
solver = caffe.SGDSolver('solver.prototxt')
# Automatic SGD: TEST2
solver.step(niter)
# save the weights to compare later
w_solver_step = copy(solver.net.layers[1].blobs[0].data.astype('float64'))
b_solver_step = copy(solver.net.layers[1].blobs[1].data.astype('float64'))
# Manual SGD: TEST1
solver = None
solver = caffe.SGDSolver('solver.prototxt')
lr = 0.01
momentum = 0.
# Get layer types
layer_types = []
for ll in solver.net.layers:
layer_types.append(ll.type)
# Get the indices of layers that have weights in them
weight_layer_idx = [idx for idx,l in enumerate(layer_types) if 'Convolution' in l or 'InnerProduct' in l]
for it in range(1, niter+1):
solver.net.forward() # fprop
solver.net.backward() # bprop
for k in weight_layer_idx:
solver.net.layers[k].blobs[0].diff[...] *= lr
solver.net.layers[k].blobs[1].diff[...] *= lr
solver.net.layers[k].blobs[0].data[...] -= solver.net.layers[k].blobs[0].diff
solver.net.layers[k].blobs[1].data[...] -= solver.net.layers[k].blobs[1].diff
# save the weights to compare later
w_fwdbwd_update = copy(solver.net.layers[1].blobs[0].data.astype('float64'))
b_fwdbwd_update = copy(solver.net.layers[1].blobs[1].data.astype('float64'))
# Compare
print "after iter", niter, ": weight diff: ", np.linalg.norm(w_solver_step - w_fwdbwd_update), "and bias diff:", np.linalg.norm(b_solver_step - b_fwdbwd_update)
二つの試験を用いて重みを比較し、最後の行が生成する:私はこの差が0.0
ことを期待したようにafter iter 5 : weight diff: 0.000203027766144 and bias diff: 1.78390789051e-05
を
アイデア?
あなたはsolver.prototxtゼロに[ 'weight_decay'](http://stackoverflow.com/q/32177764/1714410)を設定することがありますか? – Shai
はい、以前言及していなかったが、 'weight_decay:0.0'が設定されています。何が起こっているかは、これらの2つのテストを1回だけ実行すると、すべてのレイヤーから正確に一致するウェイトベクトルが取得されますが、その後の繰り返しは取得されません。 – Aniket
勾配の勢いがあるかもしれません。勢いを0に設定してみてください。 – mkuse