本篇是我们算法实战的第二篇,针对的是我们在“基础算法篇(六),基于AC框架的PPO算法”中提出的相关算法,具体算法中部分参考了莫烦老师的相关代码,在这里向莫烦老师表示感谢。
Tensorflow实现Actor-Critic框架下的经典PPO算法
一、基础游戏背景介绍
在这次代码实现中,为了体现与前面离散型输出的不同,我们特意选择了Gym中的转动杆游戏,如下图:
游戏的目标就是给转动杆一个力,最终让它能够稳定的立起来。这个游戏与DQN中使用的“活动杆小车”游戏不同的是,这个游戏的输入action_space是一个Box(1,)类型,即一个float的连续值。同时,这个游戏的输出observation_space是一个Box(3,)类型,是三个float的数组。
其他关于编程环境的搭建,请大家参考“番外篇,强化学习基础环境搭建”
下面我们正式进入我们的程序。
二、主函数
同样的,让我们先看main()函数:
def main():
# first, create the envrioment of 'Pendulum-v0'
# the game Pendulum-v0's observation_space is Box(3,), it means the observation has three var and each one is float
# the action_space is Box(1,), it means the action has one var and is float
# the output of the game is continuous, not discrete
env = gym.make(ENV_NAME).unwrapped
# second, create the PPO agent. it is based the AC arch, so it has two type of network
# the critic which give the value of the state
# the actor which give the action
agent = PPO(env.observation_space, env.action_space)
for episode in range(EPISODES):
# every episode reset the memory
agent.resetMemory()
# get the initial state
state = env.reset()
# this is the total reward
ep_r = 0
for step in range(STEPS):
# show the game window
env.render()
# output the action
action = agent.Choose_Action(state)
# process the action and get the info
next_state, reward, done, info = env.step(action)
# store the date to update the model
agent.Store_Data(state, action, reward, next_state, done)
# train the agent every BATCH_SIZE
if (step + 1) % BATCH_SIZE == 0 or step == STEPS - 1:
agent.Train(next_state)
# set the new state
state = next_state
# record the reward
ep_r += reward
if step == STEPS - 1:
agent.UpdateActorParameters()
# caculate the total reward in every episode
if episode == 0:
all_ep_r.append(ep_r)
else:
all_ep_r.append(all_ep_r[-1] * 0.9 + ep_r * 0.1)
print(
'Ep: %i' % episode,
"|Ep_r: %i" % ep_r,
("|Lam: %.4f" % METHOD['lam']) if METHOD['name'] == 'kl_pen' else '',
)
上述主函数主要分为以下几步(针对每一行代码):
- 1.生成环境对象env
- 2.生成PPO对象agent
- 3.开始每一幕(Episode)循环
- 4.首先重置agent存储的数据,将上一幕存储的数据清零
- 5.得到环境的初始状态
- 6.设置记录这一幕reward的变量
- 7.开始这一幕中每一步(Step)的循环
- 8.首先显示游戏窗口
- 9.基于状态state,利用agent生成行动action
- 10.将action输入环境,得到下一个状态next_state和实时收益reward等数据
- 11.存储相关数据
- 12.如果满足训练条件,则进行agent的训练,用梯度下降更新相关Critic和Actor网络参数
- 13.将最新得到的下一个状态,改为现有状态
- 14.判断是否是最后一个step,如果是,则执行两个actor参数的拷贝更新,否则继续执行步循环,直到走完设计的步数
- 15.后续的代码是记录每个Episode的总得分,并将其存储和打印出来
我们可以看出,从主函数角度来讲,与DQN的函数基本一致,区别在于这里是每个Episode直接打印结果。
下面,我们来详细介绍基于Actor-Critic框架的PPO类。
三、Agent类
在“基础算法篇(六),基于AC框架的PPO算法”中我们介绍了相关算法,这里我们是严格按照算法进行的实现,其中网络构建了两类三个:
- 价值网络(Critic),一个网络,输入是环境的状态,输出是这个状态的价值;
- 策略网络(Actor),两个网络,一个用来与环境交互,另一个进行参数更新,这种方式主要用来解决经典PG算法中的“采集数据不能够重复使用的问题”。
下面我们详细介绍相关代码实现部分。
(一)PPO类的初始化函数
PPO类的初始化主要是导入观测空间和行动空间的大小,并根据这两个量生成相应的策略和价值网络,具体代码如下:
def __init__(self, observation_space, action_space):