MAML-RL Pytorch 代码解读 (6) -- maml_rl/envs/bandit.py

MAML-RL Pytorch 代码解读 (6) – maml_rl/envs/bandit.py

基本介绍

在网上看到的元学习 MAML 的代码大多是跟图像相关的,强化学习这边的代码比较少。

因为自己的思路跟 MAML-RL 相关,所以打算读一些源码。

MAML 的原始代码是基于 tensorflow 的,在 Github 上找到了基于 Pytorch 源码包,学习这个包。

源码链接

https://github.com/dragen1860/MAML-Pytorch-RL

文件路径

./maml_rl/envs/bandit.py

import

import numpy as np

import gym
from gym import spaces
from gym.utils import seeding

BernoulliBanditEnv()

阅读这部分代码不太明白 self._tasktask 具体指带的是什么信息。

class BernoulliBanditEnv(gym.Env):
    
    #### 这个类的环境是伯努力分布下的多臂赌博机问题。智能体推动其中 “K” 个手臂,说了 “i” 信息,收到从伯努力分布中采样得到的具有 “pi” 信息的奖励,从[0,1]均匀分布中采样得到的pi被保证。
    """Multi-armed bandit problems with Bernoulli observations, as described
    in [1].

    At each time step, the agent pulls one of the `k` possible arms (actions), 
    say `i`, and receives a reward sampled from a Bernoulli distribution with 
    parameter `p_i`. The multi-armed bandit tasks are generated by sampling 
    the parameters `p_i` from the uniform distribution on [0, 1].

    [1] Yan Duan, John Schulman, Xi Chen, Peter L. Bartlett, Ilya Sutskever,
        Pieter Abbeel, "RL2: Fast Reinforcement Learning via Slow Reinforcement
        Learning", 2016 (https://arxiv.org/abs/1611.02779)
    """
	
    #### 初始类信息。当前环境继承gym.Env()类,k表示维度;那么action_space就是离散的k维度动作空间;observation_space中的状态信息就是一个数据,但是不明白这里为何high=0而不是1;_task接受task字典;_means应该就是将task字典里面的'mean'用元素全部是0.5的K维度向量赋予而成;最后设置随机数。
    def __init__(self, k, task={}):
        super(BernoulliBanditEnv, self).__init__()
        self.k = k

        self.action_space = spaces.Discrete(self.k)
        self.observation_space = spaces.Box(low=0, high=0,
                                            shape=(1,), dtype=np.float32)

        self._task = task
        self._means = task.get('mean', np.full((k,), 0.5, dtype=np.float32))
        self.seed()

    #### 跳转到源码上是numpy的,意思就是获得一组随机数。第一个self.np_random是一个与随机数相关的实例,seed是随机数种子。
    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    #### 因为元学习需要采用很多的任务,因此means得到的是num_tasks(任务数)行和self.k列的随机数矩阵作为均值,tasks对这个矩阵按行拆分成一个个字典,字典的键是"mean"值是每一行作为一个array数组。相当于初始化每个任务的均值是随机数array。
    def sample_tasks(self, num_tasks):
        means = self.np_random.rand(num_tasks, self.k)
        tasks = [{'mean': mean} for mean in means]
        return tasks

    #### 因为元学习有很多的任务,需要重置任务实现切换。用_task形参task,意味着在程序运行中task的初始化可能更原本的初始化不一样。self._means用task字典的”mean“来替代。
    def reset_task(self, task):
        self._task = task
        self._means = task['mean']

    #### 这个reset实现每个任务的重置,重置成初始状态。
    def reset(self):
        return np.zeros(1, dtype=np.float32)
	
    #### assert关键字的作用是检查输出的动作信息在不在动作空间内。mean的意思应该是从action中获得这个赌博机的期望?这里没搞懂。reward的意思是从概率是mean的一重二项分布中抽取奖励信息。观测信息就是一个元素是0的array。
    def step(self, action):
        assert self.action_space.contains(action)
        mean = self._means[action]
        reward = self.np_random.binomial(1, mean)
        observation = np.zeros(1, dtype=np.float32)

        return observation, reward, True, self._task

GaussianBanditEnv()

class GaussianBanditEnv(gym.Env):
    
    #### 这个类的环境是正态分布下的多臂赌博机问题。智能体推动其中 “K” 个手臂,说了 “i” 信息,收到从正态分布中采样得到的均值是 “pi” 且标准差是 ”std“ 且在任务中固定的信息的奖励,从[0,1]均匀分布中采样得到的pi被保证。
    """Multi-armed problems with Gaussian observations.

    At each time step, the agent pulls one of the `k` possible arms (actions),
    say `i`, and receives a reward sampled from a Normal distribution with
    mean `p_i` and standard deviation `std` (fixed across all tasks). The
    multi-armed bandit tasks are generated by sampling the parameters `p_i`
    from the uniform distribution on [0, 1].
    """

    #### 初始类信息。当前环境继承gym.Env()类,k表示维度;std表示标准差;那么action_space就是离散的k维度动作空间;observation_space中的状态信息就是一个数据,但是不明白这里为何high=0而不是1;_task接受task字典;_means应该就是将task字典里面的'mean'用元素全部是0.5的K维度向量赋予而成;最后设置随机数。
    def __init__(self, k, std=1.0, task={}):
        super(GaussianBanditEnv, self).__init__()
        self.k = k
        self.std = std

        self.action_space = spaces.Discrete(self.k)
        self.observation_space = spaces.Box(low=0, high=0,
                                            shape=(1,), dtype=np.float32)

        self._task = task
        self._means = task.get('mean', np.full((k,), 0.5, dtype=np.float32))
        self.seed()

    #### 跳转到源码上是numpy的,意思就是获得一组随机数。第一个self.np_random是一个与随机数相关的实例,seed是随机数种子。
    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    #### 因为元学习需要采用很多的任务,因此means得到的是num_tasks(任务数)行和self.k列的随机数矩阵作为均值,tasks对这个矩阵按行拆分成一个个字典,字典的键是"mean"值是每一行作为一个array数组。相当于初始化每个任务的均值是随机数array。
    def sample_tasks(self, num_tasks):
        means = self.np_random.rand(num_tasks, self.k)
        tasks = [{'mean': mean} for mean in means]
        return tasks

    #### 因为元学习有很多的任务,需要重置任务实现切换。用_task形参task,意味着在程序运行中task的初始化可能更原本的初始化不一样。self._means用task字典的”mean“来替代。
    def reset_task(self, task):
        self._task = task
        self._means = task['mean']

    #### 这个reset实现每个任务的重置,重置成初始状态。
    def reset(self):
        return np.zeros(1, dtype=np.float32)

    #### assert关键字的作用是检查输出的动作信息在不在动作空间内。mean的意思应该是从action中获得这个赌博机的期望?这里没搞懂。reward的意思是从概率是mean的一重二项分布中抽取奖励信息。观测信息就是一个元素是0的array。
    def step(self, action):
        assert self.action_space.contains(action)
        mean = self._means[action]
        reward = self.np_random.normal(mean, self.std)
        observation = np.zeros(1, dtype=np.float32)

        return observation, reward, True, self._task
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ctrl+Alt+L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值