强化学习——DQN算法

1、DQN算法介绍

        DQN算与sarsa算法和Q-learning算法类似,对于sarsa和Q-learning,我们使用一个Q矩阵,记录所有的state(状态)和action(动作)的价值,不断学习更新,最后使得机器选择在某种状态下,价值最高的action进行行动。但是当state和action的数量特别大的时候,甚至有限情况下不可数时,这时候再用Q矩阵去记录对应价值就会有很大的局限性,而DQN就是在这一点上进行了改进。在DQN中,对于每种state下采取的action所对应价值,我们将会使用神经网络来进行计算。

2、平衡车游戏的实例

        平衡车游戏在gym库中,这里需要下载gym库,这个游戏中,状态由四个数字来进行表示(我也不知道这四个数字代表什么,但是无伤大雅),接着只会有两种行动,并且reward并不需要我们进行设置,这个游戏进行过程中会自己返回reward。现在先搭建环境

env = gym.make('CartPole-v1')
env.reset()
#打印游戏
def show():
    plt.imshow(env.render(mode='rgb_array'))
    plt.axis('off')
    plt.show()
#show()

 搭建环境后再创建两个神经网络,并且要让两个神经网络的参数一致,在后续的过程中,一个神经网络会延迟更新。这两个神经网络会以四个状态参数作为输入,然后以两个动作的评分作为输出

#创建神经网络

#计算动作模型,也就是真正需要使用的模型
model = torch.nn.Sequential(
    torch.nn.Linear(4,128),
    torch.nn.ReLU(),
    torch.nn.Linear(128,2),
)

#经验网络,用于评估状态分数
next_model = torch.nn.Sequential(
    torch.nn.Linear(4,128),
    torch.nn.ReLU(),
    torch.nn.Linear(128,2)
)

#把两个神经网络的参数统一一下
next_model.load_state_dict(model.state_dict())

#print(model,next_model)

接下来我们需要创建一个样本池,神经网络会在这个样本池中进行学习,随后需要不断更新我们的样本池,当我们有一个新的行动时,我们应该添加新的样本,删除旧的样本,保持样本池最大数量不变

#想样本池中添加一些数据,删除一些古老的数据
def update_date():
    old_count = len(datas)

    while len(datas) - old_count<200:
        #初始化
        state = env.reset()

        over = False
        while not over:
            #获取当前状态得到一个动作
            action = get_action(state)

            #执行动作,得到反馈
            next_state,reward,over,_ = env.step(action)

            #记录样本
            datas.append((state,action,reward,next_state,over))

            #更新状态
            state = next_state

    update_count = len(datas) - old_count
    drop_count = max(len(datas)-10000,0)

    while len(datas)>10000:
        datas.pop(0)
    return update_count,drop_count

        接下来需要进行采样,并将样本格式转换为所需要的格式

#获取一批数据样本
def get_sample():
    # 从样本池中采样
    samples = random.sample(datas, 64)

    state = np.array([i[0] for i in samples])
    action = np.array([i[1] for i in samples])
    reward = np.array([i[2] for i in samples])
    next_state = np.array([i[3] for i in samples])
    over = np.array([i[4] for i in samples])

    state = torch.FloatTensor(state).reshape(-1, 4)
    action = torch.LongTensor(action).reshape(-1, 1)
    reward = torch.FloatTensor(reward).reshape(-1, 1)
    next_state = torch.FloatTensor(next_state).reshape(-1, 4)
    over = torch.LongTensor(over).reshape(-1, 1)

    return state, action, reward, next_state, over

        接着是价值函数(直接交给神经网络就可以了)

def get_value(state,action):
    value = model(state)

    value = value.gather(dim=1,index=action)
    return value

        接下来是获取target函数,这个函数的意义在于,我们是不知道游戏的全貌的,这样的话在一个状态下所采取的行动,不仅仅至于它本身有关,更和接下来所到达的状态和接下来应该采取的行动有关,价值value应该要想target靠近

def get_target(reward,next_state,over):
    with torch.no_grad():
        target = next_model(next_state)

    target = target.max(dim = 1)[0]
    target = target.reshape(-1,1)

    target *= 0.98

    target *= (1-over)#游戏结束了就不用玩了

    target += reward

    return target

然后就是测试函数并开始训练了

def train():
    model.train()
    optimizer = torch.optim.Adam(model.parameters(),lr=2e-3)
    loss_fn = torch.nn.MSELoss()


    for epoch in range(500):
        update_count,drop_count = update_date()

        for i in range(200):
            state,action,reward,next_state,over = get_sample()

            value = get_value(state,action)
            target = get_target(reward,next_state,over)

            loss = loss_fn(value,target)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            if (i+1)%10==0:
                next_model.load_state_dict(model.state_dict())

            if epoch%50==0:
                test_result = sum([tes(play=False) for _ in range(20)])/20
                print(f"Epoch: {epoch}, Data Size: {len(datas)}, Update: {update_count}, Drop: {drop_count}, Test Reward: {test_result}")

接下来是完整代码

#这里会使用神经网络
import gym
import torch
import random
import numpy as np
import matplotlib.pyplot as plt
from IPython import display
from matplotlib.animation import FuncAnimation

env = gym.make('CartPole-v1')
env.reset()
#打印游戏
def show():
    plt.imshow(env.render(mode='rgb_array'))
    plt.axis('off')
    plt.show()
#show()

#创建神经网络

#计算动作模型,也就是真正需要使用的模型
model = torch.nn.Sequential(
    torch.nn.Linear(4,128),
    torch.nn.ReLU(),
    torch.nn.Linear(128,2),
)

#经验网络,用于评估状态分数
next_model = torch.nn.Sequential(
    torch.nn.Linear(4,128),
    torch.nn.ReLU(),
    torch.nn.Linear(128,2)
)

#把两个神经网络的参数统一一下
next_model.load_state_dict(model.state_dict())

#print(model,next_model)


#定义动作函数
def get_action(state):
    if random.random()<0.01:
        return random.choice([0,1])

    state = torch.FloatTensor(state).reshape(1,4)

    return model(state).argmax().item()

#样本池
datas = []

#想样本池中添加一些数据,删除一些古老的数据
def update_date():
    old_count = len(datas)

    while len(datas) - old_count<200:
        #初始化
        state = env.reset()

        over = False
        while not over:
            #获取当前状态得到一个动作
            action = get_action(state)

            #执行动作,得到反馈
            next_state,reward,over,_ = env.step(action)

            #记录样本
            datas.append((state,action,reward,next_state,over))

            #更新状态
            state = next_state

    update_count = len(datas) - old_count
    drop_count = max(len(datas)-10000,0)

    while len(datas)>10000:
        datas.pop(0)
    return update_count,drop_count

#获取一批数据样本
def get_sample():
    # 从样本池中采样
    samples = random.sample(datas, 64)

    state = np.array([i[0] for i in samples])
    action = np.array([i[1] for i in samples])
    reward = np.array([i[2] for i in samples])
    next_state = np.array([i[3] for i in samples])
    over = np.array([i[4] for i in samples])

    state = torch.FloatTensor(state).reshape(-1, 4)
    action = torch.LongTensor(action).reshape(-1, 1)
    reward = torch.FloatTensor(reward).reshape(-1, 1)
    next_state = torch.FloatTensor(next_state).reshape(-1, 4)
    over = torch.LongTensor(over).reshape(-1, 1)

    return state, action, reward, next_state, over


def get_value(state,action):
    value = model(state)

    value = value.gather(dim=1,index=action)
    return value

def get_target(reward,next_state,over):
    with torch.no_grad():
        target = next_model(next_state)

    target = target.max(dim = 1)[0]
    target = target.reshape(-1,1)

    target *= 0.98

    target *= (1-over)

    target += reward

    return target

#测试函数
def tes(play):
    #初始化
    state = env.reset()

    #记录reward之和,越大越好
    reward_sum = 0

    over = False
    while not over:
        #获取动作
        action = get_action(state)

        #执行动作
        state,reward,over,_ = env.step(action)
        reward_sum +=reward

        #打印动画
        if play and random.random()<0.2:#跳帧
            display.clear_output(wait=True)
            show()
    return reward_sum

def train():
    model.train()
    optimizer = torch.optim.Adam(model.parameters(),lr=2e-3)
    loss_fn = torch.nn.MSELoss()


    for epoch in range(500):
        update_count,drop_count = update_date()

        for i in range(200):
            state,action,reward,next_state,over = get_sample()

            value = get_value(state,action)
            target = get_target(reward,next_state,over)

            loss = loss_fn(value,target)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            if (i+1)%10==0:
                next_model.load_state_dict(model.state_dict())

            if epoch%50==0:
                test_result = sum([tes(play=False) for _ in range(20)])/20
                print(f"Epoch: {epoch}, Data Size: {len(datas)}, Update: {update_count}, Drop: {drop_count}, Test Reward: {test_result}")


train()

为什么需要两个神经网络?

这个两个神经网络其实是一致的,只是其中一个会延迟更新参数。

这个原因在于假如在一个游戏中,我们的目标状态并不是固定,可能是一直变换的,就如这个游戏中,平衡的状态是多种多样的,那么我们一直跟踪这个目标就会变得困难,这时我们不妨固定住某一个曾经是目标的状态,让机器先尝试去达到这种状态,再去跟踪下一个固定目标状态,这样的方式会使得机器更容易找到目标状态。这也是为什么需要一个一样的,但是延迟更新的神经网络。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
深度强化学习是结合了深度学习和强化学习的一种算法方法,它的发展历史可以追溯到强化学习和深度学习各自的起源。 强化学习是一种机器学习方法,旨在通过智能体与环境的交互来学习最优的行为策略。其基本思想是通过试错和奖励机制来引导智能体的学习过程。强化学习的发展历史可以追溯到20世纪50年代的动态规划方法,随后逐渐发展出了值函数和策略函数的方法,如Q-learning和SARSA等。然而,传统的强化学习方法在处理高维、复杂的问题时面临着维度灾难和计算复杂性的挑战。 深度学习是一种基于神经网络的机器学习方法,通过多层次的神经网络模型来学习数据的表示和特征提取。深度学习在图像识别、语音识别等领域取得了巨大成功。然而,传统的深度学习方法在处理序列决策问题时存在困难,因为它们缺乏对时间序列和延迟奖励的建模能力。 深度强化学习的发展可以追溯到2013年,当时DeepMind团队提出了一种基于深度神经网络的强化学习算法——深度Q网络(DQN)。DQN通过将强化学习和深度学习相结合,成功地解决了一些复杂的游戏问题。随后,深度强化学习得到了广泛的关注和研究。 在此基础上,深度强化学习的发展又涌现出了一系列的算法,如策略梯度方法、Actor-Critic方法、Proximal Policy Optimization(PPO)等。这些算法通过引入深度神经网络来近似值函数或策略函数,进一步提高了深度强化学习在处理复杂问题上的能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值