存在一个共享的网络,有多个线程是这个共享网络的拷贝,每个线程用这个网络进行与环境交互、训练。这样可以达到提高训练样本多样性的目的。
(1)一个网络的类,ACnet,包含了动作网络、分值网络
(2)class Worker(object) ,每个用来独立训练共享网络的线程,只要执行这个worker.work(),就会开始训练共享网络。
然后就是一个for循环,执行worker.work(),就会更新共享网络的参数。
各个线程在代码中没有任何的通信,只是去更新共享网络参数,并周期的读取共享网络参数。
动作选择是随机选择的。
参考自:
https://github.com/uvipen/Super-mario-bros-A3C-pytorch
和CartPole-v0差不多,区别:
(1)模型是卷积模型,共享特征提取层
本质原理:
看了源码,比critic-actor强的无非就是加个多线程收集更多的数据。
伪代码:
线程i:
循环:
(0)提取global model权重
(1)环境交互一定轮数
(2)更新global model权重,不更新自己权重
(3)重复(0)
然后就是多个线程异步的执行各个线程;
total_loss = -actor_loss + critic_loss - opt.beta * entropy_loss
这个计算解读:
entropy_loss是actor的输出算的:
policy = F.softmax(logits, dim=1)
log_policy = F.log_softmax(logits, dim=1)
entropy = -(policy * log_policy).sum(1, keepdim=True)
这么算的意义是啥呢?应该是不断的让actor选择这个动作的概率变小,可以理解成一个正则项。
剩余的按照得分的metric都可以推导出来:
actor_loss = actor_loss + log_policy * gae
R = R * opt.gamma + reward
critic_loss = critic_loss + (R - value) ** 2 / 2
(1)多线程报错,可以改成单线程模拟多线程。
(2)目前代码中每一个小关分别是不同的模型。。。这不是搞笑么。。。用a关的模型打b关游戏就是乱打。。有待改进