tensorflow实现梯度累计,再回传
生活随笔
收集整理的這篇文章主要介紹了
tensorflow实现梯度累计,再回传
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
由于主機顯卡只有12g的顯存,且只裝了一塊30系列的卡,因此在跑代碼時難免會遇到batch_size不能太大的尷尬,因此可以通過,梯度累計的方式進行優(yōu)化,來變相擴大batch_size。這樣的操作在pytorch中很好實現(xiàn),但在tf中稍顯復(fù)雜。
上代碼,解釋:
def train():......# 所有可訓(xùn)練參數(shù) trainable_vars = tf.trainable_variables()# 規(guī)定需要訓(xùn)練的參數(shù)vit_trainable_vars = [var for var in trainable_vars if 'VGG' not in var.name] #both generate and vision_transformer #291print("************vars to train:",len(vit_trainable_vars))# 在計算圖中定義一個操作,為每一個要訓(xùn)練的參數(shù)創(chuàng)建一個等shape的全0變量accum_vars = [tf.Variable(tf.zeros_like(tv.initialized_value()), trainable=False) for tv in vit_trainable_vars]# 梯度歸零操作zero_ops = [tv.assign(tf.zeros_like(tv)) for tv in accum_vars]global_step = tf.Variable(1, trainable=False)# 定義優(yōu)化操作with tf.device('/gpu:0'):with tf.name_scope('train'):#train_step = tf.train.AdamOptimizer(learning_rate, 0.9, 0.999).minimize(loss, global_step=global_step)# 優(yōu)化器optimizer = tf.train.AdamOptimizer(learning_rate, 0.9, 0.999)# 計算梯度grads = optimizer.compute_gradients(loss, vit_trainable_vars)# 將本次梯度類加 accum_ops = [accum_vars[i].assign_add(gv[0]) for i, gv in enumerate(grads)]# 優(yōu)化參數(shù)train_step = optimizer.apply_gradients([(accum_vars[i], gv[1]) for i, gv in enumerate(grads)], global_step=global_step)...iter = 0while True:...... iter += 1sess.run(accum_ops) #累加兩次梯度if iter % 2 == 0:...sess.run(train_step, feed_dict={...}) #優(yōu)化一次參數(shù)...sess.run(zero_ops) #將梯度置0...這樣就完成了計算兩次梯度,并累加回傳的目的,相當(dāng)于batch_size擴大了一倍。
值得注意的是,如果我們不規(guī)定要保存的參數(shù)化,新創(chuàng)建的Variable也會被保存,會導(dǎo)致我們的模型體積變大,因此要規(guī)定只保存原來模型的參數(shù)。例,我在實際使用中:
var_to_save = [val for val in var if 'Adam' not in val.name and 'Variable_' not in val.name]saver = tf.train.Saver(var_to_save, max_to_keep=None)總結(jié)
以上是生活随笔為你收集整理的tensorflow实现梯度累计,再回传的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录之tensorflow和pytorc
- 下一篇: Tensorflow1.x 和 2.x如