无模型强化学习:蒙特卡洛与TD算法原理及在生物问题中的实践
30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度如果你是一名生物专业的学生第一次接触“强化学习”这个词可能会觉得它离你的世界很远——那是机器人、游戏AI或者自动驾驶的领域。但请稍等让我们换个角度思考你每天在实验室里做的实验本质上不也是一个“试错-反馈-优化”的过程吗比如你尝试不同的培养基配方动作观察细胞生长情况奖励然后调整下一次的实验方案策略。这个过程与强化学习的核心思想惊人地相似。强化学习并非计算机科学的专属。它是一套关于“智能体如何通过与环境交互来学习最优决策”的通用框架。对于生物研究者而言理解这套框架能为你分析复杂的生物系统如基因调控网络、生态种群动态或优化实验流程提供全新的、量化的视角。本系列文章旨在为生物背景的读者打开这扇门。在前两篇中我们探讨了强化学习的基本范式、马尔可夫决策过程以及基于动态规划的“模型已知”求解方法。然而现实世界中的生物系统其内部机制状态转移概率、即时奖励往往是未知或极其复杂的“黑箱”。我们无法像解方程一样直接算出最优策略。这就引出了我们今天要解决的核心问题当环境模型未知时智能体如何仅通过“尝试”与“观察”来学习这正是“无模型强化学习”的用武之地而蒙特卡洛方法和时序差分算法是其中两大基石。本文将为你清晰地剖析这两种方法蒙特卡洛方法像是一位严谨的实验员必须完成整个实验一个回合后才能分析数据、得出结论而时序差分算法则像一位敏锐的观察者每进行一步操作就立即根据初步结果调整假设。我们将通过一个经典的“悬崖漫步”模拟环境用Python代码亲手实现这两种算法并直观对比它们的学习效率与策略特点。读完本文你将不仅理解这些算法的原理更能掌握其代码实现并能够判断在何种生物信息学或计算生物学场景下该选用哪种方法。让我们开始这次从“理论推演”到“实践学习”的关键跨越。1. 从“全知”到“探索”为何需要无模型学习在上一篇关于动态规划的文章中我们假设智能体完全知晓环境的“游戏规则”——即状态转移概率P(s|s,a)和奖励函数R(s,a,s)。这好比一位生物学家已经完全掌握了某个生化反应通路的所有酶动力学参数可以直接计算出最优的反应条件。然而在绝大多数真实的生物研究场景中我们面对的是“模型未知”的环境药物筛选你不知道某种新化合物对特定靶点的确切作用概率和效果强度只能通过一次次实验细胞实验、动物实验来观察。生态管理你无法精确预测引入一个新物种后整个生态系统每个物种数量变化的概率只能通过干预和监测来学习。实验流程优化你不清楚每个操作步骤如离心时间、温度对最终产物得率的精确影响函数只能通过改变参数并检测结果来摸索。在这些情况下动态规划需要已知模型就无能为力了。我们需要让智能体或我们的算法像科学家一样通过与环境的实际交互来收集数据并从这些数据中学习。这类方法统称为无模型强化学习。无模型强化学习的核心任务是在不依赖环境模型的前提下直接评估策略的好坏策略评估并改进策略策略提升。蒙特卡洛方法和时序差分算法是解决这一任务的两种根本性思路。2. 核心概念辨析蒙特卡洛 vs. 时序差分理解这两种方法关键在于把握它们如何利用经验数据来更新对状态或动作价值的估计。2.1 蒙特卡洛方法完整的实验报告核心思想蒙特卡洛方法通过完整回合的累积回报来估计状态或动作的价值。它必须等待一个回合从开始到终止结束后用整个过程中获得的总奖励来更新这个回合中访问过的所有状态或状态-动作对的价值。生物类比你要评估一种新的培养方案对细胞最终产量的影响。你必须让一批细胞在一整个生长周期结束后测量最终产量然后用这个最终结果来反推和评价培养过程中每个阶段状态所采取操作动作的价值。在获得最终结果前你无法对过程中的任何一步做出评价。公式核心对于某个状态s其价值V(s)的更新目标是该状态之后直到回合结束所获得的实际总回报G_t。V(S_t) ← V(S_t) α [G_t - V(S_t)]其中α是学习率G_t是从时刻t开始到回合结束的折扣累积奖励。优点与局限优点无偏估计。因为使用了真实的完整回报估计值在大量回合平均后会收敛到真实值。局限高方差、必须等待回合结束、只能用于回合制任务。2.2 时序差分算法步步为营的调整核心思想时序差分算法结合了蒙特卡洛的“从经验学习”和动态规划的“自举”思想。它不需要等待回合结束而是利用下一步的估计值来更新当前步的估计值。核心公式TD(0)V(S_t) ← V(S_t) α [R_{t1} γV(S_{t1}) - V(S_t)]其中R_{t1} γV(S_{t1})被称为TD目标δ_t R_{t1} γV(S_{t1}) - V(S_t)被称为TD误差。生物类比在实验过程中你并不等到细胞培养完全结束。而是在每天取样时根据当天的细胞生长密度即时奖励和你对明天密度的预测下一状态的价值来即时调整你对今天所采取操作价值的判断。这是一种“在线”的、持续的学习。与蒙特卡洛的直观对比 假设我们要估计从家到实验室的时间。蒙特卡洛你今天走了一次花了30分钟。那么你今天对“从家出发”这个状态的价值估计就更新为30分钟。你必须走完全程才能获得这个数据。时序差分你今天走到公交站花了5分钟然后你估计从公交站到实验室还要20分钟。那么你此刻就可以更新“从家出发”的估计值为5 20 25分钟。你利用了下一步的估计值来立即更新当前值。核心优势无需等待回合结束可以在线学习通常方差更低收敛更快。3. 环境搭建悬崖漫步问题为了具体实现和对比算法我们引入一个经典示例环境“悬崖漫步”。这是一个网格世界智能体需要从起点左下角安全走到终点右下角但要避开中间的“悬崖”。状态网格中的每个格子共 4行 x 12列 48个状态。动作上、下、左、右4个动作。奖励每走一步奖励 -1鼓励尽快到达终点。掉入悬崖中间底部一排除起点终点的格子奖励 -100并回到起点。到达终点回合结束奖励 0或视为获得正奖励并结束。目标学习一个策略以最安全、最快的路径到达终点。这个环境很好地模拟了生物实验中的风险与收益权衡一条看似更短的路径靠近悬崖风险极高实验失败代价大而一条更安全的路径绕远路虽然步骤多但期望总损失更小。下面我们用Python实现这个环境import numpy as np import matplotlib.pyplot as plt from tqdm import tqdm # 用于显示进度条 class CliffWalkingEnv: def __init__(self, ncol12, nrow4): self.nrow nrow self.ncol ncol self.x 0 # 记录当前智能体位置的横坐标 self.y self.nrow - 1 # 记录当前智能体位置的纵坐标起点在左下角 def step(self, action): # 动作定义0:上, 1:下, 2:左, 3:右 change [[0, -1], [0, 1], [-1, 0], [1, 0]] self.x min(self.ncol - 1, max(0, self.x change[action][0])) self.y min(self.nrow - 1, max(0, self.y change[action][1])) next_state self.y * self.ncol self.x reward -1 done False # 判断是否到达终点或掉下悬崖 if self.y self.nrow - 1 and self.x 0: # 智能体位于最下面一行悬崖行或目标行 done True if self.x ! self.ncol - 1: # 不是终点那就是掉下悬崖了 reward -100 return next_state, reward, done def reset(self): # 重置智能体到起点 self.x 0 self.y self.nrow - 1 return self.y * self.ncol self.x4. Sarsa在线策略的时序差分控制Sarsa 是一个经典的在线策略时序差分控制算法。其名称来源于一次更新所需的数据元组(S_t, A_t, R_{t1}, S_{t1}, A_{t1})。4.1 算法原理Sarsa 的核心在于其更新公式用于更新动作价值函数 Q(s, a)Q(S_t, A_t) ← Q(S_t, A_t) α [R_{t1} γQ(S_{t1}, A_{t1}) - Q(S_t, A_t)]请注意TD目标中使用的下一个动作A_{t1}是根据当前正在被评估和改进的策略通常是ε-greedy策略在状态S_{t1}下采样得到的。这意味着它评估和改进的是它自己正在执行的那个策略因此被称为在线策略学习。算法流程初始化Q表。对每个回合 a. 初始化状态S。 b. 根据当前Q表和ε-greedy策略选择动作A。 c. 当回合未结束时 i. 执行动作A得到奖励R和下一个状态S‘。 ii. 根据当前Q表和ε-greedy策略选择下一个动作A’。 iii. 使用上述公式更新Q(S, A)。 iv.S ← S‘,A ← A’。重复步骤2直到策略收敛。4.2 Python代码实现class Sarsa: Sarsa算法 def __init__(self, ncol, nrow, epsilon, alpha, gamma, n_action4): self.Q_table np.zeros([nrow * ncol, n_action]) # 初始化Q(s,a)表格 self.n_action n_action self.alpha alpha # 学习率 self.gamma gamma # 折扣因子 self.epsilon epsilon # ε-greedy策略中的参数 def take_action(self, state): # ε-greedy策略选择动作 if np.random.random() self.epsilon: action np.random.randint(self.n_action) else: action np.argmax(self.Q_table[state]) return action def update(self, s0, a0, r, s1, a1): # Sarsa更新公式 td_error r self.gamma * self.Q_table[s1, a1] - self.Q_table[s0, a0] self.Q_table[s0, a0] self.alpha * td_error # 训练Sarsa智能体 np.random.seed(0) ncol 12 nrow 4 env CliffWalkingEnv(ncol, nrow) epsilon 0.1 alpha 0.1 gamma 0.9 agent Sarsa(ncol, nrow, epsilon, alpha, gamma) num_episodes 500 return_list [] # 记录每一条序列的回报 for i in range(10): with tqdm(totalint(num_episodes/10), descIteration %d % i) as pbar: for i_episode in range(int(num_episodes/10)): episode_return 0 state env.reset() action agent.take_action(state) done False while not done: next_state, reward, done env.step(action) next_action agent.take_action(next_state) episode_return reward agent.update(state, action, reward, next_state, next_action) state next_state action next_action return_list.append(episode_return) if (i_episode1) % 10 0: pbar.set_postfix({ episode: %d % (num_episodes/10 * i i_episode 1), return: %.3f % np.mean(return_list[-10:]) }) pbar.update(1) # 绘制学习曲线 episodes_list list(range(len(return_list))) plt.plot(episodes_list, return_list) plt.xlabel(Episodes) plt.ylabel(Returns) plt.title(Sarsa on Cliff Walking) plt.show()4.3 结果分析与策略可视化运行上述代码你将看到回报随着训练逐渐提升从约-100提升到约-20。训练结束后我们可以可视化学习到的策略def print_agent(agent, env, action_meaning, disaster[], end[]): for i in range(env.nrow): for j in range(env.ncol): if (i * env.ncol j) in disaster: print(****, end ) elif (i * env.ncol j) in end: print(EEEE, end ) else: a agent.best_action(i * env.ncol j) pi_str for k in range(len(action_meaning)): pi_str action_meaning[k] if a[k] 0 else o print(pi_str, end ) print() action_meaning [^, v, , ] print(Sarsa算法最终收敛到的策略为) print_agent(agent, env, action_meaning, list(range(37, 47)), [47])输出将显示一个策略图。你会发现Sarsa学到的策略会远离悬崖边缘选择一条相对安全但可能更长的路径。这是因为作为在线策略算法它在探索靠近悬崖时一旦掉下去会受到巨大惩罚因此会迅速学会避开高风险区域。5. Q-learning离线策略的时序差分控制Q-learning 是另一个奠基性的时序差分算法也是最著名的强化学习算法之一。它与Sarsa的关键区别在于其更新公式。5.1 算法原理与Sarsa的对比Q-learning 的更新公式为Q(S_t, A_t) ← Q(S_t, A_t) α [R_{t1} γ max_{a}Q(S_{t1}, a) - Q(S_t, A_t)]注意TD目标R_{t1} γ * max_{a}Q(S_{t1}, a)。它使用的是在状态S_{t1}下可能的最大Q值而不是实际采取的动作A_{t1}对应的Q值。这意味着Sarsa在线策略学习的是执行策略behavior policy的价值它更新时考虑的是下一步实际会执行的动作。因此它更“胆小”会考虑到探索带来的风险。Q-learning离线策略学习的是目标策略target policy即贪婪策略的价值它更新时只考虑“最优未来”而用于与环境交互、产生数据的行为策略如ε-greedy可以不同。因此它更“乐观”和“大胆”。一个生动的比喻Sarsa像一个在悬崖边学走路的人他知道自己下一步可能会因为探索ε概率而失足所以他会离悬崖远一点。Q-learning像一个在悬崖边研究地图的人他假设自己下一步总会走最安全的那一步max操作因此他规划出的最优路径可能更贴近悬崖因为地图上那条路最短尽管他实际走的时候因为探索也可能掉下去。5.2 Python代码实现class QLearning: Q-learning算法 def __init__(self, ncol, nrow, epsilon, alpha, gamma, n_action4): self.Q_table np.zeros([nrow * ncol, n_action]) self.n_action n_action self.alpha alpha self.gamma gamma self.epsilon epsilon def take_action(self, state): if np.random.random() self.epsilon: action np.random.randint(self.n_action) else: action np.argmax(self.Q_table[state]) return action def update(self, s0, a0, r, s1): # Q-learning 更新公式注意这里用的是 max_a Q(s1, a) td_error r self.gamma * self.Q_table[s1].max() - self.Q_table[s0, a0] self.Q_table[s0, a0] self.alpha * td_error # 训练Q-learning智能体 np.random.seed(0) epsilon 0.1 alpha 0.1 gamma 0.9 agent QLearning(ncol, nrow, epsilon, alpha, gamma) num_episodes 500 return_list [] for i in range(10): with tqdm(totalint(num_episodes/10), descIteration %d % i) as pbar: for i_episode in range(int(num_episodes/10)): episode_return 0 state env.reset() done False while not done: action agent.take_action(state) next_state, reward, done env.step(action) episode_return reward agent.update(state, action, reward, next_state) state next_state return_list.append(episode_return) if (i_episode1) % 10 0: pbar.set_postfix({ episode: %d % (num_episodes/10 * i i_episode 1), return: %.3f % np.mean(return_list[-10:]) }) pbar.update(1) episodes_list list(range(len(return_list))) plt.plot(episodes_list, return_list) plt.xlabel(Episodes) plt.ylabel(Returns) plt.title(Q-learning on Cliff Walking) plt.show() print(Q-learning算法最终收敛到的策略为) print_agent(agent, env, action_meaning, list(range(37, 47)), [47])5.3 结果对比与深入理解运行代码后你会发现Q-learning学到的最优策略通过agent.best_action打印确实是一条贴着悬崖上沿的最短路径。然而在训练过程中由于其行为策略ε-greedy的探索性它实际获得的平均回报可能比Sarsa更差因为探索时会掉下悬崖。这揭示了离线策略学习的强大之处它能够学习一个与产生数据的行为策略不同的最优策略。Q-learning最终学到的是那个“理想中”的最优路径尽管在探索过程中表现不佳。这也意味着Q-learning可以更好地利用历史数据离线学习因为其更新不依赖于产生数据的具体策略。6. 多步时序差分学习平衡偏差与方差我们之前讨论的Sarsa和Q-learning都是“单步”TD算法。蒙特卡洛方法使用整个回合的回报多步无偏但高方差单步TD使用一步的即时奖励和估计值有偏但低方差。自然的想法是取一个折中n步时序差分学习。6.1 n步Sarsan步Sarsa的更新目标既不是单步的TD目标也不是回合结束的蒙特卡洛回报而是n步的回报G_{t:tn} R_{t1} γR_{t2} ... γ^{n-1}R_{tn} γ^n Q(S_{tn}, A_{tn})当n1时就是单步Sarsa当n趋于无穷大即到回合结束就是蒙特卡洛方法。通过调整n我们可以平滑地在偏差和方差之间进行权衡。6.2 代码实现5步Sarsaclass nstep_Sarsa: n步Sarsa算法 def __init__(self, n, ncol, nrow, epsilon, alpha, gamma, n_action4): self.Q_table np.zeros([nrow * ncol, n_action]) self.n_action n_action self.alpha alpha self.gamma gamma self.epsilon epsilon self.n n # 采用n步Sarsa算法 self.state_list [] # 保存之前的状态 self.action_list [] # 保存之前的动作 self.reward_list [] # 保存之前的奖励 def take_action(self, state): if np.random.random() self.epsilon: action np.random.randint(self.n_action) else: action np.argmax(self.Q_table[state]) return action def update(self, s0, a0, r, s1, a1, done): self.state_list.append(s0) self.action_list.append(a0) self.reward_list.append(r) if len(self.state_list) self.n: # 若保存的数据可以进行n步更新 G self.Q_table[s1, a1] # 得到Q(s_{tn}, a_{tn}) for i in reversed(range(self.n)): G self.gamma * G self.reward_list[i] # 不断向前计算每一步的回报 # 如果到达终止状态最后几步虽然长度不够n步也将其进行更新 if done and i 0: s self.state_list[i] a self.action_list[i] self.Q_table[s, a] self.alpha * (G - self.Q_table[s, a]) s self.state_list.pop(0) # 将需要更新的状态动作从列表中删除下次不必再更新 a self.action_list.pop(0) self.reward_list.pop(0) # n步Sarsa的主要更新步骤 self.Q_table[s, a] self.alpha * (G - self.Q_table[s, a]) if done: # 如果到达终止状态即将开始下一条序列则将列表全清空 self.state_list [] self.action_list [] self.reward_list [] np.random.seed(0) n_step 5 # 5步Sarsa算法 alpha 0.1 epsilon 0.1 gamma 0.9 agent nstep_Sarsa(n_step, ncol, nrow, epsilon, alpha, gamma) num_episodes 500 return_list [] for i in range(10): with tqdm(totalint(num_episodes/10), descIteration %d % i) as pbar: for i_episode in range(int(num_episodes/10)): episode_return 0 state env.reset() action agent.take_action(state) done False while not done: next_state, reward, done env.step(action) next_action agent.take_action(next_state) episode_return reward agent.update(state, action, reward, next_state, next_action, done) state next_state action next_action return_list.append(episode_return) if (i_episode1) % 10 0: pbar.set_postfix({ episode: %d % (num_episodes/10 * i i_episode 1), return: %.3f % np.mean(return_list[-10:]) }) pbar.update(1) episodes_list list(range(len(return_list))) plt.plot(episodes_list, return_list) plt.xlabel(Episodes) plt.ylabel(Returns) plt.title(5-step Sarsa on Cliff Walking) plt.show() print(5步Sarsa算法最终收敛到的策略为) print_agent(agent, env, action_meaning, list(range(37, 47)), [47])你会发现5步Sarsa的收敛速度通常比单步Sarsa更快因为它每一步更新利用了更多未来信息减少了更新的方差。其学到的策略同样倾向于安全路径。7. 关键概念总结与对比为了更清晰地理解我们将核心概念总结如下表特性蒙特卡洛方法时序差分算法 (TD)动态规划 (DP)模型需求无模型无模型需要完整环境模型更新时机必须等待回合结束每一步都可以更新可随时迭代计算更新目标实际累积回报G_tTD目标R_{t1} γV(S_{t1})期望回报E[RγV(S)]偏差/方差无偏高方差有偏低方差无偏依赖模型准确性学习方式离线回合制在线增量式离线模型计算生物类比分析完整实验报告实时调整实验方案根据已知生化通路理论计算在线策略 vs. 离线策略在线策略 (On-policy)如Sarsa。用于生成数据的策略行为策略和被评估改进的策略目标策略是同一个策略。它学习的是自己正在执行的策略更关注实际表现。离线策略 (Off-policy)如Q-learning。行为策略如ε-greedy和目标策略贪婪策略是不同的。它学习的是一个独立的最优策略可以更高效地利用历史探索数据。8. 给生物研究者的启示与实践建议问题建模是关键将你的生物问题转化为强化学习问题是最具挑战也最重要的一步。明确什么是“状态”如实验条件、细胞状态、生态系统指标、“动作”如施加的干预、选择的参数和“奖励”如产物产量、细胞活性、生态稳定性。从简单环境开始像“悬崖漫步”这样的网格世界是完美的沙盒。先用它来理解和测试算法再迁移到更复杂的模拟环境如用ODE模拟的生化反应网络。选择适合的算法如果你的实验成本高、周期长如动物实验更适合离线策略方法如Q-learning可以最大化利用有限的实验数据。如果你的实验可以快速、低成本地迭代如高通量筛选、计算机模拟在线策略方法如Sarsa或多步TD方法可能更容易实现和调试。如果任务有明显的“回合”概念如一个完整的生长周期可以考虑蒙特卡洛方法。超参数调优学习率α、折扣因子γ、探索率ε对结果影响巨大。需要像优化实验条件一样系统地调整这些参数。从仿真到现实先在计算模型或简化系统中验证算法再考虑在真实生物实验中的应用。这能极大降低风险和成本。9. 总结与展望至此你已经掌握了无模型强化学习的两大核心方法蒙特卡洛和时序差分特别是Sarsa和Q-learning。你理解了在线学习与离线学习的根本区别并亲手在代码中实现了它们。这两种方法解决了在环境模型未知时“如何学习”的问题是通往现代深度强化学习如DQN、DDPG的必经之路。对于生物研究者而言它们提供了从“被动观察数据”到“主动交互学习”的范式转变。在接下来的文章中我们将探讨如何用函数近似如神经网络来处理巨大的状态空间例如将显微镜图像或基因表达谱作为状态这就是深度Q网络的核心思想。我们也将初步接触策略梯度方法它直接学习策略函数非常适合动作空间连续或高维的场景例如优化连续的培养参数。建议你运行本文的所有代码改变超参数如epsilon,alpha,gamma观察对学习速度和最终策略的影响。理解这些基础算法在简单环境中的行为是将来处理复杂生物系统强化学习问题的坚实基础。 30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度

相关新闻