hijkzzz / pymarl2

Fine-tuned MARL algorithms on SMAC (100% win rates on most scenarios)
https://iclr-blogposts.github.io/2023/blog/2023/riit/
Apache License 2.0
633 stars 124 forks source link

动作探索选择的问题 #10

Closed liushunyu closed 3 years ago

liushunyu commented 3 years ago

我比较了一下 pymarl 和 pymarl2 的代码

发现在 pymarl 的 basic_controller.py 中的这个动作探索选择 https://github.com/oxwhirl/pymarl/blob/c971afdceb34635d31b778021b0ef90d7af51e86/src/controllers/basic_controller.py#L40-L48

if not test_mode:
    # Epsilon floor
    epsilon_action_num = agent_outs.size(-1)
    if getattr(self.args, "mask_before_softmax", True):
        # With probability epsilon, we will pick an available action uniformly
        epsilon_action_num = reshaped_avail_actions.sum(dim=1, keepdim=True).float()

    agent_outs = ((1 - self.action_selector.epsilon) * agent_outs
                   + th.ones_like(agent_outs) * self.action_selector.epsilon/epsilon_action_num)

被移动到了 action_selectors.py 中 https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/components/action_selectors.py#L94-L97

而且计算方式貌似在是否mask上有所不同,请问一下为什么要这样改动哇

hijkzzz commented 3 years ago

基本上是一样的~~~只是原来那样太乱了,探索统一放到 selectors 里面。在VMIX下测试貌似更稳定

liushunyu commented 3 years ago

好的,另外还有一个小问题哈,我发现在 episode_runner.py 你们改动了一下,将 action 放到 cpu上再 update 到 batch 里面 https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/runners/episode_runner.py#L68-L80

但其实在 batch 的 update 函数里有一行是把变量放到 gpu 上(如果使用 gpu),这样你们前面先从 gpu 放回 cpu 是不是有点冗余,还是出于什么原因考虑的呢? https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/components/episode_buffer.py#L103

hijkzzz commented 3 years ago

因为buffer 的数据是放在cpu内存中的,所以移过来释放gpu显存。

liushunyu commented 3 years ago

我debug跟了一下代码,self.batch 是在这里用 self.new_batch() 定义的

https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/runners/episode_runner.py#L44

而 self.new_batch() 的初始化使用了 self.args.device,如果当前 device 是 cuda 的话就会使用 cuda https://github.com/hijkzzz/pymarl2/blob/3f894bc24a8dbdf7d642dcfb5f107cd15d02d200/src/runners/episode_runner.py#L30

从而导致这一步的 self.device 是 cuda https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/components/episode_buffer.py#L103

然后我看了一下 buffer 的定义是用 cpu 存储的 https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/run/run.py#L113-L115

这里的逻辑应该是先得到 episode_batch (在 gpu 上),再加入到 buffer 中(加入buffer时会将变量放到 cpu 上) https://github.com/hijkzzz/pymarl2/blob/d0aaf583605b2b012a1fd080eb6880a00954ed28/src/run/run.py#L177-L178

那么在生成 episode_batch 的过程中先从 gpu 转 cpu,又被转回 gpu 就有点冗余了好像?在后面加入 buffer 时都会放 cpu上,不知道我理解有没有问题~

hijkzzz commented 3 years ago

你观察的很仔细 这么看 new_batch 的时候要用cpu~

liushunyu commented 3 years ago

嗯嗯有道理,谢谢啦