【强化学习】常用算法之一 “SARSA”

简介: 强化学习是一种通过学习与环境交互来最大化累积奖励的方法。在强化学习中,一个智能体在特定环境中根据当前状态选择一个动作,执行该动作后,环境将转移到新的状态,并且智能体将获得奖励。强化学习的目标是通过学习,使智能体能够选择一系列能够获取最大累积奖励的动作序列,即找到最优策略。SARSA算法是一种基于状态-动作值的强化学习算法,用来学习最优策略。本文详细介绍了强化学习中的SARSA算法,包括其发展历程、算法原理、功能以及使用方法,并给出了求解迷宫问题的示例代码。

强化学习是一种机器学习方法,通过与环境不断交互来学习最优行为策略。SARSA(State-action-reward-state-action)算法是强化学习中的经典算法之一,用于求解马尔可夫决策过程(Markov Decision Process, MDP)中的最优策略。本文将详细介绍SARSA算法的发展历程、算法原理、功能以及使用方法,并附带示例代码和运行结果。

本文将详细讲解强化学习常用算法之一“SARSA”


image.png
一、简介
强化学习是一种通过学习与环境交互来最大化累积奖励的方法。在强化学习中,一个智能体在特定环境中根据当前状态选择一个动作,执行该动作后,环境将转移到新的状态,并且智能体将获得奖励。强化学习的目标是通过学习,使智能体能够选择一系列能够获取最大累积奖励的动作序列,即找到最优策略。SARSA算法是一种基于状态-动作值的强化学习算法,用来学习最优策略。

二、发展史
SARSA算法最早由Richard Sutton和Andrew Barto在他们的著作《强化学习导论》中提出。SARSA是Q-learning算法的一种特例,也是一种基于值函数的算法。

    Q-learning算法是一种基于状态-动作值的强化学习算法,它通过维护一个Q值表(存储每个状态-动作对的状态-动作值)来学习最优策略。然而,Q-learning算法必须对Q值表进行离散化处理,因此只适用于状态空间和动作空间较小且离散的问题。为了解决这个问题,Richard Sutton等人提出了SARSA算法。

    SARSA算法是一种基于值函数和策略的算法,它不需要对状态空间和动作空间进行离散化处理,适用于连续状态和动作的问题。该算法使用一个Q值函数和一个策略函数来近似最优策略。

三、算法公式

  1. SARSA算法公式
     SARSA算法的更新公式如下:
    

image.png
其中,Q(s, a)表示在状态s下选择动作a的状态-动作值,r表示执行动作a后获得的即时奖励,α表示学习率,γ表示折扣因子,s’表示转移到的新状态,a’表示在新状态s’下选择的动作。

  1. SARSA算法原理
     SARSA算法的核心思想是通过不断更新状态-动作值函数Q(s, a)来学习最优策略。该算法按照以下步骤进行:
    

初始化状态-动作值函数Q(s, a)和策略函数π(a|s)的值。
在每个时间步t中,依据当前状态s和策略函数π选择一个动作a。
执行动作a,观察获得的即时奖励r和新状态s’。
根据新状态s’和策略函数π选择一个新动作a’。
更新状态-动作值函数Q(s, a)的值,使用SARSA更新公式。
将新状态s’和新动作a’作为下一步的状态s和动作a。
重复上述步骤,直到达到终止条件。
通过不断迭代更新状态-动作值函数Q(s, a),SARSA算法可以逐步逼近最优状态-动作值函数,从而得到最优策略。

四、算法功能
SARSA算法具有以下功能:

模型无关性:SARSA算法不需要对环境模型进行假设,只通过与环境交互来学习最优策略。
收敛性:在一定条件下,SARSA算法保证会收敛到最优策略。
适用性:SARSA算法适用于状态空间和动作空间较大且连续的问题,而不需要对状态空间和动作空间进行离散化处理。
五、示例代码


import numpy as np

# 定义迷宫环境
maze = np.array([
    [0, 0, 0, 0],
    [0, -1, 0, -1],
    [0, 0, 0, -1],
    [-1, 0, 0, 1]
])

# 定义起始状态和终止状态
start_state = (3, 0)
goal_state = (3, 3)

# 定义动作空间
actions = [(0, 1), (0, -1), (-1, 0), (1, 0)]

# 初始化状态-动作值函数
Q = np.zeros((4, 4, 4))

# 定义参数
alpha = 0.1
gamma = 0.9
epsilon = 0.1
max_episodes = 100

# SARSA算法 
for episode in range(max_episodes):
    state = start_state
    action = np.random.choice(range(4)) if np.random.rand() < epsilon else np.argmax(Q[state])

    while state != goal_state:
        # next_state = (state[0] + actions[action][0], state[1] + actions[action][1])
        a = state[0] + actions[action][0]
        b = state[1] + actions[action][1]
        if a > 3:
            a-=1
        elif b > 3:
            b-=1
        elif a < -4:
            a+= 1
        elif b < -4:
            b+= 1
        next_state = (a,b)
        reward = maze[next_state]
        next_action = np.random.choice(range(4)) if np.random.rand() < epsilon else np.argmax(Q[next_state])
        Q[state][action] += alpha * (reward + gamma * Q[next_state][next_action] - Q[state][action])

        state = next_state
        action = next_action

# 输出结果
for i in range(4):
    for j in range(4):
        print("State:", (i, j))
        print("Up:", Q[i][j][0])
        print("Down:", Q[i][j][1])
        print("Left:", Q[i][j][2])
        print("Right:", Q[i][j][3])
        print()

运行结果如下:


State: (0, 0)
Up: -0.008042294056935573
Down: -0.007868742418369764
Left: -0.016173595452674966
Right: 0.006662566560762523

State: (0, 1)
Up: 0.048576025675988774
Down: -0.0035842473161881465
Left: 0.024420015715567546
Right: -0.46168987981312615

State: (0, 2)
Up: 0.04523751845081987
Down: 0.04266319340558091
Left: 0.044949583791193154
Right: 0.026234839551098416

State: (0, 3)
Up: 0.01629652821649763
Down: 0.050272192325180515
Left: -0.009916869922464355
Right: -0.4681667868865369

State: (1, 0)
Up: -0.09991342319696966
Down: 0.0
Left: 0.0
Right: 0.036699099068340166

State: (1, 1)
Up: 0.008563965102313987
Down: 0.0
Left: 0.0
Right: 0.3883250678150607

State: (1, 2)
Up: -0.3435187267522706
Down: -0.2554776873673874
Left: 0.05651543121932354
Right: 0.004593450910446022

State: (1, 3)
Up: -0.1
Down: -0.013616634831997914
Left: 0.01298827764814053
Right: 0.0

State: (2, 0)
Up: 0.28092113053540924
Down: 0.0
Left: 0.0024286388798406364
Right: 0.06302299434701504

State: (2, 1)
Up: 0.0
Down: 0.0
Left: -0.16509175606504775
Right: 1.9146361697676122

State: (2, 2)
Up: -0.1
Down: 0.0
Left: 0.03399106390140035
Right: 0.0

State: (2, 3)
Up: -0.3438668479533914
Down: 0.004696957810272524
Left: -0.19
Right: 0.0

State: (3, 0)
Up: 3.3060693607932445
Down: 0.8893977121867367
Left: 0.0
Right: 0.13715553550041798

State: (3, 1)
Up: 4.825854511712306
Down: -0.03438123168566812
Left: 0.10867882029322147
Right: 1.0015572397722665

State: (3, 2)
Up: 5.875704328143301
Down: 0.9315770230698863
Left: 0.0006851481810742227
Right: 0.47794799892127526

State: (3, 3)
Up: 5.4028951599661275
Down: 2.6989177956329757
Left: -0.6454474033238188
Right: 0.018474082554518417
    通过运行示例代码,我们可以得到每个状态下的最优动作及对应的状态-动作值。

六、总结
本文详细介绍了强化学习中的SARSA算法,包括其发展历程、算法原理、功能以及使用方法,并给出了求解迷宫问题的示例代码。SARSA算法能够实现模型无关性和收敛性,适用于状态空间和动作空间较大且连续的问题。通过对状态-动作值函数的迭代更新,SARSA算法可以逐步逼近最优策略,并通过与环境交互来学习最优行为策略。
image.png

目录
相关文章
|
7月前
|
机器学习/深度学习 算法 Python
【Python强化学习】时序差分法Sarsa算法和Qlearning算法在冰湖问题中实战(附源码)
【Python强化学习】时序差分法Sarsa算法和Qlearning算法在冰湖问题中实战(附源码)
105 1
|
7月前
|
机器学习/深度学习 人工智能 算法
【PyTorch深度强化学习】TD3算法(双延迟-确定策略梯度算法)的讲解及实战(超详细 附源码)
【PyTorch深度强化学习】TD3算法(双延迟-确定策略梯度算法)的讲解及实战(超详细 附源码)
1190 1
|
2月前
|
机器学习/深度学习 算法 机器人
多代理强化学习综述:原理、算法与挑战
多代理强化学习是强化学习的一个子领域,专注于研究在共享环境中共存的多个学习代理的行为。每个代理都受其个体奖励驱动,采取行动以推进自身利益;在某些环境中,这些利益可能与其他代理的利益相冲突,从而产生复杂的群体动态。
229 5
|
13天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法及应用
探索人工智能中的强化学习:原理、算法及应用
|
13天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法与应用
探索人工智能中的强化学习:原理、算法与应用
|
4月前
|
机器学习/深度学习 算法 TensorFlow
深入探索强化学习与深度学习的融合:使用TensorFlow框架实现深度Q网络算法及高效调试技巧
【8月更文挑战第31天】强化学习是机器学习的重要分支,尤其在深度学习的推动下,能够解决更为复杂的问题。深度Q网络(DQN)结合了深度学习与强化学习的优势,通过神经网络逼近动作价值函数,在多种任务中表现出色。本文探讨了使用TensorFlow实现DQN算法的方法及其调试技巧。DQN通过神经网络学习不同状态下采取动作的预期回报Q(s,a),处理高维状态空间。
63 1
|
4月前
|
机器学习/深度学习 存储 算法
强化学习实战:基于 PyTorch 的环境搭建与算法实现
【8月更文第29天】强化学习是机器学习的一个重要分支,它让智能体通过与环境交互来学习策略,以最大化长期奖励。本文将介绍如何使用PyTorch实现两种经典的强化学习算法——Deep Q-Network (DQN) 和 Actor-Critic Algorithm with Asynchronous Advantage (A3C)。我们将从环境搭建开始,逐步实现算法的核心部分,并给出完整的代码示例。
306 1
|
4月前
|
测试技术 数据库
探索JSF单元测试秘籍!如何让您的应用更稳固、更高效?揭秘成功背后的测试之道!
【8月更文挑战第31天】在 JavaServer Faces(JSF)应用开发中,确保代码质量和可维护性至关重要。本文详细介绍了如何通过单元测试实现这一目标。首先,阐述了单元测试的重要性及其对应用稳定性的影响;其次,提出了提高 JSF 应用可测试性的设计建议,如避免直接访问外部资源和使用依赖注入;最后,通过一个具体的 `UserBean` 示例,展示了如何利用 JUnit 和 Mockito 框架编写有效的单元测试。通过这些方法,不仅能够确保代码质量,还能提高开发效率和降低维护成本。
54 0
|
5月前
|
机器学习/深度学习 存储 数据采集
强化学习系列:A3C算法解析
【7月更文挑战第13天】A3C算法作为一种高效且广泛应用的强化学习算法,通过结合Actor-Critic结构和异步训练的思想,实现了在复杂环境下的高效学习和优化策略的能力。其并行化的训练方式和优势函数的引入,使得A3C算法在解决大规模连续动作空间和高维状态空间的问题上表现优异。未来,随着技术的不断发展,A3C算法有望在更多领域发挥重要作用,推动强化学习技术的进一步发展。
|
6月前
|
机器学习/深度学习 分布式计算 算法
在机器学习项目中,选择算法涉及问题类型识别(如回归、分类、聚类、强化学习)
【6月更文挑战第28天】在机器学习项目中,选择算法涉及问题类型识别(如回归、分类、聚类、强化学习)、数据规模与特性(大数据可能适合分布式算法或深度学习)、性能需求(准确性、速度、可解释性)、资源限制(计算与内存)、领域知识应用以及实验验证(交叉验证、模型比较)。迭代过程包括数据探索、模型构建、评估和优化,结合业务需求进行决策。
60 0