前言前面讲了强化学习的基本概念这节课来说一说强化学习的策略学习Policy-based算法。在进入正文之前说一句策略学习的目标就是要用一个神经网络来近似策略函数这个神经网络叫做策略网络Policy Network它可以用来控制agent运动想要训练策略网络就要用到Policy Gradient算法该算法是策略学习的核心还有中间计算策略梯度我仅仅是把推导公式列了出来简要的说了一下如果仅仅是应用强化学习算法解决问题中间过程不太懂也没关系就看看最后的策略梯度算法的过程理解一下就可以了一、策略学习1.1 策略函数πa|s它是一个概率密度函数可以用来自动控制agent运动它的输入是当前的状态s输出是一个概率分布以超级玛丽这个游戏为例假设给定当前状态s后策略函数输出三个概率值向左向右和向上跳的概率分别为0.2,0.1和0.7代码如下示例这个例子里输入是状态s输出是一个3行1列的列向量向量的每一个元素是动作的概率有了这三个概率值agent做一次随机抽样就得到了动作a三个动作都有可能被抽到但是向上的动作被抽到的概率最大抽出动作a后agent就做动作a2.求得策略网络的过程以游戏为例如果一个游戏只有五个状态十个动作那就有一个5*10的表格那就很简单了我们通过玩这个游戏把表里的每个概率算出来超级玛丽这样的游戏有无穷的状态根本不可能把每个状态可能采取的动作都记录在一张表格里超级玛丽这个游戏我们就没有办法直接计算策略函数大部分情况下都没有办法直接计算策略函数所以要做函数近似函数近似的方法有很多种线性函数kernel函数神经网络我们当然是要用神经网络去近似策略函数喽-;我们使用πa|s;θ近似πa|sθ是神经网络的参数一开始并不知道是随机初始化的通过学习来改进θ介绍完策略学习的一些概念后开始介绍策略学习喽1.2 策略学习我们的目标就是近似Vπ(st)Vπ(st)是对状态价值函数求的期望值那么根据agent采取的动作是离散值还是连续值下面是action为离散和连续的时候Vπ(st)的计算公式我们使用神经网络来近似Vπ(st)把Vπ(st)的π即策略函数用神经网络来近似Vπ(st)就变成了下面的形式Qusetion怎么样让策略网络变得越来越好呢答案就是改进模型参数θ让Vst;θ变得越来越大因此我们就把目标函数定义为了Vst;θ的期望这个期望是关于状态s求的把状态s作为随机变量求其期望值s就被去掉了就是一个关于θ的函数了那就让Jθ越大越好要让Jθ越来越大就需要使用策略梯度Policy Gradient的方法让agent玩游戏每一步观测到不同的状态s状态s相当于从状态的概率分布随机抽样得到的把Vs;θ关于θ求导得到它的梯度后用梯度上升的方法来更新θ这很类似于随机梯度上升随机性来源于状态s我们计算的应该Jθ关于θ的导数这才是更新θ用到的梯度这里我们计算的是Vs;θ关于θ的导数因为我们不可能在开始玩游戏的时候就知道所有的状态sVs;θ关于θ的导数被称为策略梯度1.3 计算策略梯度Policy Gradient在计算梯度时我们假设Qπs,a不依赖于策略π事实上是依赖于π的仅仅是为了方便理解不是特别严谨如果你只是用策略梯度的算法这么理解就可以了最终得到计算策略梯度的公式注意上面计算Vs;θ关于θ的导数是action是连续值的时候action为离散值的情况很简单直接在最后列出离散值情况的公式了最终我们得到了action为离散值和连续值两种情况的公式1.4 策略梯度算法的过程在t时刻观测到状态st然后用蒙特卡洛近似来计算策略梯度把策略网络π作为概率密度函数用策略网络π随机抽样得到一个动作at计算动作价值函数的值把结果即为qt对策略网络π求导算出对于θ的梯度近似的计算策略梯度更新策略网络一个问题我们并不知道怎么计算qt即动作价值函数的值两种方法1.REINFORCE一种叫做REINFORCE的算法用策略网络π来控制agent运动一直玩到游戏结束把整个游戏的轨迹记录下来s1,a1,r1,s2,a2,r2,…,st,at,rt;观测到所欲的奖励rt就计算出来ut注意这里的ut是Ut的观测值因为Qπst,at EUt我们用观测值ut代替Qπst,at即qtut这是一种近似2.用神经网络近似Qπ这样就用了两个神经网络近似Qπs,a的神经网络qs,a;w称为价值网络被称为critic另一个近似πa|s的神经网络称为策略网络πa|s,θ称为actor这样就引出了actor-critic method接下来会介绍acrot-critic method二、REINFORCE算法代码示例defreinforce(env_name,learning_rate0.001,gamma0.99,num_episodes1000):envgym.make(env_name)state_dimenv.observation_space.shape[0]action_dimenv.action_space.n policy_netPolicyNetwork(state_dim,action_dim)optimizeroptim.Adam(policy_net.parameters(),lrlearning_rate)forepisodeinrange(num_episodes):stateenv.reset()states,actions,rewards[],[],[]doneFalse# 收集轨迹数据whilenotdone:state_tensortorch.FloatTensor(state)action_probspolicy_net(state_tensor)# 通过策略网络得到动作概率actionnp.random.choice(action_dim,paction_probs.detach().numpy())# 根据概率选择动作next_state,reward,done,_env.step(action)states.append(state)actions.append(action)rewards.append(reward)statenext_state# 计算回报returns[]G0forrinreversed(rewards):Grgamma*G# 从后往前计算累计回报returns.insert(0,G)# 将G插入到列表最前面这样returns就是正序的returnstorch.FloatTensor(returns)# 标准化回报减少方差returns(returns-returns.mean())/(returns.std()1e-9)# 更新策略statestorch.FloatTensor(states)# 将状态列表转换为Tensoractionstorch.LongTensor(actions)# 将动作列表转换为Tensorlog_probstorch.log(policy_net(states))# 计算所有状态对应所有动作的对数概率# policy_net(states)输入多个状态输出每个状态对应的动作概率分布# 形状[batch_size, action_dim]# 例如如果有3个状态2个动作 → [[0.7, 0.3], [0.2, 0.8], [0.5, 0.5]]# torch.log()计算对数概率# 转换后[[log(0.7), log(0.3)], [log(0.2), log(0.8)], [log(0.5), log(0.5)]]# 形状保持不变[batch_size, action_dim]# 选择每个状态实际执行的动作的对数概率# actions [1, 0, 1] 实际执行的动作序列# log_probs tensor([[-0.357, -1.204], # 状态1: [log(0.7), log(0.3)] [-1.609, -0.223], # 状态2: [log(0.2), log(0.8)] [-0.693, -0.693]]) # 状态3: [log(0.5), log(0.5)]# 索引过程# np.arange(len(actions)) [0, 1, 2] ← 状态索引# actions [1, 0, 1] ← 动作索引# selected_log_probs [# log_probs[0, 1], # 状态0动作1 → -1.204# log_probs[1, 0], # 状态1动作0 → -1.609# log_probs[2, 1] # 状态2动作1 → -0.693# ]# 结果tensor([-1.204, -1.609, -0.693])selected_log_probslog_probs[np.arange(len(actions)),actions]# 损失函数负的加权对数概率权重为回报# 对应上面公式g(at,θt) Qt·dθ,tloss-(returns*selected_log_probs).sum()optimizer.zero_grad()loss.backward()optimizer.step()ifepisode%1000:print(fEpisode{episode}, Total Reward:{sum(rewards)})env.close()总结以上就是今天要讲的内容本文仅仅简单介绍了策略学习方法如有错误请谅解并指正。