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

简单的强化学习举例

1,定义奖励函数

首先,需要根据具体的任务需求来定义奖励函数。例如,对于机器人导航任务,可以根据机器人与目标点的距离来定义奖励函数:

import numpy as npdef navigation_reward(robot_position, target_position):# 计算机器人当前位置与目标位置之间的欧几里得距离distance = np.linalg.norm(np.array(robot_position) - np.array(target_position))# 距离越近,奖励越高reward = -distancereturn reward

2. 集成奖励函数到环境中

在强化学习中,环境负责与智能体进行交互,并根据智能体的动作给出相应的奖励。通常,环境类会有一个 step 方法,该方法接受智能体的动作作为输入,并返回下一个状态、奖励、是否终止等信息

import numpy as npclass NavigationEnv: # 定义导航环境类def __init__(self):# 初始化机器人的起始位置和目标位置self.robot_position = np.array([0, 0]) # 机器人初始位置 (x=0, y=0)self.target_position = np.array([10, 10]) # 目标位置 (x=10, y=10)def step(self, action):# 核心逻辑:执行动作 → 更新状态 → 计算奖励 → 判断终止# 根据动作更新机器人的位置self.robot_position += action # 通过向量加法更新位置# 通过向量加法更新机器人位置。例如,若动作是 [2, 3],新位置为 (0+2, 0+3) = (2, 3)# 计算奖励reward = navigation_reward(self.robot_position, self.target_position)# 判断是否到达目标位置done = np.linalg.norm(self.robot_position - self.target_position) < 0.1# 返回下一个状态、奖励、是否终止等信息,返回四元组return self.robot_position, reward, done, {}

3. 在训练循环中使用奖励函数

在训练智能体时,需要在每个时间步调用环境的 step 方法,并根据返回的奖励来更新智能体的策略。以下是一个简单的训练循环示例:

代码分为三大部分:

  1. 环境 (NavigationEnv)

    • 状态:机器人的二维坐标
    • 动作:离散动作空间 (0 = 向右移动,1 = 向上移动)
    • 奖励:负距离 (-distance),鼓励机器人靠近目标
  2. 策略网络 (PolicyNetwork)

    • 输入:机器人当前位置 (二维向量)
    • 输出:两个动作的概率分布
    • 结构:两层全连接网络,使用 ReLU 激活和 softmax 输出
  3. 训练循环

    • 收集数据:每个 episode 收集状态、动作、奖励序列
    • 计算回报:使用折扣因子计算每个时间步的累积回报
    • 更新策略:通过最大化累积回报的对数概率来更新网络参数
# 修正后的完整代码
import numpy as np
import torch
import torch.optim as optimclass NavigationEnv:def __init__(self):self.reset() ## 初始化时直接调用reset方法def reset(self):self.robot_position = np.array([0.0, 0.0])self.target_position = np.array([10.0, 10.0])return self.robot_positiondef step(self, action):self.robot_position += action # # 执行动作(向量加法)distance = np.linalg.norm(self.robot_position - self.target_position)reward = -distance  # 简单奖励函数,奖励设计:距离越近奖励越高(负值越小)done = distance < 0.1 # 终止条件:距离目标小于0.1单位return self.robot_position, reward, done, {}class PolicyNetwork(torch.nn.Module):def __init__(self, input_size, output_size):super().__init__()self.fc1 = torch.nn.Linear(input_size, 128) # 输入层→隐藏层(128神经元)self.fc2 = torch.nn.Linear(128, output_size) # 隐藏层→输出层(动作维度)def forward(self, x):x = torch.relu(self.fc1(x)) # ReLU激活函数引入非线性 return torch.softmax(self.fc2(x), dim=-1) # 输出动作概率分布env = NavigationEnv()
policy_net = PolicyNetwork(2, 2) # 输入状态维度2,输出动作数2
optimizer = optim.Adam(policy_net.parameters(), lr=0.001) # 自适应学习率优化器
action_map = {0: np.array([1,0]), 1: np.array([0,1])} # 动作映射表 0向右移动1个单位,1向上移动1个单位
gamma = 0.99 #未来奖励折扣因子
for episode in range(1000): #训练1000轮state = env.reset()  # 重置环境done = Falserewards, states, actions = [], [], [] # 数据收集容器while not done:state_tensor = torch.FloatTensor(state) # 转为PyTorch张量probs = policy_net(state_tensor)        # 获取动作概率action_idx = torch.multinomial(probs, 1).item() # 按概率抽样动作action = action_map[action_idx]         # 转换为实际动作向量next_state, reward, done, _ = env.step(action)  # 环境反馈# 存储轨迹数据rewards.append(reward)                  states.append(state_tensor)actions.append(action_idx)state = next_state  # 状态更新# 计算累积回报returns = []cumulative = 0for r in reversed(rewards):             # 从最后一步反向计算cumulative = r + gamma * cumulative # 计算累积回报returns.insert(0, cumulative)       # 保持时序# 策略梯度更新optimizer.zero_grad()                   # 清空梯度for s, a, R in zip(states, actions, returns):prob = policy_net(s)                # 重新计算动作概率(需梯度)log_prob = torch.log(prob[a])       # 选择动作的对数概率loss = -log_prob * R                # 策略梯度损失loss.backward()                     # 反向传播累积梯度optimizer.step()print(f"Episode {episode}, Total Reward: {sum(rewards):.1f}")
  1. Episode 0

    • 初始位置 (0,0)

    • 随机选择动作:可能频繁撞墙(若未加边界约束)

    • 奖励约 -200(低效路径)

  2. Episode 500

    • 网络学会向目标方向移动

    • 路径呈现锯齿形(探索仍在进行)

    • 奖励提升至 -50

  3. Episode 1000

    • 稳定选择向右和向上动作

    • 直线接近目标,奖励接近 0

    • 成功收敛

优化方向建议

  1. 状态归一化:将坐标范围缩放到 [-1,1] 加速训练

  2. 经验回放:使用 deque 存储历史数据,随机采样更新

  3. 熵正则化:在损失函数中添加熵项鼓励探索

  4. Advantage Actor-Critic:引入价值函数估计优势值

http://www.xdnf.cn/news/397711.html

相关文章:

  • 笔试阶段性心得总结
  • 模块化编程
  • ACM模式手动构建二叉树
  • 算法导论第9章思考题
  • 深入理解深度循环神经网络(Deep RNN)
  • Beta分布--贝叶斯建模概率或比例常用分布
  • eNsp的使用
  • 数据结构【二叉树的遍历实现】
  • 免费公共DNS服务器推荐
  • 如何读论文【论文精读】
  • opencascade.js stp vite webpack 调试笔记
  • C++ STL编程 vector空间预留、vector高效删除、vector数据排序、vector代码练习
  • 风扇接口
  • 自制PowerPoint荧光笔插件指南
  • 集合(超详细)
  • 【人工智能】DeepSeek的崛起-下一代AI模型的秘密武器
  • 微调自qwen3的无审查大模型(需谨慎使用):Josiefied-Qwen3-8B-abliterated-v1
  • LeetCode 热题 100 101. 对称二叉树
  • 单链表C语言实现(付代码全)
  • 进程检测与控制
  • C++学习之STL学习
  • 联合类型的逻辑或关系与类型保护
  • 关于我在实现用户头像更换时遇到的图片上传和保存的问题
  • Colab使用_文件操作
  • C++.IP协议通信
  • 【C++进阶】第3课—二叉搜索树
  • C++猴子摘桃 2024年信息素养大赛复赛 C++小学/初中组 算法创意实践挑战赛 真题详细解析
  • [超详细,推荐!!!]前端性能优化策略详解
  • VC++ 获取CPU信息的两种方法
  • POSIX信号量