欢迎访问宙启技术站
智能推送

使用Python的RolloutStorage()实现数据增量更新的实例演示

发布时间:2024-01-04 22:09:22

RolloutStorage是一个用于存储数据的类,常用于强化学习中的存储记忆数据。它可以存储多个Agent的经验,包括状态、动作、奖励和下一个状态等信息,并可以方便地对存储的数据进行操作,比如增量更新。

下面我们以一个简单的强化学习任务为例,演示如何使用RolloutStorage来实现数据的增量更新。我们使用CartPole-v1环境,目标是控制杆子在平衡的同时移动小车。

首先,我们需要安装gym和pytorch包,并导入所需的包和模块:

!pip install gym torch
import gym
import torch
import numpy as np
from torch.utils.data.sampler import BatchSampler, SubsetRandomSampler

接下来,我们创建一个RolloutStorage对象,并设置相关参数,如状态空间的维度、动作空间的维度、存储的最大容量和存储的数据类型等。我们还需要选择一个策略网络和一个值函数网络来生成动作和评估状态价值:

class Policy(torch.nn.Module):
    def __init__(self, input_dim, output_dim):
        super(Policy, self).__init__()
        self.fc1 = torch.nn.Linear(input_dim, 64)
        self.fc2 = torch.nn.Linear(64, output_dim)
        self.relu = torch.nn.ReLU()
        
    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

class ValueFunction(torch.nn.Module):
    def __init__(self, input_dim):
        super(ValueFunction, self).__init__()
        self.fc1 = torch.nn.Linear(input_dim, 32)
        self.fc2 = torch.nn.Linear(32, 1)
        self.relu = torch.nn.ReLU()
        
    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

input_dim = 4  # 环境状态空间的维度
output_dim = 2  # 环境动作空间的维度
max_capacity = 10000  # 存储的最大容量
dtype = torch.float

storage = RolloutStorage(max_capacity, input_dim, output_dim, dtype)
policy_net = Policy(input_dim, output_dim)
value_net = ValueFunction(input_dim)

接下来,我们定义一个函数来生成一个批次的训练数据。在强化学习中,我们使用一种称为回合的方法来生成训练数据。每个回合包括多个时间步骤,每个时间步骤都包括一个状态、一个动作、一个奖励和一个下一个状态。我们在每个回合结束时计算回报,并将数据存储在RolloutStorage中:

def generate_training_data(storage, env, num_steps):
    state = env.reset()
    storage.states[0].copy_(torch.tensor(state, dtype=dtype))
    done = False
    num_total_steps = 1
    
    for t in range(num_steps):
        with torch.no_grad():
            action_prob = policy_net(torch.tensor(state, dtype=dtype))
            action = np.random.choice(output_dim, p=action_prob.numpy())
            next_state, reward, done, _ = env.step(action)
            storage.insert(state, action, reward, done)
            
            state = next_state
            storage.states[num_total_steps].copy_(torch.tensor(state, dtype=dtype))
            num_total_steps += 1
            
            if done:
                break
        
    storage.compute_returns(value_net)

在训练之前,我们需要定义一些超参数,比如学习率、优化器和训练的总步数等。我们还需要创建一个BatchSampler对象,用于从RolloutStorage中采样批次的训练数据:

learning_rate = 0.001
num_steps = 10000
num_epochs = 10
batch_size = 32
gamma = 0.99  # 衰减因子

optimizer_policy = torch.optim.Adam(policy_net.parameters(), lr=learning_rate)
optimizer_value = torch.optim.Adam(value_net.parameters(), lr=learning_rate)

sampler = BatchSampler(SubsetRandomSampler(range(max_capacity)), batch_size, drop_last=False)

接下来,我们开始训练过程。在每个训练周期中,我们从BatchSampler中采样一个批次的数据,并使用策略网络生成动作概率,然后使用动作概率和对应的回报计算策略梯度,并更新策略网络。同时,我们还使用值函数网络评估状态价值,并计算值函数的损失并更新值函数网络:

for epoch in range(num_epochs):
    for indices in sampler:
        batch_states = storage.states[indices].detach()
        batch_actions = storage.actions[indices].detach()
        batch_returns = storage.returns[indices].detach()
        
        action_probs = policy_net(batch_states)
        action_log_probs = torch.log_softmax(action_probs, dim=1)
        selected_log_probs = batch_returns * action_log_probs[range(batch_size), batch_actions]
        policy_loss = -selected_log_probs.mean()
        
        optimizer_policy.zero_grad()
        policy_loss.backward()
        optimizer_policy.step()
        
        values = value_net(batch_states).squeeze()
        value_loss = (values - batch_returns).pow(2).mean()
        
        optimizer_value.zero_grad()
        value_loss.backward()
        optimizer_value.step()

最后,在训练完成之后,我们可以使用训练后的策略网络对环境进行测试。通过多次运行该环境,我们可以观察到小车在平衡杆的同时移动的情况。以下是测试的示例代码:

def test_policy(policy_net, env, num_episodes):
    for episode in range(num_episodes):
        state = env.reset()
        done = False
        total_reward = 0
        
        while not done:
            with torch.no_grad():
                action_prob = policy_net(torch.tensor(state, dtype=dtype))
                action = np.argmax(action_prob.numpy())
                state, reward, done, _ = env.step(action)
                total_reward += reward
                
        print("Episode {}: Total reward = {}".format(episode + 1, total_reward))

test_policy(policy_net, gym.make('CartPole-v1'), num_episodes=10)

综上所述,我们通过RolloutStorage类实现了一个简单的数据增量更新的示例,并利用策略梯度方法训练了一个可以控制小车的策略网络。这个示例可以帮助我们理解如何使用RolloutStorage进行强化学习的数据存储和增量更新的操作。