3. 强化学习核心概念:马尔可夫决策过程、状态/动作/奖励设计、策略与值函数
好,咱们进入正题。这一章是强化学习的“地基”,说白了就是搞清楚:无人机到底是怎么学会做决策的?
我记得刚接触强化学习那会儿,看了不少论文,满屏的公式,头都大了。后来自己动手写代码,才发现核心就那么几个概念。今天我就把这些东西掰开了讲,保证你听完能上手。
3.1 马尔可夫决策过程(MDP)—— 无人机的“世界观”
强化学习的问题,几乎都可以用马尔可夫决策过程(MDP)来描述。你想想看,无人机在飞行时,它看到的是当前的环境(比如前方有障碍物),然后做出一个动作(比如左转),接着环境变了(障碍物到了右边),它再根据新的状态做决策。这不就是一个典型的MDP吗?
MDP有五个要素,我习惯用一个元组来表示:(S, A, P, R, γ)。
- S(状态空间):无人机能感知到的所有可能情况。比如位置、速度、朝向、与障碍物的距离等。
- A(动作空间):无人机能执行的所有动作。比如前进、后退、左转、右转、悬停等。
- P(状态转移概率):在状态s下执行动作a后,到达状态s'的概率。注意,这个概率是环境决定的,我们通常不知道,需要靠采样来估计。
- R(奖励函数):在状态s下执行动作a后,环境给无人机的一个即时反馈。这个反馈可以是正的(比如靠近目标),也可以是负的(比如撞到障碍物)。
- γ(折扣因子):一个0到1之间的数,用来权衡当前奖励和未来奖励的重要性。γ越接近1,无人机越有“远见”;越接近0,无人机越“短视”。
核心性质:马尔可夫性
未来的状态只取决于当前的状态和动作,与过去的历史无关。说白了就是:“下一刻会发生什么,只取决于你现在在哪儿、做了什么,跟你之前怎么来的没关系。”
这个性质大大简化了问题。我在项目中遇到过,如果不满足马尔可夫性(比如无人机需要记住过去几帧的图像才能判断障碍物运动趋势),那就得用部分可观测马尔可夫决策过程(POMDP),复杂度直接上了一个台阶。
下面这张图,是我自己画的一个MDP流程图,你可以对照着理解:
3.2 状态、动作、奖励设计—— 好的设计是成功的一半
这部分我最有发言权。我在做无人机避障项目时,一开始状态设计得太复杂,把图像像素全塞进去了,结果模型训练了三天都不收敛。后来我简化了状态,只保留位置、速度和最近障碍物的距离,效果立竿见影。
3.2.1 状态设计
状态要满足两个条件:充分性和简洁性。
- 充分性:状态必须包含做出最优决策所需的所有信息。比如,如果无人机需要躲避动态障碍物,那光有位置还不够,还得有障碍物的速度信息。
- 简洁性:在满足充分性的前提下,状态维度越低越好。维度高了,训练难度指数级增长,这就是所谓的“维度灾难”。
我的经验
我建议你从最简单的状态开始,比如只包含无人机自身的坐标和目标点的坐标。如果训练效果不好,再逐步增加信息。千万别一上来就搞个高维状态,否则你会怀疑人生的。
3.2.2 动作设计
动作空间可以是离散的,也可以是连续的。
- 离散动作:比如 {前进, 后退, 左转, 右转, 悬停}。适合简单的任务,实现起来也容易。
- 连续动作:比如 [线速度, 角速度],取值范围是连续的。适合需要精细控制的场景,比如精准降落。
我个人习惯,在项目初期先用离散动作,快速验证算法是否有效。等算法稳定了,再换成连续动作,提升控制精度。
3.2.3 奖励设计
奖励设计是强化学习的“艺术”。设计得好,模型学得又快又好;设计得不好,模型可能学到一些“钻空子”的行为。
我曾经犯过一个错误:为了让无人机尽快到达目标,我给了它一个很大的正向奖励。结果无人机学会了在原地疯狂打转,因为这样也能触发一些中间奖励。嗯,这就是典型的“奖励黑客”。
避坑指南:
- 稀疏奖励 vs 密集奖励:稀疏奖励(只有到达目标才给奖励)训练起来很慢,但学到的策略更鲁棒。密集奖励(每一步都给奖励)训练快,但容易陷入局部最优。我建议先用密集奖励让模型快速入门,再切换到稀疏奖励进行微调。
- 奖励要平滑:奖励函数不要有剧烈的跳变,否则模型会不稳定。比如,靠近目标时奖励逐渐增加,而不是突然给一个大奖。
- 惩罚要合理:撞到障碍物给负奖励是合理的,但不要给得太重,否则无人机可能“躺平”不动了,因为动起来反而更容易被罚。
注意
奖励函数的设计没有标准答案,需要根据具体任务反复调试。我见过一个团队,花了两周时间调奖励函数,最后发现是状态设计出了问题。所以,当你发现模型怎么都学不好时,不妨回头检查一下状态和动作的设计。
3.3 策略与值函数—— 无人机的“大脑”
策略和值函数,是强化学习的两个核心概念。它们回答了同一个问题:“在某个状态下,该做什么?” 只是角度不同。
3.3.1 策略(Policy)
策略就是无人机的“行为准则”。它告诉无人机:在状态s下,应该执行动作a。
策略有两种表示方式:
- 确定性策略:
a = π(s)。给定状态s,输出唯一的动作a。比如,前方有障碍物,就左转。 - 随机性策略:
π(a|s)。给定状态s,输出一个动作的概率分布。比如,前方有障碍物,有80%的概率左转,20%的概率右转。
随机性策略在探索阶段特别有用。你想啊,如果无人机总是走同一条路,它怎么知道旁边那条路会不会更好呢?
3.3.2 值函数(Value Function)
值函数是“评估师”。它评估在某个状态(或状态-动作对)下,未来能获得多少累积奖励。
有两种常见的值函数:
- 状态值函数 V(s):从状态s开始,按照策略π行动,能获得的期望累积奖励。
- 动作值函数 Q(s, a):在状态s下执行动作a,之后按照策略π行动,能获得的期望累积奖励。
Q函数比V函数更“精细”,因为它直接告诉你每个动作的好坏。在Q-learning算法中,我们就是通过不断更新Q函数来找到最优策略的。
核心关系
策略和值函数是“共生”的。策略决定了值函数的值,而值函数反过来又可以改进策略。这就是强化学习中的“广义策略迭代”思想。
说白了,就是“你评估我,我改进你,循环往复,直到最优”。
下面这个表格,总结了策略和值函数的区别:
| 概念 | 定义 | 作用 | 例子 |
|---|---|---|---|
| 策略 π | 状态到动作的映射 | 决定“做什么” | π(前方有障碍物) = 左转 |
| 状态值函数 V(s) | 状态s的长期价值 | 评估“这个状态好不好” | V(靠近目标) = 0.9 |
| 动作值函数 Q(s, a) | 在状态s下执行动作a的长期价值 | 评估“这个动作好不好” | Q(靠近目标, 前进) = 0.95 |
3.4 一个简单的代码示例
光说不练假把式。下面我用一个极简的Q-learning算法,演示一下这些概念是怎么落地的。这个例子中,无人机在一个一维的直线上飞行,目标是到达最右侧的点。
import numpy as np
# 状态空间:0, 1, 2, 3, 4 (共5个位置)
# 动作空间:0 (左移), 1 (右移)
# 目标状态:4
n_states = 5
n_actions = 2
Q = np.zeros((n_states, n_actions)) # Q表,存储每个状态-动作对的值
# 参数
alpha = 0.1 # 学习率
gamma = 0.9 # 折扣因子
epsilon = 0.1 # 探索率
# 奖励函数
def get_reward(state):
if state == 4: # 到达目标
return 1.0
else:
return 0.0
# 状态转移(环境模型)
def step(state, action):
if action == 0: # 左移
next_state = max(0, state - 1)
else: # 右移
next_state = min(n_states - 1, state + 1)
reward = get_reward(next_state)
return next_state, reward
# Q-learning 训练
for episode in range(100):
state = 0 # 初始状态
while state != 4:
# ε-贪婪策略选择动作
if np.random.rand() < epsilon:
action = np.random.randint(n_actions) # 探索
else:
action = np.argmax(Q[state, :]) # 利用
next_state, reward = step(state, action)
# Q值更新
Q[state, action] += alpha * (reward + gamma * np.max(Q[next_state, :]) - Q[state, action])
state = next_state
print("训练后的Q表:")
print(Q)
print("最优策略(每个状态应该执行的动作):")
print(np.argmax(Q, axis=1))
这段代码虽然简单,但包含了MDP的所有要素:状态、动作、奖励、策略(ε-贪婪)、值函数(Q表)。你跑一下就会发现,无人机很快就学会了“一直向右走”这个最优策略。
小提示
你可以试着改一下奖励函数,比如给左移一个负奖励,看看无人机会不会学会“绕路”。这就是奖励设计对策略的影响,非常直观。
好了,这一章的内容就到这儿。核心就是:MDP是框架,状态/动作/奖励是输入,策略和值函数是输出。搞懂了这些,后面的算法学起来就轻松多了。