MAML-RL Pytorch 代码解读 (14) -- maml_rl/baseline.py

MAML-RL Pytorch 代码解读 (14) – maml_rl/baseline.py

基本介绍

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

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

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

源码链接

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

文件路径

./maml_rl/baseline.py

import

import torch
import torch.nn as nn

LinearFeatureBaseline()

class LinearFeatureBaseline(nn.Module):
    
    #### 这个类描述的是采用人类手工提取特征方法的baseline
	"""
	Linear baseline based on handcrafted features, as described in [1]
	(Supplementary Material 2).

	[1] Yan Duan, Xi Chen, Rein Houthooft, John Schulman, Pieter Abbeel,
		"Benchmarking Deep Reinforcement Learning for Continuous Control", 2016
		(https://arxiv.org/abs/1604.06778)
	"""

    #### 声明继承了nn.Module()类,赋值输入信息的大小、_reg_coeff(含义目前未知),一个线性网络(输入大小是特征大小,输出是1维度,说明这本质是一个向量),对这个向量赋值全0的初始化。
	def __init__(self, input_size, reg_coeff=1e-5):
		super(LinearFeatureBaseline, self).__init__()
		self.input_size = input_size
		self._reg_coeff = reg_coeff
		self.linear = nn.Linear(self.feature_size, 1, bias=False)
		self.linear.weight.data.zero_()

    #### 定义了一个特征大小的函数,输出的特征是两倍的输入特征加上4。
	@property
	def feature_size(self):
		return 2 * self.input_size + 4

    #### 做人工的特征处理。得到的是观测、观测的平方、三个与al变量相关的特征还有一个ones变量。
	def _feature(self, episodes):
		ones = episodes.mask.unsqueeze(2)
		observations = episodes.observations * ones
		cum_sum = torch.cumsum(ones, dim=0) * ones
		al = cum_sum / 100.0

		return torch.cat([observations, observations ** 2,
		                  al, al ** 2, al ** 3, ones], dim=2)

	def fit(self, episodes):
        
        #### 将一批数据里面的所有episode内容,整合成 “序列长度 x 特征大小” 这样的格式。“特征大小”实际上就是上一个函数的观测、观测的平方、三个与al变量相关的特征还有一个ones变量。具体意义暂时不明确。
		# sequence_length * batch_size x feature_size
		featmat = self._feature(episodes).view(-1, self.feature_size)
        
        #### 将奖励转化成一维度的列向量。
		# sequence_length * batch_size x 1
		returns = episodes.returns.view(-1, 1)

        #### 赋值reg_coeff然后再设置一个单位矩阵eye。
		reg_coeff = self._reg_coeff
		eye = torch.eye(self.feature_size, dtype=torch.float32,
		                device=self.linear.weight.device)
        
        #### PyTorch中的函数torch.lstsq()实现了最小二乘法。这个函数有两个参数,分别对应了MSE里的张量Y和X。这个函数有两个返回值,前一个返回值包括了所有的权重值,后一个返回值是QR分解的结果。torch.matmul作用是两个张量的矩阵乘积。这里使用torch.lstsq()方法主要是用最小二乘法获得一个网络的权重。那么这个二乘法的Y变量是“ 特征变量的转置 × 回报序列 ”,X变量是“ 特征变量的转置 × 特征变量 + 基于参数的对角阵 ”。获得的是这个“ 网络 ”的系数。
		for _ in range(5):
            
            #### 采用try结果是将报错(算不出来)的时候 reg_coeff 在原本基础上增加 10 以实现继续迭代
			try:
				coeffs, _ = torch.lstsq(
					torch.matmul(featmat.t(), returns),
					torch.matmul(featmat.t(), featmat) + reg_coeff * eye
				)
				break
			except RuntimeError:
				reg_coeff += 10
                
        #### 否则就报错。
		else:
			raise RuntimeError('Unable to solve the normal equations in '
			                   '`LinearFeatureBaseline`. The matrix X^T*X (with X the design '
			                   'matrix) is not full-rank, regardless of the regularization '
			                   '(maximum regularization: {0}).'.format(reg_coeff))
        
        #### 最后将二乘法的转置赋值给线性网络的变量
		self.linear.weight.data = coeffs.data.t()

    #### 类似与神经网络一样的前馈函数。
	def forward(self, episodes):
		features = self._feature(episodes)
		return self.linear(features)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
以下是使用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的权重。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ctrl+Alt+L

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

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

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

打赏作者

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

抵扣说明:

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

余额充值