当前位置: 首页 > news >正文

强化学习的原理

好的!让我们完全抛开代码,用机械臂的例子来直观理解强化学习的核心原理。

核心比喻:教小孩玩「盲人摸象」游戏

想象你在教一个蒙着眼睛的小孩走到房间某个位置:

1. 状态 - 「你现在在哪里」

状态就是小孩对当前环境的感知:

  • 关节角度:胳膊、腿的弯曲程度
  • 位置信息:离目标还有多远(前/后、左/右)
  • 环境反馈:是否碰到墙壁

在机械臂中

  • 状态 = 4个关节的角度 + 末端离目标点的距离

2. 动作 - 「你可以怎么动」

动作就是小孩可以做的移动:

  • 胳膊向前/向后摆动
  • 腿向前/向后迈步
  • 身体左转/右转

在机械臂中

  • 动作 = 每个关节增加1度/减少1度/保持不动
  • 4个关节 × 3种选择 = 81种可能的动作组合

3. 奖励 - 「这个动作好不好」

奖励就是给小孩的即时反馈:

情况奖励说明
向目标靠近一步+1分「做得好,方向对了!」
远离目标-1分「不对,走反了」
到达目标+100分「太棒了!找到了!」
碰到墙壁-10分「小心,撞墙了」

关键:奖励告诉智能体短期的好坏,但不告诉它长期的最优策略。


最核心的概念:Q值 - 「从这步开始,长远能得多少分」

Q值的直观理解:

Q(状态, 动作) = 「在当前这个位置,选择这个动作走下去,最终我能得到的总分数」

例子

  • 你现在站在房间中央(状态)
  • 考虑「向前走一步」(动作)
  • Q值就是:从这一步开始,最终到达目标时能得到的所有奖励总和

Q值的神奇之处:

它包含了未来所有步骤的预期回报,而不仅仅是眼前这一步的奖励。


「反向倒推」原理:从终点往回算

这是Q-learning最精妙的部分!让我们用倒推的方式思考:

情景:教机械臂到达目标点

步骤4(最后一步)

  • 状态:离目标只有1cm
  • 动作:稍微移动就能碰到目标
  • Q值 = 立即奖励100分(因为成功了)

步骤3

  • 状态:离目标5cm
  • 动作:选择往目标方向移动
  • Q值 = 当前奖励(向目标靠近+1分) + 下一步的最大Q值(100分) = 101分

步骤2

  • 状态:离目标10cm
  • 动作:选择正确方向
  • Q值 = 当前奖励(+1分) + 下一步的最大Q值(101分) = 102分

步骤1(起点)

  • 状态:初始位置
  • 动作:选择正确方向
  • Q值 = 当前奖励(+1分) + 下一步的最大Q值(102分) = 103分

这就是「价值传播」:

成功的价值像涟漪一样,从终点反向传播到起点


完整的学习过程:试错 + 价值积累

第一次尝试(完全随机):

起点 → 乱走 → 撞墙 → 失败
Q值:都很低(因为没成功过)

第N次尝试(偶然成功):

起点 → 正确方向 → 更接近 → 到达目标!
  • 最后一步的Q值被更新为100
  • 倒数第二步学到:「从那个位置往那个方向走,最终能得100分」
  • 价值一步步往回传播

经过大量训练后:

每个(状态, 动作)对的Q值都包含了「从那里开始的最佳路径的总价值」


决策过程:跟着Q值走

训练完成后,决策变得非常简单:

在每个状态

  1. 查看所有可能动作的Q值
  2. 选择Q值最高的动作
  3. 执行该动作

这就保证了智能体总是选择长期回报最高的路径。


在机械臂中的具体体现:

状态离散化:

因为Q-table不能存无限个状态,我们把连续的角度和距离分成几个区间:

  • 关节1角度:0-30°、30-60°、60-90°…
  • 离目标距离:0-2cm、2-4cm、4-6cm…

学习过程:

  1. 探索期:随机尝试各种动作,建立初步的Q值估计
  2. 利用期:逐渐倾向于选择已知的高Q值动作
  3. 收敛期:找到接近最优的策略,Q值稳定

最终效果:

机械臂学会了一条「从任何位置到目标位置」的最优路径,就像人学会了闭着眼睛也能摸到房间里的开关一样。

这就是强化学习的魅力:不需要告诉它具体怎么走,只需要定义「什么是对的」,它自己通过试错找出最佳方法!

好的!让我为每个核心原理写一个极简的代码示例:

1. 状态 - 环境感知

class RobotArmState:def __init__(self):# 状态:4个关节角度 + 离目标的距离self.joint_angles = [90, 90, 90, 90]  # 初始角度self.target_position = [5, 5, 5]      # 目标位置def get_state(self):"""获取当前状态"""current_pos = self._calculate_position()  # 根据角度计算末端位置distance = self._calculate_distance(current_pos)# 状态 = 角度 + 距离state = self.joint_angles + [distance]return statedef _calculate_position(self):"""简化版:根据关节角度计算末端位置"""# 实际中会用运动学公式,这里简化x = self.joint_angles[0] / 10y = self.joint_angles[1] / 10  z = self.joint_angles[2] / 10return [x, y, z]def _calculate_distance(self, current_pos):"""计算到目标的距离"""dx = current_pos[0] - self.target_position[0]dy = current_pos[1] - self.target_position[1]dz = current_pos[2] - self.target_position[2]return (dx**2 + dy**2 + dz**2) ** 0.5# 使用示例
arm_state = RobotArmState()
print("当前状态:", arm_state.get_state())
# 输出: [90, 90, 90, 90, 12.0] (角度 + 距离)

2. 动作 - 行为选择

class ActionSpace:def __init__(self):# 动作:每个关节可以 [-1, 0, +1] 三种变化self.actions = []# 生成所有可能的动作组合 (3^4 = 81种)for a1 in [-1, 0, 1]:for a2 in [-1, 0, 1]:for a3 in [-1, 0, 1]:for a4 in [-1, 0, 1]:self.actions.append([a1, a2, a3, a4])def get_random_action(self):"""随机选择动作(探索)"""import randomreturn random.choice(self.actions)def decode_action(self, action_index):"""根据索引获取动作"""return self.actions[action_index]# 使用示例  
action_space = ActionSpace()
random_action = action_space.get_random_action()
print("随机动作:", random_action)  # 如: [1, 0, -1, 0]

3. 奖励 - 即时反馈

class RewardSystem:def __init__(self):self.best_distance = float('inf')def calculate_reward(self, old_state, new_state, action):"""计算奖励值"""old_distance = old_state[-1]  # 旧距离new_distance = new_state[-1]  # 新距离# 基础奖励:距离改进improvement = old_distance - new_distancereward = improvement * 2  # 改进奖励# 成功奖励if new_distance < 1.0:reward += 100  # 大成功奖励!# 惩罚剧烈变化action_magnitude = sum(abs(a) for a in action)if action_magnitude > 2:reward -= 1  # 小惩罚return reward# 使用示例
reward_system = RewardSystem()
old_state = [90, 90, 90, 90, 10.0]  # 距离10
new_state = [91, 90, 90, 90, 9.8]   # 距离9.8 (更近了)
action = [1, 0, 0, 0]               # 关节1增加1度reward = reward_system.calculate_reward(old_state, new_state, action)
print("获得的奖励:", reward)  # 输出: 0.4 (因为改进了0.2 × 2)

4. Q值 - 长期价值

class QTable:def __init__(self, state_size, action_size):# Q表: 状态 → 动作 → 价值self.q_table = {}self.state_size = state_sizeself.action_size = action_sizedef _discretize_state(self, state):"""将连续状态离散化(简化版)"""# 把角度分成几个区间,距离也离散化discrete_state = []for i, value in enumerate(state):if i < 4:  # 角度:每30度一个区间bin_index = min(int(value / 30), 5)  # 0-5else:      # 距离:每5一个区间  bin_index = min(int(value / 5), 3)   # 0-3discrete_state.append(bin_index)return tuple(discrete_state)def get_q_value(self, state, action_index):"""获取Q值"""discrete_state = self._discretize_state(state)# 如果状态没见过,初始化为0if discrete_state not in self.q_table:self.q_table[discrete_state] = [0] * self.action_sizereturn self.q_table[discrete_state][action_index]def update_q_value(self, state, action_index, new_value):"""更新Q值"""discrete_state = self._discretize_state(state)if discrete_state not in self.q_table:self.q_table[discrete_state] = [0] * self.action_sizeself.q_table[discrete_state][action_index] = new_value# 使用示例
q_table = QTable(state_size=5, action_size=81)
state = [90, 90, 90, 90, 10.0]
action_idx = 40  # 某个动作q_value = q_table.get_q_value(state, action_idx)
print("当前Q值:", q_value)  # 输出: 0 (初始值)

5. 反向传播 - Q值更新

class QLearning:def __init__(self, learning_rate=0.1, discount_factor=0.9):self.lr = learning_rate      # 学习率self.gamma = discount_factor # 折扣因子def update(self, q_table, state, action_index, reward, next_state):"""Q-learning更新公式"""# 当前Q值current_q = q_table.get_q_value(state, action_index)# 下一个状态的最大Q值max_next_q = 0for next_action in range(q_table.action_size):next_q = q_table.get_q_value(next_state, next_action)max_next_q = max(max_next_q, next_q)# Q-learning核心公式!target_q = reward + self.gamma * max_next_qnew_q = current_q + self.lr * (target_q - current_q)# 更新Q表q_table.update_q_value(state, action_index, new_q)return new_q# 使用示例
q_learning = QLearning()
state = [90, 90, 90, 90, 10.0]      # 当前状态
next_state = [91, 90, 90, 90, 9.8]  # 下一个状态  
action_idx = 40                      # 执行的动作
reward = 0.4                         # 获得的奖励new_q = q_learning.update(q_table, state, action_idx, reward, next_state)
print("更新后的Q值:", new_q)  # 输出: 0.04 (0 + 0.1 × (0.4 + 0.9×0 - 0))

6. 完整决策流程

class RobotAgent:def __init__(self, state_size, action_size, exploration_rate=0.1):self.q_table = QTable(state_size, action_size)self.q_learning = QLearning()self.exploration_rate = exploration_rateself.action_space = ActionSpace()def choose_action(self, state):"""选择动作:探索 vs 利用"""import random# 探索:随机选择动作if random.random() < self.exploration_rate:action_idx = random.randint(0, len(self.action_space.actions)-1)return action_idx, self.action_space.actions[action_idx]# 利用:选择Q值最高的动作else:best_value = -float('inf')best_action_idx = 0for action_idx in range(len(self.action_space.actions)):q_value = self.q_table.get_q_value(state, action_idx)if q_value > best_value:best_value = q_valuebest_action_idx = action_idxreturn best_action_idx, self.action_space.actions[best_action_idx]def learn(self, state, action_idx, reward, next_state):"""从经验中学习"""self.q_learning.update(self.q_table, state, action_idx, reward, next_state)# 使用示例
agent = RobotAgent(state_size=5, action_size=81)# 决策过程
state = [90, 90, 90, 90, 10.0]
action_idx, action = agent.choose_action(state)
print(f"状态: {state}, 选择动作: {action}")# 学习过程  
next_state = [91, 90, 90, 90, 9.8]
reward = 0.4
agent.learn(state, action_idx, reward, next_state)

核心原理总结:

  1. 状态:机器知道自己现在什么样
  2. 动作:机器可以选择做什么
  3. 奖励:环境告诉机器做得好不好
  4. Q值:机器记住「从某个状态做某个动作,最终能得多少分」
  5. 反向传播:从成功经验往回推,更新整条路径的Q值

这些代码虽然简单,但完整展示了强化学习的核心机制!

好的!让我展示如何用神经网络替代Q表,我会保持极简风格:

1. 神经网络Q函数 - 替代Q表

import numpy as npclass NeuralNetworkQ:def __init__(self, state_size, action_size):self.state_size = state_size    # 输入维度:状态特征数self.action_size = action_size  # 输出维度:动作数# 极简神经网络参数(权重和偏置)self.weights1 = np.random.randn(state_size, 64) * 0.1  # 输入到隐藏层self.weights2 = np.random.randn(64, action_size) * 0.1 # 隐藏层到输出self.bias1 = np.zeros(64)self.bias2 = np.zeros(action_size)self.learning_rate = 0.001def predict(self, state):"""神经网络前向传播:输入状态,输出所有动作的Q值"""state = np.array(state).reshape(1, -1)# 隐藏层计算hidden = np.dot(state, self.weights1) + self.bias1hidden = np.maximum(0, hidden)  # ReLU激活函数# 输出层:每个动作的Q值q_values = np.dot(hidden, self.weights2) + self.bias2return q_values[0]  # 返回所有动作的Q值def train(self, state, target_q_values):"""训练神经网络,让它预测的Q值接近目标值"""state = np.array(state).reshape(1, -1)# 前向传播hidden = np.dot(state, self.weights1) + self.bias1hidden_relu = np.maximum(0, hidden)q_values = np.dot(hidden_relu, self.weights2) + self.bias2# 计算梯度(简化版反向传播)error = q_values - target_q_values# 输出层梯度d_weights2 = np.dot(hidden_relu.T, error)d_bias2 = np.sum(error, axis=0)# 隐藏层梯度d_hidden = np.dot(error, self.weights2.T)d_hidden[hidden <= 0] = 0  # ReLU导数d_weights1 = np.dot(state.T, d_hidden)d_bias1 = np.sum(d_hidden, axis=0)# 更新参数self.weights1 -= self.learning_rate * d_weights1self.bias1 -= self.learning_rate * d_bias1self.weights2 -= self.learning_rate * d_weights2self.bias2 -= self.learning_rate * d_bias2# 使用示例
nn_q = NeuralNetworkQ(state_size=5, action_size=81)
state = [90, 90, 90, 90, 10.0]q_values = nn_q.predict(state)
print("神经网络预测的Q值:", q_values[:5])  # 只看前5个动作

2. 深度Q学习智能体 - 替代Q表智能体

class DeepQLearningAgent:def __init__(self, state_size, action_size):self.state_size = state_sizeself.action_size = action_sizeself.q_network = NeuralNetworkQ(state_size, action_size)self.exploration_rate = 1.0self.exploration_decay = 0.995self.min_exploration = 0.01self.gamma = 0.9  # 折扣因子def choose_action(self, state):"""选择动作:探索 vs 利用"""if np.random.random() < self.exploration_rate:# 探索:随机选择return np.random.randint(self.action_size)else:# 利用:选择神经网络预测的Q值最高的动作q_values = self.q_network.predict(state)return np.argmax(q_values)def learn(self, state, action, reward, next_state, done):"""深度Q学习更新"""# 1. 预测当前状态的Q值current_q_values = self.q_network.predict(state)# 2. 计算目标Q值if done:target = reward  # 回合结束,目标就是即时奖励else:next_q_values = self.q_network.predict(next_state)max_next_q = np.max(next_q_values)target = reward + self.gamma * max_next_q# 3. 只更新执行的那个动作的Q值,其他动作保持不变target_q_values = current_q_values.copy()target_q_values[action] = target# 4. 训练神经网络self.q_network.train(state, target_q_values)# 5. 衰减探索率if self.exploration_rate > self.min_exploration:self.exploration_rate *= self.exploration_decay# 使用示例
dqn_agent = DeepQLearningAgent(state_size=5, action_size=81)
state = [90, 90, 90, 90, 10.0]action = dqn_agent.choose_action(state)
print(f"选择的动作索引: {action}")# 学习示例
next_state = [91, 90, 90, 90, 9.8]
reward = 0.4
dqn_agent.learn(state, action, reward, next_state, done=False)

3. 经验回放 - 提高学习效率

class ExperienceReplay:def __init__(self, capacity=1000):self.memory = []self.capacity = capacityself.position = 0def add(self, state, action, reward, next_state, done):"""添加经验到记忆库"""experience = (state, action, reward, next_state, done)if len(self.memory) < self.capacity:self.memory.append(experience)else:self.memory[self.position] = experienceself.position = (self.position + 1) % self.capacitydef sample(self, batch_size):"""随机采样一批经验"""indices = np.random.choice(len(self.memory), batch_size, replace=False)batch = [self.memory[i] for i in indices]# 重新组织数据states = np.array([exp[0] for exp in batch])actions = np.array([exp[1] for exp in batch])rewards = np.array([exp[2] for exp in batch])next_states = np.array([exp[3] for exp in batch])dones = np.array([exp[4] for exp in batch])return states, actions, rewards, next_states, dones# 使用示例
replay_buffer = ExperienceReplay(capacity=1000)# 添加一些经验
for i in range(10):replay_buffer.add(state=[90+i, 90, 90, 90, 10.0-i],action=np.random.randint(81),reward=np.random.uniform(-1, 1),next_state=[91+i, 90, 90, 90, 9.8-i],done=False)# 采样一批经验
batch_states, batch_actions, batch_rewards, batch_next_states, batch_dones = replay_buffer.sample(3)
print(f"采样到 {len(batch_states)} 条经验")

4. 完整的深度Q学习训练

class AdvancedDQNAgent(DeepQLearningAgent):def __init__(self, state_size, action_size):super().__init__(state_size, action_size)self.replay_buffer = ExperienceReplay(capacity=1000)self.batch_size = 32def replay(self):"""从经验回放中学习"""if len(self.replay_buffer.memory) < self.batch_size:return# 采样一批经验states, actions, rewards, next_states, dones = self.replay_buffer.sample(self.batch_size)# 批量训练for i in range(self.batch_size):self.learn(states[i], actions[i], rewards[i], next_states[i], dones[i])def remember(self, state, action, reward, next_state, done):"""记住经验"""self.replay_buffer.add(state, action, reward, next_state, done)# 完整训练流程示例
def train_dqn_agent():agent = AdvancedDQNAgent(state_size=5, action_size=81)arm_state = RobotArmState()  # 之前定义的状态类for episode in range(1000):state = arm_state.get_state()total_reward = 0for step in range(100):  # 最大步数# 选择动作action_idx = agent.choose_action(state)action = agent.action_space.actions[action_idx]# 执行动作(简化)# 实际中这里会控制机械臂运动arm_state.joint_angles = [a + delta * 5 for a, delta in zip(arm_state.joint_angles, action)]# 获取新状态和奖励next_state = arm_state.get_state()reward = reward_system.calculate_reward(state, next_state, action)# 检查是否完成done = (next_state[-1] < 1.0)  # 距离小于1表示成功# 记住经验agent.remember(state, action_idx, reward, next_state, done)# 学习agent.replay()state = next_statetotal_reward += rewardif done:breakif episode % 100 == 0:print(f"回合 {episode}, 总奖励: {total_reward:.2f}, 探索率: {agent.exploration_rate:.3f}")# 开始训练
# train_dqn_agent()

5. 神经网络 vs Q表的对比

# Q表方式(之前)
q_table = QTable(state_size=5, action_size=81)
state = [90, 90, 90, 90, 10.0]
q_value = q_table.get_q_value(state, 40)  # 查表
print("Q表方式:", q_value)# 神经网络方式(现在)
nn_q = NeuralNetworkQ(state_size=5, action_size=81)
q_values = nn_q.predict(state)  # 神经网络计算
print("神经网络方式:", q_values[40])print("\n神经网络优势:")
print("1. 可以处理连续状态,不需要离散化")
print("2. 可以泛化到没见过的状态")
print("3. 适合高维状态空间(如图像输入)")
print("4. 内存效率更高(存储网络参数而非巨大表格)")

核心改进总结:

  1. Q表 → 神经网络:从查表变成函数逼近
  2. 离散状态 → 连续状态:不需要手动离散化
  3. 单步学习 → 批量学习:通过经验回放提高效率
  4. 表格存储 → 参数存储:内存占用大幅降低

神经网络的核心优势:它学会了状态到Q值的映射函数,即使遇到没见过的状态,也能给出合理的Q值预测!

http://www.dtcms.com/a/582664.html

相关文章:

  • Python 装饰器原理与实战技巧(深度解析生成机制)
  • 全国各地网站开发外包餐饮网站建设教程
  • python购物网站开发流程专业制作网站有哪些
  • 中小学校园网站建设wordpress使用邮箱验证
  • 深入剖析C++临时对象:从创建到优化
  • OLED代码演示-使用缓存区
  • 怎么查看网站disallow找做网站
  • C语言结构体入门:定义、访问与传参全解析
  • 住房城乡建设部门户网站苏州建设公司有哪些
  • 软件工程综合实践3实验报告——校园二手交易平台系统(黑龙江大学)
  • 设计制作网站板面网站建设优化开发公司哪家好
  • “职场心态与心穷
  • 网站怎么做微信支付宝wordpress占用cpu过高
  • 郑州网站推广营销百度搜索引擎竞价排名
  • 班级网站建设思路手机模板网站模板下载
  • Rust 练习册 :Nucleotide Codons与生物信息学
  • 东坑网站仿做麻涌镇做网站
  • stm32的gpio模式到底该怎么选择?(及iic,spi,定时器原理介绍)
  • 【MySQL】触发器、日志、锁机制 深度解析
  • 电商网站后台艺术设计
  • 【湖北政务服务网-注册_登录安全分析报告】
  • 酒店网站模板设计方案网站页面设计需求文档
  • Databend 十月月报:存储过程正式可用,数据流程全面自动化
  • 湖南大型网站建设公司登陆国外网站速度慢
  • 百度恶意屏蔽网站wordpress 渗透框架
  • 算法数学---差分数组(Difference Array)
  • 石家庄城乡建设局网站服装定制品牌有哪些
  • PrettyZoo:优雅易用的 ZooKeeper 可视化管理工具
  • Trae下架Claude,但Vibe Coding之路才刚刚开始
  • 哪些行业网站推广做的多上海制作网站开发