PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
22.18k stars 5.57k forks source link

动态图计算loss反向传播时是否一定要先求均值mean? #26062

Closed dbsxdbsx closed 4 years ago

dbsxdbsx commented 4 years ago

根据官网的示例:https://www.paddlepaddle.org.cn/tutorials/projectdetail/593621 batch_loss应该先求均值再反向传播

但根据model项目中的示例(160,163行):https://github.com/PaddlePaddle/models/blob/release/1.8/dygraph/reinforcement_learning/actor_critic.py 则是通过fluid.layers.reduce_sum来对batch losss做的处理,而没有求均值。 经实验,若将该强化学习项目中的相关代码替换成:

    avg_policy_loss = fluid.layers.mean(all_policy_loss)
    avg_value_loss = fluid.layers.mean(all_value_loss)
    avg_loss = avg_policy_loss + avg_value_loss
    avg_loss.backward()
    optimizer.minimize(avg_loss)

则收敛会变慢。

因为不清楚飞桨的optimizer.minimize内部是否能跟踪到batch的信息,所以想求证下哪种做法是正确的,又或者都正确?

   

hutuxian commented 4 years ago

感谢使用Paddle。 这两种方式都是正确的。唯一需要注意的是,reduce_mean的梯度会被除以一个batch_size,所以可能要改变一下学习率呢。

dbsxdbsx commented 4 years ago

@hutuxian , 感谢回复。我又想了下:示例1就是典型的监督学习中mini-batch做法---将一个batch的样本均化成一个更加稳定的样本来处理,相当于是做了一次更稳定的Stochastic Gradient Descent;而示例2的做法则相当于连续做了batch size次的Stochastic Gradient Descent。 从数学上来说,最后的收敛速度确实只是个学习率scale的问题。 不过从道理上来说,可能应当使用示例1而不是示例2的做法,因为若一个batch中的loss都是基于相似的问题而产生的loss,那么示例2的做法相当于对同一个问题(loss)做了batch size次的修正,batch size越大,产生过度修复的概率越大(需要通过学习率来调整 的概率也越大)。 所以想了想,在实践中还是以示例1的做法为准较好。