深度强化学习实践 Maxim Lapan 章节12:actor-critic方法

写在前面

强化学习导论里面就已经学习过这种方法了,通过添加基线的方法,同时学习value函数和策略函数,更好的收敛,OK,开干

核心

提炼文中关于这个方法有效性的最核心的一个介绍

如果三个动作 a1,a2,a3a_1,a_2,a_3a1,a2,a3的价值Q1,Q2,Q3Q_1,Q_2,Q_3Q1,Q2,Q3,如果3的价值是负值,按照我们的策略梯度原理会学习到更多的执行动作1,2,但是如果奖励都是正的,那么策略会学习到三个动作都尝试增大,只是值更大的增加的更多,所以为了更好的学习,我们尝试减去这个平均值(更好的区分好的和坏的动作)

考虑到梯度的缩放的问题,将所有的奖励平均到均值为0的正太分布更好的梯度大小策略。

CartPole方差

带基线版本

原文中通过统计reward的值,并且计算均值来获得基线,并且在reward添加的时候修改了奖励值

        reward_sum += exp.reward
        baseline = reward_sum / (step_idx + 1)
        writer.add_scalar("baseline", baseline, step_idx)
        batch_states.append(exp.state)
        batch_actions.append(int(exp.action))
        if args.baseline:
            batch_scales.append(exp.reward - baseline)
        else:
            batch_scales.append(exp.reward)

梯度迭代的时候,分了两次进行梯度计算,第一次只是进行了policy的grad,并且保存了下来,然后继续使用entropy的损失进行梯度叠加,最后一次性经过了优化器优化

        optimizer.zero_grad()
        logits_v = net(states_v)
        log_prob_v = F.log_softmax(logits_v, dim=1)
        log_p_a_v = log_prob_v[range(BATCH_SIZE), batch_actions_t]
        log_prob_actions_v = batch_scale_v * log_p_a_v
        loss_policy_v = -log_prob_actions_v.mean()

        loss_policy_v.backward(retain_graph=True)
        grads = np.concatenate([p.grad.data.numpy().flatten()
                                for p in net.parameters()
                                if p.grad is not None])

        prob_v = F.softmax(logits_v, dim=1)
        entropy_v = -(prob_v * log_prob_v).sum(dim=1).mean()
        entropy_loss_v = -ENTROPY_BETA * entropy_v
        entropy_loss_v.backward()
        optimizer.step()

        loss_v = loss_policy_v + entropy_loss_v

所有的节点p在net.parameters的grad,展平成numpy flatten,然后再相互concatenate成一个一维的数组

        grads = np.concatenate([p.grad.data.numpy().flatten()
                                for p in net.parameters()
                                if p.grad is not None])

通过grads获取到的策略梯度,进行计算我们的l2,max,var的值,有基线的版本,显然要得到更好的收敛性

        g_l2 = np.sqrt(np.mean(np.square(grads)))
        g_max = np.max(np.abs(grads))
        writer.add_scalar("grad_l2", g_l2, step_idx)
        writer.add_scalar("grad_max", g_max, step_idx)
        writer.add_scalar("grad_var", np.var(grads), step_idx)

我的本地的环境感觉更加的不稳定,所以我这边的会出现很大的熵值表大的情况,整体来说还是好了很多
在这里插入图片描述

A2C

其实我们前面的已经用到了这个方法了,A值策略和V值策略,但是之前好像分布的是A值的价值函数,但是V值也是价值函数,我们这里的A值返回的是策略(动作的概率),

详细的修改,类似于前面的duel的网络,这里Actor类似于前面的动作优势函数,V值表示状态的价值函数
在这里插入图片描述

梯度

注意这里的梯度有两个,一个是action的prob,一个是value, value直接使用了mse的损失函数,动作函数使用了真实的reward,还有熵损失

细节一:adv_v = vals_ref_v - value_v.detach(), 这里使用了detach,是为了不将这里的计算引入到value的损失函数中去
细节二: 这里减去了value,就是我们的价值函数了
细节三: entropy loss是用来改善探索的

                optimizer.zero_grad()
                logits_v, value_v = net(states_v)
                loss_value_v = F.mse_loss(value_v.squeeze(-1), vals_ref_v)

                log_prob_v = F.log_softmax(logits_v, dim=1)
                adv_v = vals_ref_v - value_v.detach()
                log_prob_actions_v = adv_v * log_prob_v[range(BATCH_SIZE), actions_t]
                loss_policy_v = -log_prob_actions_v.mean()

                prob_v = F.softmax(logits_v, dim=1)
                entropy_loss_v = ENTROPY_BETA * (prob_v * log_prob_v).sum(dim=1).mean()

                # calculate policy gradients only
                loss_policy_v.backward(retain_graph=True)
                grads = np.concatenate([p.grad.data.cpu().numpy().flatten()
                                        for p in net.parameters()
                                        if p.grad is not None])

                # apply entropy and value gradients
                loss_v = entropy_loss_v + loss_value_v
                loss_v.backward()
                nn_utils.clip_grad_norm_(net.parameters(), CLIP_GRAD)
                optimizer.step()

结果

我跑了2个多小时的情况下,完全没有收敛,原文中,前面的大半个小时也是完全不动的,原文说跑了三个多小时,而且用的是优化后的参数

参数优化

原文的超参,包括学习率 0.003 ,熵的beta 介于0.02和0.03之间,环境数40-70,批大小16,32,64

写在后面

我的电脑是因为效率太低了还是怎么滴,反正收敛速度非常慢,我一直怀疑我的电脑环境是不是有些库没有兼容好,有没有遇到过同样的问题的人帮我看看?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值