MAML-RL Pytorch 代码解读 (4) -- maml_rl/policies/categorical_mlp.py

MAML-RL Pytorch 代码解读 (4) – maml_rl/policies/categorical_mlp.py

基本介绍

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

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

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

源码链接

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

文件路径

./maml_rl/policies/categorical_mlp.py

import

import  torch
import  torch.nn as nn
import  torch.nn.functional as F
from    torch.distributions import Categorical

from    collections import OrderedDict
from    maml_rl.policies.policy import Policy, weight_init

CategoricalMLPPolicy()

class CategoricalMLPPolicy(Policy):
    
    #### 基于多层感知机的策略网络,输出离散的动作值,适用于表格化的强化学习以及离散动作的游戏中。这个类是基于第二份文件的Policy()类,能访问到Policy()类的策略更新函数。
    """
    Policy network based on a multi-layer perceptron (MLP), with a
    `Categorical` distribution output. This policy network can be used on tasks
    with discrete action spaces (eg. `TabularMDPEnv`). The code is adapted from
    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/sandbox/rocky/tf/policies/maml_minimal_categorical_mlp_policy.py
    """

    def __init__(self, input_size, output_size, hidden_sizes=(), nonlinearity=F.relu):
        
        #### 将父类的 input_size 和 output_size 继承到这个类上。
        super(CategoricalMLPPolicy, self).__init__(input_size=input_size, output_size=output_size)
        
        #### hidden_sizes隐藏层神经元的行列数,存进来的是只有两个元素的元组;当元组里面的元素是一个的时候,也可以;nonlinearity非线性激活函数;num_layers相当于神经元原本层数再加一层,从后面可知加的这一层是输入层;
        self.hidden_sizes = hidden_sizes
        self.nonlinearity = nonlinearity
        self.num_layers = len(hidden_sizes) + 1

        #### 元组加法实际上就是元组的融合。a = (1,) b = (2,3,4,) a + b = (1,2,3,4,)。那么layer_sizes输出的就是输入层、隐藏层的每一层和输出层的大小。
        layer_sizes = (input_size,) + hidden_sizes + (output_size,)
        
        #### 加了输入层之后,第一层(序号0)就是输入层,那么中间层就是从序号1开始的层。这个循环的作用是为每个隐藏层具体化线性网络。当i=1时,输入维度是输入层(序号0)的维度,输出的是自己的隐藏层(序号1)的维度。当i=2时,输入维度是隐藏层(序号1)的维度,输出的是自己的隐藏层(序号2)的维度。以此类推。
        for i in range(1, self.num_layers + 1):
            self.add_module('layer{0}'.format(i),
                            nn.Linear(layer_sizes[i - 1], layer_sizes[i]))
            
        #### 最后self.apply(weight_init)的含义可能是将policy.py文件函数引进过来(不理解,待定)。
        self.apply(weight_init)

    def forward(self, input, params=None):
        
        #### 如果参数不存在,就从父类中有顺序地继承网络和名字
        if params is None:
            params = OrderedDict(self.named_parameters())
            
        #### 先将输出设定成输入值
        output = input
        
        #### 让输入经过隐藏层神经元和激活函数
        for i in range(1, self.num_layers):
            output = F.linear(output,
                              weight=params['layer{0}.weight'.format(i)],
                              bias=params['layer{0}.bias'.format(i)])
            output = self.nonlinearity(output)
            
        #### 用网络的最后一层输出每个离散动作发生的概率
        logits = F.linear(output,
                          weight=params['layer{0}.weight'.format(self.num_layers)],
                          bias=params['layer{0}.bias'.format(self.num_layers)])
        
		#### 按照传入的logits在相应的位置处进行取样,取样返回的是该位置的整数索引。
        return Categorical(logits=logits)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用PyTorch实现的MAML元学习的示例代码: ```python import torch import torch.nn as nn import torch.optim as optim class MAML(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(MAML, self).__init__() self.input_size = input_size self.hidden_size = hidden_size self.output_size = output_size self.fc1 = nn.Linear(input_size, hidden_size) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_size, output_size) def forward(self, x): x = self.fc1(x) x = self.relu(x) x = self.fc2(x) return x def clone(self, device=None): clone = MAML(self.input_size, self.hidden_size, self.output_size) if device is not None: clone.to(device) clone.load_state_dict(self.state_dict()) return clone class MetaLearner(nn.Module): def __init__(self, model, lr): super(MetaLearner, self).__init__() self.model = model self.optimizer = optim.Adam(self.model.parameters(), lr=lr) def forward(self, x): return self.model(x) def meta_update(self, task_gradients): for param, gradient in zip(self.model.parameters(), task_gradients): param.grad = gradient self.optimizer.step() self.optimizer.zero_grad() def train_task(model, data_loader, lr_inner, num_updates_inner): model.train() task_loss = 0.0 for i, (input, target) in enumerate(data_loader): input = input.to(device) target = target.to(device) clone = model.clone(device) meta_optimizer = MetaLearner(clone, lr_inner) for j in range(num_updates_inner): output = clone(input) loss = nn.functional.mse_loss(output, target) grad = torch.autograd.grad(loss, clone.parameters(), create_graph=True) fast_weights = [param - lr_inner * g for param, g in zip(clone.parameters(), grad)] clone.load_state_dict({name: param for name, param in zip(clone.state_dict(), fast_weights)}) output = clone(input) loss = nn.functional.mse_loss(output, target) task_loss += loss.item() grad = torch.autograd.grad(loss, model.parameters()) task_gradients = [-lr_inner * g for g in grad] meta_optimizer.meta_update(task_gradients) return task_loss / len(data_loader) # Example usage device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') input_size = 1 hidden_size = 20 output_size = 1 model = MAML(input_size, hidden_size, output_size) model.to(device) data_loader = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(torch.randn(100, input_size), torch.randn(100, output_size)), batch_size=10, shuffle=True) meta_optimizer = MetaLearner(model, lr=0.001) for i in range(100): task_loss = train_task(model, data_loader, lr_inner=0.01, num_updates_inner=5) print('Task loss:', task_loss) meta_optimizer.zero_grad() task_gradients = torch.autograd.grad(task_loss, model.parameters()) meta_optimizer.meta_update(task_gradients) ``` 在这个示例中,我们定义了两个类,MAML和MetaLearner。MAML是一个普通的神经网络,而MetaLearner包含了用于更新MAML的元优化器。在每个任务上,我们使用MAML的副本进行内部更新,然后使用元优化器来更新MAML的权重。在元学习的过程中,我们首先通过调用train_task函数来训练一个任务,然后通过调用meta_update函数来更新MAML的权重。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ctrl+Alt+L

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

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

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

打赏作者

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

抵扣说明:

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

余额充值