精华内容
下载资源
问答
  • 2021-08-09 11:04:00

    A3C
    在这里插入图片描述
    核心思想:Global NetWork和每个Worker网络结构是一样的。拿每个Worker网络去训练,训练完之后,拿自己的梯度去更新Global NetWork梯度。Global NetWork再将自己的梯度去更新每个Worker的梯度

    代码实现
    参考一个博主的github

    a3c_main.py

    import gym
    import numpy as np
    import matplotlib.pyplot as plt
    from Actor_Critic.A3C.agent_a3c import A3C
    
    
    def get_env_prop(env_name, continuous):
        env = gym.make(env_name)
        state_dim = env.observation_space.shape[0]
        if continuous:
            action_dim = env.action_space.shape[0]
        else:
            action_dim = env.action_space.n
    
        return env,state_dim, action_dim
    
    
    def train_a3c(env_name,continuous):
        env,state_size,action_size = get_env_prop(env_name,continuous)
        agent = A3C(env,continuous,state_size,action_size)
        scores = agent.train_worker()
        return scores
    
    
    def train_agent_for_env(env_name,continuous):
        env = gym.make(env_name)
    
        state_dim = env.observation_space.shape[0]
        if continuous:
            action_dim = env.action_space.shape[0]
        else:
            action_dim = env.action_space.n
    
        agent = A3C(env, continuous,state_dim,action_dim)
        scores = agent.train_worker()
    
        return agent,scores
    
    
    def plot_scores(scores,filename):
        fig = plt.figure()
        ax = fig.add_subplot(111)
        plt.plot(np.arange(1, len(scores) + 1), scores)
        plt.ylabel('Score')
        plt.xlabel('Episode #')
        plt.savefig(filename)
        plt.show()
    
    
    if __name__ == "__main__":
        # env = gym.make("Pendulum-v0")
        # train_scores = train_a3c(env,True)
    
        # train A3C on discrete env : CartPole
        scores_cartPole = train_agent_for_env("CartPole-v0",False)
        plot_scores(scores_cartPole,"cartPole_trainPlot.png")
    
        # train A3C on continuous env : continuous
        # a3c_mCar = train_agent_for_env("MountainCarContinuous-v0", True)
    

    agent_a3c.py

    import random
    import torch
    import torch.optim as optim
    import multiprocessing as mp
    from multiprocessing import Process
    from Actor_Critic.A3C.untils import ValueNetwork,ActorDiscrete,ActorContinous
    from Actor_Critic.A3C.worker import Worker
    
    GAMMA = 0.9
    LR = 1e-4
    GLOBAL_MAX_EPISODE = 5000
    
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    
    
    class A3C():
        def __init__(self,env,continuous,state_size,action_size):
            self.max_episode=GLOBAL_MAX_EPISODE
            #pytorch的多进程可以参考https://zhuanlan.zhihu.com/p/328271397
            self.global_episode = mp.Value('i', 0)  # 进程之间共享的变量
            #用法例子如下
            #self.global_episode .value += 1
            
            self.global_epi_rew = mp.Value('d',0)
            self.rew_queue = mp.Queue()  #self.rew_queue是一个队列  可以往里面存储值和取出值 和普通队列的作用一样。但队列不能修改变量的值,只能存储值。而共享变量可以修改变量的值
            self.worker_num = mp.cpu_count()
    
            # define the global networks
            self.global_valueNet= ValueNetwork(state_size,1).to(device)
            # global 的网络参数放入 shared memory,以便复制给各个进程中的 worker网络
            self.global_valueNet.share_memory()
    
            if continuous:
                self.global_policyNet = ActorContinous(state_size, action_size).to(device)
            else:
                self.global_policyNet = ActorDiscrete(state_size, action_size).to(device)
            self.global_policyNet.share_memory()
    
            # global optimizer
            self.global_optimizer_policy = optim.Adam(self.global_policyNet.parameters(), lr=LR)
            self.global_optimizer_value = optim.Adam(self.global_valueNet.parameters(),lr=LR)
    
            # define the workers
            self.workers=[Worker(env,continuous,state_size,action_size,i,
                                 self.global_valueNet,self.global_optimizer_value,
                                 self.global_policyNet,self.global_optimizer_policy,
                                 self.global_episode,self.global_epi_rew,self.rew_queue,
                                 self.max_episode,GAMMA)
                          for i in range(self.worker_num)]
    
        def train_worker(self):
            scores=[]
            [w.start() for w in self.workers]
            while True:
                r = self.rew_queue.get()
                if r is not None:
                    scores.append(r)
                else:
                    break
            [w.join() for w in self.workers]
    
            return scores
    
        def save_model(self):
            torch.save(self.global_valueNet.state_dict(), "a3c_value_model.pth")
            torch.save(self.global_policyNet.state_dict(), "a3c_policy_model.pth")
    

    untils.py

    import torch
    from collections import namedtuple
    import torch.nn as nn
    import torch.nn.functional as F
    from torch.distributions import Categorical
    from torch.distributions import Normal
    
    
    class ValueNetwork(nn.Module):
    
        def __init__(self, input_dim, output_dim):
            super(ValueNetwork, self).__init__()
            self.fc1 = nn.Linear(input_dim, 256)
            self.fc2 = nn.Linear(256, output_dim)
    
        def forward(self, state):
            value = F.relu(self.fc1(state))
            value = self.fc2(value)
    
            return value
    
    
    class ActorDiscrete(nn.Module):
        """
        用于离散动作空间的策略网络
        """
        def __init__(self,state_size,action_size):
            super(ActorDiscrete, self).__init__()
            self.seed = torch.manual_seed(0)
            self.fc1 = nn.Linear(state_size, 128)
            # self.fc2 = nn.Linear(64,128)
            self.fc2= nn.Linear(128, action_size)
    
        def forward(self, x):
            """
            Build a network that maps state -> action probs.
            """
    
            x=F.relu(self.fc1(x))
            out = F.softmax(self.fc2(x),dim=1)
            return out
    
        def act(self,state):
            """
            返回 action 和 action的概率
            """
            # probs for each action (2d tensor)
            probs = self.forward(state)
            m = Categorical(probs)
            action = m.sample()
    
            # return action for current state, and the corresponding probability
            return action.item(),probs[:,action.item()].item()
    
    
    class ActorContinous(nn.Module):
        """
        用于连续动作空间的策略网络
        """
        def __init__(self,state_size,action_size):
            super(ActorContinous, self).__init__()
            self.fc1 = nn.Linear(state_size, 128)
            self.fc2 = nn.Linear(128,128)
            self.mu_head = nn.Linear(128, action_size)
            self.sigma_head = nn.Linear(128, action_size)
    
        def forward(self, x):
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            mu = 2.0 * torch.tanh(self.mu_head(x))
            sigma = F.softplus(self.sigma_head(x))
            return (mu, sigma)
    
        def act(self,state):
            """
            返回 action 和 action 的 log prob
            """
            with torch.no_grad():
                (mu, sigma) = self.policy(state)  # 2d tensors
            dist = Normal(mu, sigma)
            action = dist.sample()
            action_log_prob = dist.log_prob(action)
    
            return action.numpy()[0], action_log_prob.numpy()[0]
    

    worker.py

    import math
    import torch.multiprocessing as mp
    import torch
    import torch.nn.functional as F
    from torch.distributions import Normal
    from Actor_Critic.A3C.untils import ValueNetwork,ActorDiscrete,ActorContinous
    
    
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    
    
    class Worker(mp.Process):
        def __init__(self,env,continuous,state_size,action_size,id, global_valueNet,global_value_optimizer,
                     global_policyNet,global_policy_optimizer,
                     global_epi,global_epi_rew,rew_queue,
                     max_epi,gamma):
            super(Worker, self).__init__()
            # define env for individual worker
            self.env = env
            self.continuous = continuous
            self.name = str(id)
            self.env.seed(id)
            self.state_size = state_size
            self.action_size = action_size
            self.memory=[]
    
            # passing global settings to worker
            self.global_valueNet,self.global_value_optimizer = global_valueNet,global_value_optimizer
            self.global_policyNet,self.global_policy_optimizer = global_policyNet,global_policy_optimizer
            self.global_epi,self.global_epi_rew = global_epi,global_epi_rew
            self.rew_queue = rew_queue
            self.max_epi = max_epi
            # self.batch_size = batch_size
            self.gamma = gamma
    
            # define local net for individual worker
            self.local_policyNet = ActorDiscrete(self.state_size,self.action_size).to(device)
            if self.continuous:
                self.local_policyNet = ActorContinous(self.state_size,self.action_size).to(device)
            self.local_valueNet = ValueNetwork(self.state_size,1).to(device)
    
        def sync_global(self):
            self.local_valueNet.load_state_dict(self.global_valueNet.state_dict())
            self.local_policyNet.load_state_dict(self.global_policyNet.state_dict())
    
        def calculate_loss(self):
            # get experiences from current trajectory
            states = torch.tensor([t[0] for t in self.memory], dtype=torch.float)
            
            #好像这里有点问题 因为self.memory.append([state,action,reward,next_state,done])
            #所以t[1]是action?
            #105行和107行代码
            log_probs = torch.tensor([t[1] for t in self.memory], dtype=torch.float)
    
            # -- calculate discount future rewards for every time step
            rewards = [t[2] for t in self.memory]
            fur_Rewards = []
            for i in range(len(rewards)):
                discount = [self.gamma ** i for i in range(len(rewards) - i)]
                f_rewards = rewards[i:]
                fur_Rewards.append(sum(d * f for d, f in zip(discount, f_rewards)))
            fur_Rewards = torch.tensor(fur_Rewards, dtype=torch.float).view(-1, 1)
    
            # calculate loss for critic
            V = self.local_valueNet(states)
            value_loss = F.mse_loss(fur_Rewards, V)
    
            # compute entropy for policy loss
            (mu, sigma) = self.local_policyNet(states)
            dist = Normal(mu, sigma)
            entropy = 0.5 + 0.5 * math.log(2 * math.pi) + torch.log(dist.scale)  # exploration
    
            # calculate loss for actor
            advantage = (fur_Rewards - V).detach()
            policy_loss = -advantage * log_probs
            policy_loss = (policy_loss - 0.005 * entropy).mean()
    
            return value_loss,policy_loss
    
        def update_global(self):
            value_loss, policy_loss = self.calculate_loss()
    
            self.global_value_optimizer.zero_grad()
            value_loss.backward()
            # propagate local gradients to global parameters
            for local_params, global_params in zip(self.local_valueNet.parameters(), self.global_valueNet.parameters()):
                global_params._grad = local_params._grad
            self.global_value_optimizer.step()
    
            self.global_policy_optimizer.zero_grad()
            #求梯度
            policy_loss.backward()
            # propagate local gradients to global parameters
            for local_params, global_params in zip(self.local_policyNet.parameters(), self.global_policyNet.parameters()):
                #复制梯度
                global_params._grad = local_params._grad
                #更新参数w和b
            self.global_policy_optimizer.step()
    
            self.memory=[]  # clear trajectory
    
        def run(self):
            while self.global_epi.value < self.max_epi:
                state = self.env.reset()
                total_reward=0
                while True:
                    state = torch.from_numpy(state).float().unsqueeze(0).to(device)
                    action, prob = self.local_policyNet.act(state)  # 离散空间取直接prob,连续空间取log prob
                    next_state, reward, done, _ = self.env.step(action)
                    self.memory.append([state,action,reward,next_state,done])
                    total_reward += reward
                    state = next_state
    
                    if done:
                        # recoding global episode and episode reward
                        with self.global_epi.get_lock():
                            self.global_epi.value += 1
                        with self.global_epi_rew.get_lock():
                            if self.global_epi_rew.value == 0.:
                                self.global_epi_rew.value = total_reward
                            else:
                                # Moving average reward
                                self.global_epi_rew.value = self.global_epi_rew.value * 0.99 + total_reward * 0.01
                        self.rew_queue.put(self.global_epi_rew.value)
    
                        print("w{} | episode: {}\t , episode reward:{:.4} \t  "
                              .format(self.name,self.global_epi.value,self.global_epi_rew.value))
                        break
    
                # update and sync with the global net when finishing an episode
                self.update_global()
                self.sync_global()
    
            self.rew_queue.put(None)
    
    
    更多相关内容
  • 强化学习算法-基于python的强化学习a3c算法实现
  • 基于强化学习A3C与DQN的月球着陆游戏训练设计与实现
  • 浅谈利用A3C玩转超级玛丽奥前言github什么是Actor-Critic?A3C算法loss值计算 前言 很早以前看过超级玛丽奥利用人工智能玩,以前感觉很高档。就写一篇吧。 github 什么是Actor-Critic? Actor-Critic,其实是用了两...

    浅谈利用A3C玩转超级玛丽奥

    前言

    很早以前看过超级玛丽奥利用人工智能玩,以前感觉很高档。就写一篇吧。
    在这里插入图片描述
    在这里插入图片描述

    github

    https://github.com/yanjingke/Super-mario

    什么是Actor-Critic?

    Actor-Critic,其实是用了两个网络:两个网络有一个共同点,输入状态S: 一个输出策略,负责选择动作,我们把这个网络成为Actor; 一个负责计算每个动作的分数,我们把这个网络成为Critic。
    大家可以形象地想象为,Actor是舞台上的舞者,Critic是台下的评委。Actor在台上跳舞,一开始舞姿并不好看,Critic根据Actor的舞姿打分。Actor通过Critic给出的分数,去学习:如果Critic给的分数高,那么Actor会调整这个动作的输出概率;相反,如果Critic给的分数低,那么就减少这个动作输出的概率。
    在AC中中的Critic,估算的是V值也就是一个评分,因为在强化学习中,往往没有足够的时间让我们去和环境互动。在Critic中如果预测动作评价,假设我们用Critic网络,预估到S状态下三个动作A1,A2,A3的Q值分别为1,2,10。但在开始的时候,我们采用平均策略,于是随机到A1。于是我们用策略梯度的带权重方法更新策略,这里的权重就是Q值。于是策略会更倾向于选择A1,意味着更大概率选择A1。结果A1的概率就持续升高…
    这就掉进了正数陷阱。我们明明希望A3能够获得更多的机会,最后却是A1获得最多的机会。这是为什么呢?
    这是因为Q值用于是一个正数,如果权重是一个正数,那么我们相当于提高对应动作的选择的概率。权重越大,我们调整的幅度将会越大。其实当我们有足够的迭代次数,这个是不用担心这个问题的。因为总会有机会抽中到权重更大的动作,因为权重比较大,抽中一次就能提高很高的概率。

    在这里插入图片描述
    但在强化学习中,往往没有足够的时间让我们去和环境互动。这就会出现由于运气不好,使得一个很好的动作没有被采样到的情况发生。要解决这个问题,我们可以通过减去一个baseline,令到权重有正有负。而通常这个baseline,我们选取的是权重的平均值。减去平均值之后,值就变成有正有负了。
    在这里插入图片描述
    所以我们可以得到更新的权重:Q(s,a)-V(s)。然而在每次的奖励中会进行得分的衰减gamma。
    总结

    1、为了避免正数陷阱,我们希望Actor的更新权重有正有负。因此,我们把Q值减去他们的均值V。有:Q(s,a)-V(s)

    2、为了避免需要预估V值和Q值,我们希望把Q和V统一;由于Q(s,a) = gamma * V(s’) + r - V(s)。所以我们得到TD-error公式: TD-error = gamma * V(s’) + r - V(s)

    A3C算法

    在A3C中有一个公共的神经网络模型,这个神经网络包括Actor网络和Critic网络两部分的功能这样加快了速度。下面有n个worker线程,每个线程里有和公共的神经网络一样的网络结构,每个线程会独立的和环境进行交互得到经验数据,这些线程之间互不干扰,独立运行。
    在这里插入图片描述
    它是怎么实现公共网络的啦?
    在A3C中需要解决的问题:在这里插入图片描述
    在这里插入图片描述
    由于智能体在与环境交互过程中有大量的随机性,所以算的是期望,为了计算A,现在出现了Q和V,那我得训练俩网络了
    来个近似让问题简单些吧:
    在这里插入图片描述
    是不是不用训练两个网络啦?
    在这里插入图片描述
    它俩好像都是根据状态来预测结果:
    在这里插入图片描述

    
    class ActorCritic(nn.Module):
        def __init__(self, num_inputs, num_actions):
            super(ActorCritic, self).__init__()
            self.conv1 = nn.Conv2d(num_inputs, 32, 3, stride=2, padding=1)
            self.conv2 = nn.Conv2d(32, 32, 3, stride=2, padding=1)
            self.conv3 = nn.Conv2d(32, 32, 3, stride=2, padding=1)
            self.conv4 = nn.Conv2d(32, 32, 3, stride=2, padding=1)
            self.lstm = nn.LSTMCell(32 * 6 * 6, 512)
            self.critic_linear = nn.Linear(512, 1)
            self.actor_linear = nn.Linear(512, num_actions)
            self._initialize_weights()
    
        def _initialize_weights(self):
            for module in self.modules():
                if isinstance(module, nn.Conv2d) or isinstance(module, nn.Linear):
                    nn.init.xavier_uniform_(module.weight)
                    # nn.init.kaiming_uniform_(module.weight)
                    nn.init.constant_(module.bias, 0)
                elif isinstance(module, nn.LSTMCell):
                    nn.init.constant_(module.bias_ih, 0)
                    nn.init.constant_(module.bias_hh, 0)
    
        def forward(self, x, hx, cx):
            x = F.relu(self.conv1(x))
            x = F.relu(self.conv2(x))
            x = F.relu(self.conv3(x))
            x = F.relu(self.conv4(x))
            # print( (hx, cx))
            hx, cx = self.lstm(x.view(x.size(0), -1), (hx, cx))
            return self.actor_linear(hx), self.critic_linear(hx), hx, cx#隐层和记忆单元
    
    

    AC整体流程:
    1.获取数据: (不断与环境交互,通过策略 )在这里插入图片描述
    2.前向传播计算:
    在这里插入图片描述
    3.计算梯度:
    在这里插入图片描述
    4.更新参数:
    在这里插入图片描述

    def local_train(index, opt, global_model, optimizer, save=False):
        torch.manual_seed(123 + index)
        if save:
            start_time = timeit.default_timer()
        writer = SummaryWriter(opt.log_path)
        env, num_states, num_actions = create_train_env(opt.world, opt.stage, opt.action_type)#单独玩
        local_model = ActorCritic(num_states, num_actions)
        if opt.use_gpu:
            local_model.cuda()
        local_model.train()
        state = torch.from_numpy(env.reset())
        if opt.use_gpu:
            state = state.cuda()
        done = True
        curr_step = 0
        curr_episode = 0
        while True:
            if save:
                if curr_episode % opt.save_interval == 0 and curr_episode > 0:
                    torch.save(global_model.state_dict(),
                               "{}/a3c_super_mario_bros_{}_{}".format(opt.saved_path, opt.world, opt.stage))
                print("Process {}. Episode {}".format(index, curr_episode))
            curr_episode += 1
            local_model.load_state_dict(global_model.state_dict())
            if done:
                h_0 = torch.zeros((1, 512), dtype=torch.float)
                c_0 = torch.zeros((1, 512), dtype=torch.float)
            else:
                h_0 = h_0.detach()
                c_0 = c_0.detach()
            if opt.use_gpu:
                h_0 = h_0.cuda()
                c_0 = c_0.cuda()
    
            log_policies = []
            values = []
            rewards = []
            entropies = []
    
            for _ in range(opt.num_local_steps):
                curr_step += 1
                logits, value, h_0, c_0 = local_model(state, h_0, c_0)#return self.actor_linear(hx), self.critic_linear(hx), hx, cx#隐层和记忆单元
                policy = F.softmax(logits, dim=1)
                log_policy = F.log_softmax(logits, dim=1)
                entropy = -(policy * log_policy).sum(1, keepdim=True)#计算当前熵值
    
                #进行分布采样
                m = Categorical(policy)#采样
                action = m.sample().item()
    
                state, reward, done, _ = env.step(action)
                # env.render()
                state = torch.from_numpy(state)
                if opt.use_gpu:
                    state = state.cuda()
                if curr_step > opt.num_global_steps:
                    done = True
    
                if done:
                    curr_step = 0
                    state = torch.from_numpy(env.reset())
                    if opt.use_gpu:
                        state = state.cuda()
    
                values.append(value)
                log_policies.append(log_policy[0, action])
                rewards.append(reward)
                entropies.append(entropy)
    
                if done:
                    break
    
            R = torch.zeros((1, 1), dtype=torch.float)
            if opt.use_gpu:
                R = R.cuda()
            if not done:
                _, R, _, _ = local_model(state, h_0, c_0)#这个R相当于最后一次的V值,第二个返回值是critic网络的
    
            gae = torch.zeros((1, 1), dtype=torch.float)#额外的处理,为了减小variance
            if opt.use_gpu:
                gae = gae.cuda()
            actor_loss = 0
            critic_loss = 0
            entropy_loss = 0
            next_value = R
    
            for value, log_policy, reward, entropy in list(zip(values, log_policies, rewards, entropies))[::-1]:
                gae = gae * opt.gamma * opt.tau
                gae = gae + reward + opt.gamma * next_value.detach() - value.detach()#Generalized Advantage Estimator 带权重的折扣项
                next_value = value
                actor_loss = actor_loss + log_policy * gae
                R = R * opt.gamma + reward
                critic_loss = critic_loss + (R - value) ** 2 / 2
                entropy_loss = entropy_loss + entropy
    
            total_loss = -actor_loss + critic_loss - opt.beta * entropy_loss
            writer.add_scalar("Train_{}/Loss".format(index), total_loss, curr_episode)
            optimizer.zero_grad()
            total_loss.backward()
    
            for local_param, global_param in zip(local_model.parameters(), global_model.parameters()):
                if global_param.grad is not None:
                    break
                global_param._grad = local_param.grad
    
            optimizer.step()
    
            if curr_episode == int(opt.num_global_steps / opt.num_local_steps):
                print("Training process {} terminated".format(index))
                if save:
                    end_time = timeit.default_timer()
                    print('The code runs for %.2f s ' % (end_time - start_time))
                return
    

    loss值计算

    策略损失(Policy): 在这里插入图片描述
    (起决策的网络)
    Value网络损失:在这里插入图片描述
    (预期与实际的差异)
    熵:在这里插入图片描述(熵越大表示各种行为可能性都能有一些,别太绝对)
    整体损失函数:
    在这里插入图片描述

      for value, log_policy, reward, entropy in list(zip(values, log_policies, rewards, entropies))[::-1]:
                gae = gae * opt.gamma * opt.tau
                gae = gae + reward + opt.gamma * next_value.detach() - value.detach()#Generalized Advantage Estimator 带权重的折扣项
                next_value = value
                actor_loss = actor_loss + log_policy * gae
                R = R * opt.gamma + reward
                critic_loss = critic_loss + (R - value) ** 2 / 2
                entropy_loss = entropy_loss + entropy
    
            total_loss = -actor_loss + critic_loss - opt.beta * entropy_loss
            writer.add_scalar("Train_{}/Loss".format(index), total_loss, curr_episode)
            optimizer.zero_grad()
            total_loss.backward()
    

    在这里插入图片描述

    展开全文
  • 从结果上看,改进的A3C算法计算效率更高,寻优效果更好,目前深度强化学习非常火热,很容易出成果,非常适合在本代码的基础上稍微加点东西,即可形成自己的成果,非常适合深度强化学习方向的人学习! ID:69150641

    主题:基于改进A3C算法的微网优化调度与需求响应管理

    内容简介:

    代码主要做的是基于深度强化学习的微网/虚拟电厂优化调度策略研究,微网的聚合单元包括风电机组,储能单元,温控负荷(空调、热水器)以及需求响应负荷,并且考虑并网,可与上级电网进行能量交互,采用A3C算法以及改进的A3C算法进行求解,从结果上看,改进的A3C算法计算效率更高,寻优效果更好,目前深度强化学习非常火热,很容易出成果,非常适合在本代码的基础上稍微加点东西,即可形成自己的成果,非常适合深度强化学习方向的人学习!

    ID:69150641830359180

    小代码狂人

    技术交流 资源共享 莫如博客陪您进步!

    本文转载自:莫如博客

    展开全文
  • 基于强化学习算法A3C,DDPG,DDPO的机器人手臂游戏训练设计与实现
  • 强化学习--A3C

    2022-04-24 18:52:21
    二、核心算法(A3C) Asynchronous Advantage Actor-critic 前言 强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与...

    系列文章目录

    强化学习


    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题 。


    一、强化学习是什么?

    强化学习是智能体(Agent)以“试错”的方式进行学习,通过与环境进行交互获得的奖赏指导行为,目标是使智能体获得最大的奖赏,强化学习不同于连接主义学习中的监督学习,主要表现在强化信号上,强化学习中由环境提供的强化信号是对产生动作的好坏作一种评价(通常为标量信号),而不是告诉强化学习系统RLS(reinforcement learning system)如何去产生正确的动作。由于外部环境提供的信息很少,RLS必须靠自身的经历进行学习。通过这种方式,RLS在行动-评价的环境中获得知识,改进行动方案以适应环境。
    理解:强化学习其实就是和人一样,一开始是什么都不懂的,所谓吃一堑长一智,他像一个新生的孩子,它在不断的试错过程中慢慢知道了做什么有奖励,做什么对得到奖励会有一定的价值,做什么会被打。在这个过程中不会像监督学习一样有个师傅带你,完全需要自己去摸索,就像修仙宗门一样,有背景的宗门弟子是继承掌门之位(监督),创立宗门的人是开山立派(强化),必须一步一个脚印去不断成长。

    其实强化学习吸引我的就是因为它主要使用在游戏上,例如:
    在 Flappy bird 这个游戏中,我们需要简单的点击操作来控制小鸟,躲过各种水管,飞的越远越好,因为飞的越远就能获得更高的积分奖励。

    机器有一个玩家小鸟——Agent
    需要控制小鸟飞的更远——目标
    整个游戏过程中需要躲避各种水管——环境
    躲避水管的方法是让小鸟用力飞一下——行动
    飞的越远,就会获得越多的积分——奖励
    在这里插入图片描述

    二、核心算法(A3C) Asynchronous Advantage Actor-critic

    A3C( Asynchronous Advantage Actor-critic,简称A3C)主要是通过相比Actor-Critic,A3C的优化主要有3点,分别是异步训练框架,网络结构优化,Critic评估点的优化。其中异步训练框架是最大的优化,也就是相当于多线程并行运算,这大大提高了训练的速度。
    在这里插入图片描述

    if __name__ == "__main__":
        # 创建会话
        SESS = tf.Session()
        # 用cpu跑
        with tf.device("/cpu:0"):
            # 训练Actor与Critic,分开学习会更好
            OPT_A = tf.train.RMSPropOptimizer(LR_A, name='RMSPropA')
            OPT_C = tf.train.RMSPropOptimizer(LR_C, name='RMSPropC')
            # 全局神经网络
            GLOBAL_AC = ACNet(GLOBAL_NET_SCOPE)  # we only need its params
            workers = []
            # Create worker,根据cpu内核数量分配
            for i in range(N_WORKERS):
                i_name = 'W_%i' % i  # worker name
                workers.append(Worker(i_name, GLOBAL_AC))
    
        # 创建一个多线程管理
        COORD = tf.train.Coordinator()
        SESS.run(tf.global_variables_initializer())
        # tensorboard可视化
        if OUTPUT_GRAPH:
            if os.path.exists(LOG_DIR):
                shutil.rmtree(LOG_DIR)
            tf.summary.FileWriter(LOG_DIR, SESS.graph)
    
        worker_threads = []
        # 开启多个线程,线程情况上面已经添加好了
        for worker in workers:
            job = lambda: worker.work()
            t = threading.Thread(target=job)
            # 开启多线程神经网络的训练
            t.start()
            worker_threads.append(t)
        #     将线程放到管理者中
        COORD.join(worker_threads)
    
        plt.plot(np.arange(len(GLOBAL_RUNNING_R)), GLOBAL_RUNNING_R)
        plt.xlabel('step')
        plt.ylabel('Total moving reward')
        plt.show()
    
    

    网络因为环境问题,命令行被配置到Tensorboard 2.8.0去了,所以无法显示网络的可视化

    class ACNet(object):
        def __init__(self, scope, globalAC=None):
    
            if scope == GLOBAL_NET_SCOPE:  # get global network
                with tf.variable_scope(scope):
                    self.s = tf.placeholder(tf.float32, [None, N_S], 'S')
                    self.a_params, self.c_params = self._build_net(scope)[-2:]
            else:  # local net, calculate losses
                with tf.variable_scope(scope):
                    self.s = tf.placeholder(tf.float32, [None, N_S], 'S')
                    self.a_his = tf.placeholder(tf.float32, [None, N_A], 'A')
                    self.v_target = tf.placeholder(tf.float32, [None, 1], 'Vtarget')
    
                    mu, sigma, self.v, self.a_params, self.c_params = self._build_net(scope)
    
                    td = tf.subtract(self.v_target, self.v, name='TD_error')
                    with tf.name_scope('c_loss'):
                        self.c_loss = tf.reduce_mean(tf.square(td))
    
                    with tf.name_scope('wrap_a_out'):
                        mu, sigma = mu * A_BOUND[1], sigma + 1e-4
    
                    normal_dist = tf.distributions.Normal(mu, sigma)
    
                    with tf.name_scope('a_loss'):
                        log_prob = normal_dist.log_prob(self.a_his)
                        exp_v = log_prob * tf.stop_gradient(td)
                        entropy = normal_dist.entropy()  # encourage exploration
                        self.exp_v = ENTROPY_BETA * entropy + exp_v
                        self.a_loss = tf.reduce_mean(-self.exp_v)
    
                    with tf.name_scope('choose_a'):  # use local params to choose action
                        self.A = tf.clip_by_value(tf.squeeze(normal_dist.sample(1), axis=[0, 1]), A_BOUND[0], A_BOUND[1])
                    with tf.name_scope('local_grad'):
                        self.a_grads = tf.gradients(self.a_loss, self.a_params)
                        self.c_grads = tf.gradients(self.c_loss, self.c_params)
    
                with tf.name_scope('sync'):
                    with tf.name_scope('pull'):
                        self.pull_a_params_op = [l_p.assign(g_p) for l_p, g_p in zip(self.a_params, globalAC.a_params)]
                        self.pull_c_params_op = [l_p.assign(g_p) for l_p, g_p in zip(self.c_params, globalAC.c_params)]
                    with tf.name_scope('push'):
                        self.update_a_op = OPT_A.apply_gradients(zip(self.a_grads, globalAC.a_params))
                        self.update_c_op = OPT_C.apply_gradients(zip(self.c_grads, globalAC.c_params))
    
        def _build_net(self, scope):
            w_init = tf.random_normal_initializer(0., .1)
            with tf.variable_scope('actor'):
                l_a = tf.layers.dense(self.s, 200, tf.nn.relu6, kernel_initializer=w_init, name='la')
                mu = tf.layers.dense(l_a, N_A, tf.nn.tanh, kernel_initializer=w_init, name='mu')
                sigma = tf.layers.dense(l_a, N_A, tf.nn.softplus, kernel_initializer=w_init, name='sigma')
            with tf.variable_scope('critic'):
                l_c = tf.layers.dense(self.s, 100, tf.nn.relu6, kernel_initializer=w_init, name='lc')
                v = tf.layers.dense(l_c, 1, kernel_initializer=w_init, name='v')  # state value
            a_params = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=scope + '/actor')
            c_params = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=scope + '/critic')
            return mu, sigma, v, a_params, c_params
    
        def update_global(self, feed_dict):  # run by a local
            SESS.run([self.update_a_op, self.update_c_op], feed_dict)  # local grads applies to global net
    
        def pull_global(self):  # run by a local
            SESS.run([self.pull_a_params_op, self.pull_c_params_op])
    
        def choose_action(self, s):  # run by a local
            s = s[np.newaxis, :]
            return SESS.run(self.A, {self.s: s})
    
    

    因为开启的是线程,所以将核心操作代码都放在了Worker类中

    class Worker(object):
        def __init__(self, name, globalAC):
            # 创建游戏环境
            self.env = gym.make(GAME).unwrapped
            # 线程名
            self.name = name
            # 线程名传入神经网络
            self.AC = ACNet(name, globalAC)
    
        def work(self):
            # 回合制循环
            global GLOBAL_RUNNING_R, GLOBAL_EP
            total_step = 1
            buffer_s, buffer_a, buffer_r = [], [], []
            while not COORD.should_stop() and GLOBAL_EP < MAX_GLOBAL_EP:
                s = self.env.reset() #重置环境
                ep_r = 0 #总价值
                for ep_t in range(MAX_EP_STEP):
                    # 最大步数的循环
                    # if self.name == 'W_0':
                    #     self.env.render()
                    # 通过网络选择动作
                    a = self.AC.choose_action(s)
                    # 环境检测当前状态的观测值,价值,是否结束,,,
                    s_, r, done, info = self.env.step(a)
                    # 如果没结束,但是走到最大步数时也结束
                    done = True if ep_t == MAX_EP_STEP - 1 else False
                    # 累计总价值
                    ep_r += r
                    # 记忆库存储,让价值符合正态分布
                    buffer_s.append(s)
                    buffer_a.append(a)
                    buffer_r.append((r + 8) / 8)  # normalize
                    
                    if total_step % UPDATE_GLOBAL_ITER == 0 or done:  # update global and assign to local net
                        if done:
                            v_s_ = 0  # terminal
                        else:
                            v_s_ = SESS.run(self.AC.v, {self.AC.s: s_[np.newaxis, :]})[0, 0]
                        # 
                        buffer_v_target = []
                        for r in buffer_r[::-1]:  # reverse buffer r
                            v_s_ = r + GAMMA * v_s_
                            buffer_v_target.append(v_s_)
                        #     将结果反向传递到ACNet神经网络中
                        buffer_v_target.reverse()
                        # 没有创建记忆库,还是使用最初的QLearning 调用np.hstack栈存储
                        buffer_s, buffer_a, buffer_v_target = np.vstack(buffer_s), np.vstack(buffer_a), np.vstack(
                            buffer_v_target)
                        # 将占位符的值传递到ACNet神经网络中
                        feed_dict = {
                            self.AC.s: buffer_s,
                            self.AC.a_his: buffer_a,
                            self.AC.v_target: buffer_v_target,
                        }
                        # 更新网络权重参数
                        self.AC.update_global(feed_dict)
                        # 清空记忆库
                        buffer_s, buffer_a, buffer_r = [], [], []
                        self.AC.pull_global()
                    # 赋值为下一个观测值
                    s = s_
                    # 下一步
                    total_step += 1
                    if done:
                        # DDpolicy gradient的更新方式,如果没有价值,赋值
                        if len(GLOBAL_RUNNING_R) == 0:  # record running episode reward
                            GLOBAL_RUNNING_R.append(ep_r)
                        else:
                            # 价值等于0.95历史价值,和当前价值的0.05
                            GLOBAL_RUNNING_R.append(0.9 * GLOBAL_RUNNING_R[-1] + 0.1 * ep_r)
                        print(
                            self.name,
                            "Ep:", GLOBAL_EP,
                            "| Ep_r: %i" % GLOBAL_RUNNING_R[-1],
                        )
                        GLOBAL_EP += 1
                        break
    
    
    展开全文
  • 强化学习A3C原理

    千次阅读 2021-05-21 11:14:46
    这样一来一回, 形成了一种有效率的强化学习方式. 我们知道目前的计算机多半是有双核, 4核, 甚至 6核, 8核. 一般的学习方法, 我们只能让机器人在一个核上面玩耍. 但是如果使用 A3C 的方法, 我们可以给他们安排去不同...
  • 深度强化学习——A3C

    万次阅读 多人点赞 2017-06-13 20:32:33
    异步的优势行动者评论家算法(Asynchronous Advantage Actor-Critic,A3C)是Mnih等人根据异步强化学习(Asynchronous Reinforcement Learning, ARL) 的思想,提出的一 种轻量级的 DRL 框架,该框架可以使用异步的...
  • 简单介绍A3C (第五部分) 从本系列课程开始,我们研究了两种不同的强化学习方法: 基于数值的方法(Q-learning,Deep Q-learning):该方法是学习一个值函数,该值函数将每组状态、动作映射到一个数值。多亏了这个...
  • 【深度强化学习A3C

    千次阅读 2020-07-14 15:12:25
    由于普通的Actor-Critic难以收敛,需要一些其他的优化;Asynchronous Advantage Actor-Critic(A3C)就是其中较好的优化算法。
  • for p in threads: p.join() global_model.save_weights('./A3C_LunarLander_2e3_epochs.h5') plt.plot(rewards_plt) plt.show() plt.plot(losses_plt) plt.show() 训练2000轮的奖励变化 训练2000轮的loss变化
  • A3C算法的全称是Asynchronous Advantage Actor-Critic,异步优势执行者/评论者算法。这个算法和优势执行者/评论者算法的区别在于,在执行过程中不是每一步都更新参数,而是在回合结束后用整个轨迹进行更新。因此可以...
  • 本项目利用深度强化学习中的A3C算法提取某支股票的历史数据特征,然后预测未来15天的收盘价格走势。 注: 1)本项目使用tensorflow1.14版本。 2)投资有风险,理财需谨慎。 3)本人选择某股训练结果如下,通过实践...
  • 包括DP, MC, TD, TD-lambda, DQN, PG, AC, A3C, DDPG, Dyna_Q, Bandit, AlphaGoBangZero以及部分仿真游戏源码
  • 强化学习(十五) A3C

    千次阅读 2019-08-01 10:50:35
    强化学习(十四) Actor-Critic中,我们讨论了Actor-Critic的算法流程,但是由于普通的Actor-Critic算法难以收敛,需要一些其他的优化。而Asynchronous Advantage Actor-critic(以下简称A3C)就是其中比较好的优化...
  • 深入浅出理解A3C强化学习

    千人学习 2019-01-11 16:23:09
    本课程是一次理论+实战的结合,首先介绍强化学习的模型原理,详解A3C模型的原理,其次通过实践落实强化学习在游戏中的应用。
  • 为此,DeeoMind团队提出了一种新的算法,称为异步优势行为者评论家(A3C)算法,该算法要优于其他深度强化学习算法,因为其需要较少的计算能力和训练时间。A3C的主要思想是通过多个智能体并行学习并整合其所有经验。 ...
  • 强化学习中,有许多经典的模型,其中一个就是A3C,全称是Asynchronous Advantage Actor-critic。这种模型其实是从之前我们提及的最基本的policy gradient模型一步一步发展来的。最初的强化学习模型中只有一个actor...
  • 强化学习经典算法笔记(十七):A3C算法的PyTorch实现 发现前面没有介绍Asynchronous Advantage Actor-Critic,A3C算法的文章,在这里补上这一篇。 A3C算法简介 A3C算法是非常有名且经典的Policy Gradient算法,是A2C...
  • 并行强化学习算法:A2C/A3C

    千次阅读 2020-06-02 07:07:09
    AsynchronousAdvantageActor-Critic是一种异步的基于优势函数的Actor-Critic并行学习算法。 Actor指需要学习的policy π,Critic指需要学习的Value Function。
  • 学习笔记:强化学习A3C代码详解

    千次阅读 多人点赞 2018-11-18 15:34:21
    写在前面:我是根据莫烦的视频学习的Reinforce learning,具体代码实现包括Q-learning,SARSA,DQN,Policy-Gradient,Actor-Critic以及A3C。(莫凡老师的网站:...
  • 强化学习之AC、A2C和A3C

    千次阅读 2021-09-03 23:24:09
    阅读本文可参考我以前的文章《强化学习实践教学》...首先,A2C的全称是Advantage Actor Critic,而A3C是Asynchronous Advantage Actor Critic,A2C源自A3
  • 强化学习——A3C,GA3C

    千次阅读 2017-08-11 21:00:02
    论文共实现了四种异步训练的强化学习算法,分别是one-step Q-learning, one-step Sarsa, n-step Q-learning, and advantage actor-critic(A3C)。 不同线程的agent,其探索策略不同以保证多样性,不需要经验...
  • 基于python的强化学习算法A3C设计与实现
  • 与其他强化学习库(例如著名的 , 和。 Machin尝试仅提供RL算法的简单明了的实现。 Machin中的所有算法均以最小的抽象设计,并具有非常详细的文档以及各种有用的教程。 2.可重复使用 Machin采用与pytorch类似的方法...
  • 基于策略搜索的强化学习方法 1.policy gridient 1.1 基础推导 1.2 Tip Tip1: add a baseline(增加基线) 因为原来的梯度,一直都会取正数,不是特别合适,但是这样其实无可厚非,因为可以用过大小进行区分,但...
  • A3C全称Asynchronous Advantage Actor-Critic,顾名思义,它采用的是Actor-Critic的形式(需要回顾Actor-Critic的,可以点击这里【强化学习】Actor-Critic(演员-评论家)算法详解)。为了训练一对Actor和Critic,...
  • 随机选择action 特别感谢这位博主的分享,代码亲测注释详细、效果超群 ... QLearning选择action 同样非常感谢这位博主的分享,代码亲测...A3C训练小车爬山 感谢这位博主的分享,这是一份言简意赅的代码,训练过程中小车..
  • # A3C做出的改进: # 解决AC难以收敛的问题 # 不一样的地方: # import threading # import tensorflow as tf import tensorflow.compat.v1 as tf tf.compat.v1.disable_eager_execution() import numpy as np ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,159
精华内容 863
关键字:

强化学习a3c