【李宏毅】HW12

news2024/9/20 14:48:20

HW12

  • 一、作业描述
    • 1、Policy Gradient
    • 2、Actor-Critic
  • 二、实验
    • 1、simple
    • 2、medium
    • 3、strong
  • 三、代码


一、作业描述

在这个HW中,你可以自己实现一些深度强化学习方法:
1、策略梯度Policy Gradient
2、Actor-Critic
这个HW的环境是OpenAI gym的月球着陆器。希望这个月球着陆器落在两个旗子中间。
什么是月球着陆器?
“LunarLander-v2”是模拟飞行器在月球表面着陆时的情况。
这项任务是使飞机能够“安全地”降落在两个黄色旗帜之间的停机坪上。着陆平台始终位于坐标(0,0)处。坐标是状态向量中的前两个数字。“LunarLander-v2”实际上包括“代理”和“环境”。在本作业中,我们将利用函数“step()”来控制“代理”的动作。
那么‘step()’将返回由“环境”给出的观察/状态和奖励…
在这里插入图片描述
Box(8,)意味着观察是一个8维向量

在这里插入图片描述

‘Discrete(4)’意味着代理可以采取四种行动。

  • 0表示代理不会采取任何操作
  • 2意味着代理将向下加速
  • 1,3意味着代理将向左和向右加速

接下来,我们将尝试让代理与环境进行交互。
在采取任何行动之前,我们建议调用’ reset()'函数来重置环境。此外,该函数将返回环境的初始状态。
在这里插入图片描述

1、Policy Gradient

直接根据状态输出动作或者动作的概率。那么怎么输出呢,最简单的就是使用神经网络。网络应该如何训练来实现最终的收敛呢?反向传播算法,我们需要一个误差函数,通过梯度下降来使我们的损失最小。但对于强化学习来说,我们不知道动作的正确与否,只能通过奖励值来判断这个动作的相对好坏。如果一个动作得到的reward多,那么我们就使其出现的概率增加,如果一个动作得到的reward少,我们就使其出现的概率减小。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

每次循环都要收集很多数据才进行一次参数更新。

2、Actor-Critic

在这里插入图片描述
在这里插入图片描述
增加基准判断这个动作是否是真的好!
在这里插入图片描述
分配不同的权重

在这里插入图片描述
组合衰减因子。

二、实验

1、simple

#torch.set_deterministic(True)
torch.use_deterministic_algorithms(True)

training result:在这里插入图片描述
testing:在这里插入图片描述
test reward:在这里插入图片描述
server:
在这里插入图片描述
score:在这里插入图片描述

2、medium

……
NUM_BATCH = 500        # totally update the agent for 400 time
rate = 0.99
……
        while True:

            action, log_prob = agent.sample(state) # at, log(at|st)
            next_state, reward, done, _ = env.step(action)

            log_probs.append(log_prob) # [log(a1|s1), log(a2|s2), ...., log(at|st)]
            seq_rewards.append(reward)
            state = next_state
            total_reward += reward
            total_step += 1
            
            if done:
                final_rewards.append(reward)
                total_rewards.append(total_reward)
                # calculate accumulative rewards
                for i in range(2, len(seq_rewards)+1):
                    seq_rewards[-i] += rate * (seq_rewards[-i+1])
                rewards += seq_rewards
                
                break

training result:
在这里插入图片描述
在这里插入图片描述

testing:
在这里插入图片描述

test reward:
在这里插入图片描述
在这里插入图片描述

server:
在这里插入图片描述

score:

在这里插入图片描述

3、strong

from torch.optim.lr_scheduler import StepLR
class ActorCritic(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Sequential(
            nn.Linear(8, 16),
            nn.Tanh(),
            nn.Linear(16, 16),
            nn.Tanh()
        )
        
        self.actor = nn.Linear(16, 4)
        self.critic = nn.Linear(16, 1)
        
        self.values = []
        self.optimizer = optim.SGD(self.parameters(), lr=0.001)
        
    def forward(self, state):
        hid = self.fc(state)
        self.values.append(self.critic(hid).squeeze(-1))
        return F.softmax(self.actor(hid), dim=-1)
    
    def learn(self, log_probs, rewards):
        values = torch.stack(self.values)
        loss = (-log_probs * (rewards - values.detach())).sum() 
        self.optimizer.zero_grad()
        loss.backward()
        
        self.optimizer.step()
        
        self.values = []
        
    def sample(self, state):
        action_prob = self(torch.FloatTensor(state))
        action_dist = Categorical(action_prob)
        action = action_dist.sample()
        log_prob = action_dist.log_prob(action)
        return action.item(), log_prob
        

training result:

在这里插入图片描述

在这里插入图片描述

testing:

在这里插入图片描述

test reward:
在这里插入图片描述

在这里插入图片描述

server:
在这里插入图片描述

score:
在这里插入图片描述

三、代码

** 准备工作**
首先,我们需要安装所有必要的软件包。
其中一个是由OpenAI构建的gym,它是一个开发强化学习算法的工具包。
在这里插入图片描述
可以利用“step()”使代理按照随机选择的“random_action”动作。
“step()”函数将返回四个值:
-观察/状态
-奖励
-完成 done(对/错)
-其他信息

observation, reward, done, info = env.step(random_action)
print(done)

在这里插入图片描述
奖励
着陆平台始终位于坐标(0,0)处。坐标是状态向量中的前两个数字。奖励从屏幕顶部移动到着陆垫和零速度大约是100…140分。如果着陆器离开着陆平台,它将失去回报。如果着陆器崩溃或停止,本集结束,获得额外的-100或+100点。每个支腿接地触点为+10。点燃主引擎每帧扣-0.3分。解决了就是200分。
随机代理
开始训练之前,我们可以看看一个随机的智能体能否成功登陆月球。

env.reset()

img = plt.imshow(env.render(mode='rgb_array'))

done = False
while not done:
    action = env.action_space.sample()
    observation, reward, done, _ = env.step(action)

    img.set_data(env.render(mode='rgb_array'))
    display.display(plt.gcf())#展示当前图窗的句柄
    display.clear_output(wait=True)

在这里插入图片描述
政策梯度
现在,我们可以建立一个简单的政策网络。网络将返回动作空间中的一个动作。

class PolicyGradientNetwork(nn.Module):

    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(8, 16)
        self.fc2 = nn.Linear(16, 16)
        self.fc3 = nn.Linear(16, 4)

    def forward(self, state):
        hid = torch.tanh(self.fc1(state))
        hid = torch.tanh(self.fc2(hid))
        return F.softmax(self.fc3(hid), dim=-1)

然后,我们需要构建一个简单的代理。代理将根据上述策略网络的输出进行操作。代理可以做几件事:

  • learn():根据对数概率和奖励更新策略网络。
  • sample():在从环境接收到观察之后,利用策略网络来告知要采取哪个动作。该函数的返回值包括动作概率和对数概率。
from torch.optim.lr_scheduler import StepLR
class PolicyGradientAgent():
    
    def __init__(self, network):
        self.network = network
        self.optimizer = optim.SGD(self.network.parameters(), lr=0.001)
        
    def forward(self, state):
        return self.network(state)
    def learn(self, log_probs, rewards):
        loss = (-log_probs * rewards).sum() # You don't need to revise this to pass simple baseline (but you can)

        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()
        
    def sample(self, state):
        action_prob = self.network(torch.FloatTensor(state))
        action_dist = Categorical(action_prob)
        action = action_dist.sample()
        log_prob = action_dist.log_prob(action)
        return action.item(), log_prob

训练代理
现在让我们开始训练我们的代理人。
通过将代理和环境之间的所有交互作为训练数据,策略网络可以从所有这些尝试中学习。

agent.network.train()  # Switch network into training mode 
EPISODE_PER_BATCH = 5  # update the  agent every 5 episode
NUM_BATCH = 500        # totally update the agent for 400 time

avg_total_rewards, avg_final_rewards = [], []

prg_bar = tqdm(range(NUM_BATCH))#进度条
for batch in prg_bar:

    log_probs, rewards = [], []
    total_rewards, final_rewards = [], []

    # collect trajectory
    for episode in range(EPISODE_PER_BATCH):
        
        state = env.reset()
        total_reward, total_step = 0, 0
        seq_rewards = []
        while True:

            action, log_prob = agent.sample(state) # at, log(at|st)
            next_state, reward, done, _ = env.step(action)

            log_probs.append(log_prob) # [log(a1|s1), log(a2|s2), ...., log(at|st)]
            # seq_rewards.append(reward)
            state = next_state
            total_reward += reward
            total_step += 1
            rewards.append(reward) # change here
            # ! IMPORTANT !
            # Current reward implementation: immediate reward,  given action_list : a1, a2, a3 ......
            #                                                         rewards :     r1, r2 ,r3 ......
            # medium:change "rewards" to accumulative decaying reward, given action_list : a1,                           a2,                           a3, ......
            #                                                           rewards :           r1+0.99*r2+0.99^2*r3+......, r2+0.99*r3+0.99^2*r4+...... ,  r3+0.99*r4+0.99^2*r5+ ......
            # boss : implement Actor-Critic
            if done:
                final_rewards.append(reward)
                total_rewards.append(total_reward)
                
                break

    print(f"rewards looks like ", np.shape(rewards))  
    print(f"log_probs looks like ", np.shape(log_probs))     
    # record training process
    avg_total_reward = sum(total_rewards) / len(total_rewards)
    avg_final_reward = sum(final_rewards) / len(final_rewards)
    avg_total_rewards.append(avg_total_reward)
    avg_final_rewards.append(avg_final_reward)
    prg_bar.set_description(f"Total: {avg_total_reward: 4.1f}, Final: {avg_final_reward: 4.1f}")

    # update agent
    # rewards = np.concatenate(rewards, axis=0)
    rewards = (rewards - np.mean(rewards)) / (np.std(rewards) + 1e-9)  # normalize the reward ,std求标准差
    agent.learn(torch.stack(log_probs), torch.from_numpy(rewards))#torch.from_numpy创建一个张量,torch.stack沿一个新维度对输入张量序列进行连接,序列中所有张量应为相同形状
    print("logs prob looks like ", torch.stack(log_probs).size())
    print("torch.from_numpy(rewards) looks like ", torch.from_numpy(rewards).size())

训练结果
在训练过程中,我们记录了“avg_total_reward ”,它表示在更新策略网络之前集的平均总奖励。理论上,如果代理变得更好,avg_total_reward会增加。

plt.plot(avg_total_rewards)
plt.title("Total Rewards")
plt.show()

此外,“avg_final_reward”表示集的平均最终奖励。具体来说,最终奖励是一集最后收到的奖励,表示飞行器是否成功着陆。

plt.plot(avg_final_rewards)
plt.title("Final Rewards")
plt.show()

测试
测试结果将是5次测试的平均奖励

fix(env, seed)
agent.network.eval()  # set the network into evaluation mode
NUM_OF_TEST = 5 # Do not revise this !!!
test_total_reward = []
action_list = []
for i in range(NUM_OF_TEST):
  actions = []
  state = env.reset()

  img = plt.imshow(env.render(mode='rgb_array'))

  total_reward = 0

  done = False
  while not done:
      action, _ = agent.sample(state)
      actions.append(action)
      state, reward, done, _ = env.step(action)

      total_reward += reward

      img.set_data(env.render(mode='rgb_array'))
      display.display(plt.gcf())
      display.clear_output(wait=True)
      
  print(total_reward)
  test_total_reward.append(total_reward)

  action_list.append(actions) # save the result of testing 

动作分布

distribution = {}
for actions in action_list:
  for action in actions:
    if action not in distribution.keys():
      distribution[action] = 1
    else:
      distribution[action] += 1
print(distribution)

服务器
下面的代码模拟了judge服务器上的环境。可用于测试。

action_list = np.load(PATH,allow_pickle=True) # The action list you upload
seed = 543 # Do not revise this
fix(env, seed)

agent.network.eval()  # set network to evaluation mode

test_total_reward = []
if len(action_list) != 5:
  print("Wrong format of file !!!")
  exit(0)
for actions in action_list:
  state = env.reset()
  img = plt.imshow(env.render(mode='rgb_array'))

  total_reward = 0

  done = False

  for action in actions:
  
      state, reward, done, _ = env.step(action)
      total_reward += reward
      if done:
        break

  print(f"Your reward is : %.2f"%total_reward)
  test_total_reward.append(total_reward)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu | 重装ubuntu(VMware虚拟机环境)

前言 最近又把双系统的ubuntu搞崩了,在grub界面进不去,估计找不到启动项,被迫重装。 这次觉得还是windows系统好使,就用vmware虚拟机了。 一、安装vmware虚拟机 参考我之前的博客。 二、安装ubuntu 下载ubuntu18.04的iso文件…

15.2 浏览器中的进程

浏览器中的进程 start 上一篇文章,学习到了如何区分进程和线程。在这里再复习一下,进程类似于一个工厂,线程类似于工厂的工人,一个工厂可以有一个或多个工人。 1. 浏览器的进程 一个浏览器中有很多的进程,我以谷歌…

2023年的摸鱼小技巧:Python自动生成请假条【思路详解】

嗨害大家好鸭!我是小熊猫~ 这不2023到了,新的一年,新的摸鱼 在办公室里的小透明来实现用Python来批量生成请假条, 这波啊,这波是智取!!! Python资料电子书:点击此处跳转文末名片获…

Excel函数公式大全—SUMIF/SUMIFS函数

EXCEL系列文章目录 Excel系列文章是本人亲身经历职场之后萌发的想法,为什么Excel覆盖如此之广,几乎每个公司、学校、家庭都在使用,但是它深藏的宝藏功能却很少被人使用,PQ、BI这些功能同样适用于数据分析;并且在一些需…

内部成员之五:内部类

文章目录一、内部类分类:成员内部类vs局部内部类成员内部类实例化成员内部类每日一考一、内部类 1、Java中允许将类A声明在类B中,则类A就是内部类,类B为外部类。 分类:成员内部类vs局部内部类 成员内部类(静态、非静…

【ElasticSearch7.X】学习笔记(三)

【ElasticSearch7.X】学习笔记五、集群部署5.1、相关概念5.1.1、集群 Cluster3.1.2、节点 Node5.2、下载安装5.3、 启动5.4、 测试六、进阶6.1、核心概念6.1.1、索引(Index)6.1.2、类型(Type)6.1.3、文档(Document&…

Handler的学习

一、Handler到底有什么用呢? 首先看以下案例: public class MainActivity extends AppCompatActivity { Button btn;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activi…

vue这些原理你都知道吗?(面试版)

前言 在之前面试的时候我自己也经常会遇到一些vue原理的问题, 我也总结了下自己的经常的用到的,方便自己学习,今天也给大家分享出来, 欢迎大家一起学习交流, 有更好的方法欢迎评论区指出, 后序我也将持续整理总结~ 描述 Vue 与 React 区别 说明概念: vue:是一套用于构建用户…

虚拟化技术学习笔记3

1、KVM虚拟机管理工具部署 学习目标: 能够为KVM虚拟机管理工具部署准备环境 能够部署KVM虚拟机管理工具 1、KVM系统需求: 1)Host system requirements: 1核心、2G内存、6G硬盘 2)KVM hypervisor requirements: l…

U3D客户端框架(资源管理篇)之主资源加载器模块设计实现

一、主资源加载器模块设计实现 作用 主资源加载器是为面向用户而设计的上层应用层类,用户使用主资源加载器作为文件加载器加载文件, 加载器可以通过Assetbundle方式加载,Http方式加载资源。 UML类图设计 前置模块 主资源加载器需要引用到一…

Qt扫盲-QHash理论总结

QHash理论总结一、概述二、使用1. 添加 元素2. 获取元素3. 遍历元素4. 删除元素5. qHash()的散列函数6.算法复杂性一、概述 QHash是Qt的通用容器类之一。它和QMap一样是用来存储(键,值)对的工具,并提供快速查找与键相关联的值的功能。 QHash提供了与QMa…

密码学的一些常识01

序 作为一个小白,对称加密,非对称加密,数字签名,数字证书,CA,diff-helman,DES,AED,RSA……这些都不会。所以,百度启动,先初步了解。 实际应用 我是个小白……0基础的&…

sklearn中精确率、召回率及F1值得micro,macro及weighted算法

为什么要用精确率和召回率 有这样一个训练集,1000个人参加了结直肠癌CRC的检测,实际有0.5%的人得了CRC(即5个人)。用神经网络算法得到检测这样一个训练集能达到99%的准确率。从数值上判断该算法是不错的,因为只有1%的误…

springboot+disruptor再体验

Disruptor是一个高性能队列,常见的还有kafka、rabbitmq等,下面体验一下~ 1、Disruptor简介 Disruptor 是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的…

[C++]STL之string的模拟实现

上一章我们对string的常见接口及使用进行了讲解,接下来我们将对一些常见的接口,包括构造函数,析构函数,运算符重载等等进行模拟实现.方便我们理解string接口实现的原理. 在讲解之前先说一下string的成员变量. 首先是字符串内容_…

微信小程序picker组件遇到的问题以及解决办法

一、picker基本概念二、遇到的问题三、如何解决四、延伸五、效果图一、picker基本概念 先来看一下官方文档中picker的基本概念: 从底部弹起的滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器,时间选择器…

Bochs下载安装

文章目录下载Bochs配置BochsBochs Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。事实上,它可以在任何编译运行Bochs的…

【Unity3D编辑器扩展】Unity3D中实现Text的字体的替换

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 在开发中会遇到要将场景中的Text的字体全部替换的情况。 所以…

NetInside网络分析帮您解决系统性能问题(一)

前言 某大学信息中心负责人表示,有用户反馈,在通过VPN访问某一IP的80端口时连接时断时续。同时信息中心给到的信息是通过VPN:XXX.XXX.253.5访问IP地址XXX.XXX.130.200的80端口出现访问时断时续问题。 需要通过分析系统看一下实际情况&#…

云原生周刊 | 人类、机器人与 Kubernetes

近日 Grafana 官网发表了一篇博客介绍了 2022 年比较有意思、脑洞大开的一些 Grafana 使用案例,比如监控特斯拉 Model 3 的充电状态、OTA 更新状况等等。 海事技术供应商 Royal IHC 利用 Grafana 展示客户船队的关键性能指标,例如燃料消耗、服务时间、大…