AI4Finance-Foundation / ElegantRL

Massively Parallel Deep Reinforcement Learning. 🔥
https://ai4finance.org
Other
3.74k stars 850 forks source link

The alpha loss calculating of SAC is different from other repo #10

Closed youzhonghui closed 3 years ago

youzhonghui commented 3 years ago

The alpha loss calculated in this repo via:

alpha_loss = (self.alpha_log * (log_prob - self.target_entropy).detach()).mean()

and self.target_entropy is initialized with self.target_entropy = np.log(action_dim)

https://github.com/Yonv1943/ElegantRL/blob/05c720e6b84ff393d38c929066da982dbe59957c/AgentZoo.py#L405

I found another repo which implement the SAC with auto alpha adjustment:

https://github.com/dongminlee94/deep_rl/blob/3cfd41d7e3b7f3cf4a3ee5d6a8ac8f49cbe36d93/agents/sac.py#L154

and that repo calculate alpha_loss with:

alpha_loss = -(self.log_alpha * (log_pi + self.target_entropy).detach()).mean()

and self.target_entropy is initialized with -np.prod((act_dim,)).item()

Why is there such a difference? Am I overlook something?

Yonv1943 commented 3 years ago

作为非英语母语者,为了准确给使用拼音作为用户名的user回复,我决定使用中文。(看不懂中文的人,请信赖在线翻译软件) As a non-native English speaker, in order to accurately respond to users who use pinyin as user name, I decided to use Chinese. (For those who cannot understand Chinese, please rely on online translation software)


alpha(或log_alpha)的初始化代码,不应该选择0(或log(1)),经过大量实验,它应该选择更小的数值。至于具体选哪个值,要看实际算出来的Q值大小(我自己多次尝试的结果,Q值的绝对值在128内比较合适)。然而,Q值大小和 reward scaling、gamma值、等等有关,因此大家的实现会有不同。初始值有不同也不要紧,因为这只会影响SAC的预热时长,只要alpha初始化的值不离谱,SAC依然可以稳定训练。

alpha_loss 的代码理论上与SAC作者的实现完全一致。我只是让代码变得更好看而已。 SAC作者的意图:

综上所述, alpha_loss = (self.alpha_log * (log_prob - self.target_entropy).detach()).mean() 就是 alpha_loss = (self.alpha_log * (通过相减来判断实际策略熵是否大于目标策略熵).detach()).mean() detach() 非常重要,使用了它的张量只是一个普通数值,梯度不会通过它传播 我们会最小化或最大化 alpha_loss (调小或调大),完全取决于 实际策略熵是否大于目标策略熵 谁大谁小。

youzhonghui commented 3 years ago

原来如此,讲解的很详细,谢谢分享!

typoverflow commented 3 years ago

您好,关于上面的回复我有一些问题

  1. 关于target entropy,在原论文附录以及一些实现中均初始化为-dim(A),但是在您的代码中初始化为dim(A),请问这样的初始化出于什么考虑?
  2. 您提到

    综上所述, alpha_loss = (self.alpha_log (log_prob - self.target_entropy).detach()).mean() 就是 alpha_loss = (self.alpha_log (通过相减来判断实际策略熵是否大于目标策略熵).detach()).mean()

按照我的理解,由于\pi(a|s)一项被吸收到了期望里,那么真正的“策略熵减目标熵”应当对应于-log_prob - self.target_entropy。直观来看,当“策略熵减目标熵”为正值,alpha的梯度为正,梯度下降使得alpha减小,而alpha减小将导致优化目标更关注Q值,从而使策略不那么“随机”,策略熵减小;反之,如果策略熵小于目标熵,alpha的更新将导致策略熵增大。个人感觉更符合“让实际策略熵log_prob 保持在目标策略熵 target_entropy 附近”的想法。而您的实现中log_prob前并没有负号,请问这是为什么呢?

如果我的上述理解存在问题,请您予以指正,谢谢!

Shapeno commented 8 months ago

alpha_loss = -(self.log_alpha * (log_pi + self.target_entropy).detach()).mean()的写法和原作者有出入,当self.log_alpha为0的时候,这个损失将永远为0,从而导致self.log_alpha永远为0。 原作者的写法为 alpha_loss = -(self.alpha * (log_pi + self.target_entropy).detach()).mean() 乘上alpha而非log_alpha