web-dev-qa-db-ja.com

テンソルフローに勾配を蓄積する方法は?

これ に似た質問があります。

リソースが限られているため、トリプレットネットワークのトレーニングに使用されるディープモデル(VGG-16)を使用しているため、サイズ1のトレーニング例の128バッチの勾配を累積し、エラーを伝播して重みを更新します。

これをどのように行うのか私にはわかりません。私はテンソルフローで作業しますが、任意の実装/疑似コードを歓迎します。

12
Hello Lili

あなたが好きな答えの1つで提案されたコードを見てみましょう:

## Optimizer definition - nothing different from any classical example
opt = tf.train.AdamOptimizer()

## Retrieve all trainable variables you defined in your graph
tvs = tf.trainable_variables()
## Creation of a list of variables with the same shape as the trainable ones
# initialized with 0s
accum_vars = [tf.Variable(tf.zeros_like(tv.initialized_value()), trainable=False) for tv in tvs]
zero_ops = [tv.assign(tf.zeros_like(tv)) for tv in accum_vars]

## Calls the compute_gradients function of the optimizer to obtain... the list of gradients
gvs = opt.compute_gradients(rmse, tvs)

## Adds to each element from the list you initialized earlier with zeros its gradient (works because accum_vars and gvs are in the same order)
accum_ops = [accum_vars[i].assign_add(gv[0]) for i, gv in enumerate(gvs)]

## Define the training step (part with variable value update)
train_step = opt.apply_gradients([(accum_vars[i], gv[1]) for i, gv in enumerate(gvs)])

この最初の部分では、基本的に新しいvariablesopsをグラフに追加します。

  1. 変数accum_ops(のリスト)のops accum_varsを使用して勾配を累積します。
  2. Ops train_stepでモデルの重みを更新する

次に、トレーニング時にそれを使用するには、次の手順に従う必要があります(まだリンクした回答から)。

## The while loop for training
while ...:
    # Run the zero_ops to initialize it
    sess.run(zero_ops)
    # Accumulate the gradients 'n_minibatches' times in accum_vars using accum_ops
    for i in xrange(n_minibatches):
        sess.run(accum_ops, feed_dict=dict(X: Xs[i], y: ys[i]))
    # Run the train_step ops to update the weights based on your accumulated gradients
    sess.run(train_step)
22
Pop