MAML-RL Pytorch 代码解读 (3) -- maml_rl/policies/normal_mlp.py

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

文章目录

  • MAML-RL Pytorch 代码解读 (3) -- maml_rl/policies/normal_mlp.py
      • 基本介绍
        • 源码链接
        • 文件路径
      • `import` 包
      • `NormalMLPPolicy()` 类

基本介绍

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

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

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

源码链接

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

文件路径

./maml_rl/policies/normal_mlp.py

import

import math
from collections import OrderedDict

import torch
import torch.nn as nn
import torch.nn.functional as F
from maml_rl.policies.policy import Policy, weight_init
from torch.distributions import Normal

NormalMLPPolicy()

class NormalMLPPolicy(Policy):
    
    #### 基于多层感知机的策略网络,输出一个“正态分布”,这个分布的方差可训练。这个网络用于连续环境。这个类是基于第二份文件的Policy()类,能访问到Policy()类的策略更新函数。
    """
    Policy network based on a multi-layer perceptron (MLP), with a
    `Normal` distribution output, with trainable standard deviation. This
    policy network can be used on tasks with continuous action spaces (eg.
    `HalfCheetahDir`). The code is adapted from
    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/sandbox/rocky/tf/policies/maml_minimal_gauss_mlp_policy.py
    """
    
    def __init__(self, input_size, output_size, hidden_sizes=(),
                 nonlinearity=F.relu, init_std=1.0, min_std=1e-6):
        
        #### 将父类的 input_size 和 output_size 继承到这个类上。
        super(NormalMLPPolicy, self).__init__(
            input_size=input_size, output_size=output_size)
        
        #### hidden_sizes隐藏层神经元的行列数,存进来的是只有两个元素的元组;nonlinearity非线性激活函数;min_log_std最小标准差的对数形式;num_layers相当于神经元原本层数再加一层,从后面可知加的这一层是输入层;
        self.hidden_sizes = hidden_sizes
        self.nonlinearity = nonlinearity
        self.min_log_std = math.log(min_std)
        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
        
        #### 加了输入层之后,第一层(序号0)就是输入层,那么中间层就是从序号1开始的层。这个循环的作用是为每个隐藏层具体化线性网络。当i=1时,输入维度是输入层(序号0)的维度,输出的是自己的隐藏层(序号1)的维度。当i=2时,输入维度是隐藏层(序号1)的维度,输出的是自己的隐藏层(序号2)的维度。以此类推。
        for i in range(1, self.num_layers):
            self.add_module('layer{0}'.format(i),
                            nn.Linear(layer_sizes[i - 1], layer_sizes[i]))
            
        #### 最后一层输出的是均值向量self.mu。
        self.mu = nn.Linear(layer_sizes[-1], output_size)
        
        #### 而标准差self.sigma则是通过初始权值1.0赋值,大小与均值self.mu一样。torch.Tensor(output_size)输出的是与动作空间维度相同的张量。用nn.Parameter()类的目的是,将不可导的torch.Tensor(output_size)张量变成可导的,参与网络的训练中,相当于加到了layer_sizes,在后面再加一个小模块。
        self.sigma = nn.Parameter(torch.Tensor(output_size))
        
        #### self.sigma.data.fill_()d的含义是将里面的内容初始化为0,因为log1=0。
        self.sigma.data.fill_(math.log(init_std))
        
        #### 最后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)
        
        #### 用网络的最后一层输出均值
        mu = F.linear(output, weight=params['mu.weight'],
                      bias=params['mu.bias'])
        
        #### 将sigma层的结果进行限幅度处理,限制了最小幅度,然后通过指数函数生成标准差。最后输出一个正态分布。这个params['sigma']能否直接输出结果,有点不理解,那他的输入是什么?我再学一下5555。
        scale = torch.exp(torch.clamp(params['sigma'], min=self.min_log_std))
        return Normal(loc=mu, scale=scale)

你可能感兴趣的:(源码解读,MetaRL_Notes,pytorch,深度学习,python)