Tensorflow先实现梯度多次累加,再进行一次反向传播的过程

在Tensorflow中,每次sess.run(self.optimizer)时,都会同时计算梯度并且更新变量。 但是在pytorch中,可以通过三个步骤实现:

  1. 梯度清零: optimizer.zero_grad()
  2. 反向传播计算每个参数的梯度 loss.backward()
  3. 梯度下降并更新参数 optimizer.step()

如果想实现多次计算梯度后,再统一更新一次梯度(由minibatch实现大的batchsize). 或者 (长序列插帧内部迭代完整个序列后再传播一次梯度)。 就需要用到分开计算梯度和更新参数了。 在pytorch中很容易实现,但是在tensorflow中需要自己写计算梯度和更新参数的过程。

import tensorflow as tf
import numpy as np
import os

os.environment['CUDA_VISIBLE_DEVICES']='0'
x_data= np.array(range(1,20))
num_dataset = len(x_data)
batchsize= 4
minibatch_size = 2
with tf.graph().as_default():
	x = tf.placeholder(dype='float32'. shape = None)
	 w = tf.Variable(initial_value=4., dtype='float32')
    loss = w * w * x

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

    # 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 zeros
    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(loss, 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)])

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())

        for batch_count in range(batch_size):
            # 在run每个batch, 需先将前一个batch所得的累积梯度清零
            sess.run(zero_ops)

            batch_data = x_data[batch_count*batch_size: (batch_count+1)*batch_size]
            # Accumulate the gradients 'minibatch_size' times in accum_vars using accum_ops
            for minibatch_count in range(minibatch_size):
                minibatch_data = batch_data[minibatch_count*minibatch_size: (minibatch_count+1)*minibatch_size]
                accum_array = sess.run(accum_ops, feed_dict={x: minibatch_data})
                print("[%d][%d]" % (batch_count, minibatch_count), accum_array)
                print(sess.run(tvs))
            # Run the train_step ops to update the weights based on your accumulated gradients
            sess.run(train_step)
————————————————
版权声明:本文为CSDN博主「dekiang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41560402/article/details/106930463
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用TensorFlow 2.0实现梯度下降的示例代码: ``` import tensorflow as tf # 定义训练数据 x_train = [1.0, 2.0, 3.0, 4.0] y_train = [2.0, 4.0, 6.0, 8.0] # 定义模型参数 W = tf.Variable(1.0) b = tf.Variable(1.0) # 定义模型 def model(x): return W * x + b # 定义损失函数 def loss(predicted_y, desired_y): return tf.reduce_mean(tf.square(predicted_y - desired_y)) # 定义训练函数 def train(x, y, learning_rate): with tf.GradientTape() as t: current_loss = loss(model(x), y) dW, db = t.gradient(current_loss, [W, b]) W.assign_sub(learning_rate * dW) b.assign_sub(learning_rate * db) # 训练模型 for epoch in range(100): for x, y in zip(x_train, y_train): train(x, y, learning_rate=0.01) current_loss = loss(model(x_train), y_train) print(f"Epoch {epoch}: Loss: {current_loss.numpy()}") # 测试模型 x_test = [5.0, 6.0, 7.0, 8.0] y_test = [10.0, 12.0, 14.0, 16.0] predicted_y = model(x_test) print(f"Predicted Y: {predicted_y.numpy()}") print(f"Desired Y: {y_test}") ``` 在这个例子中,我们使用TensorFlow 2.0实现了一个简单的线性回归模型,并使用梯度下降算法对其进行了训练。我们首定义了训练数据,然后定义了模型参数W和b。接下来,我们定义了模型函数,它将输入x映射到输出y。然后,我们定义了损失函数,它将模型的预测输出y与真实输出y进行比较,并计算它们之间的平方差。最后,我们定义了一个训练函数,它使用梯度带自动计算模型参数W和b的梯度,并使用学习率更新它们。在训练过程中,我们迭代地将训练数据馈送给训练函数,直到达到指定的训练轮数。最后,我们使用训练好的模型对测试数据进行预测,并将预测结果与真实结果进行比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值