MATLAB 60行代码讲透Q-Learning:网格寻路与贝尔曼方程实战
简介针对强化学习入门者与MATLAB算法研究者提供一份Q-Learning源代码及详尽注释文档。案例设定为王子在16×1网格世界寻找公主通过上下左右动作避开障碍与陷阱完整演示环境建模、奖赏矩阵设计、epsilon-greedy策略和贝尔曼方程更新Q值等核心流程。压缩包只有1个doc文件大小33KB适合快速下载并对照代码逐行理解算法细节。目前已有1378人学习特别适合想通过简单游戏实例掌握无模型强化学习决策原理的读者。资料内包含可移动矩阵、奖赏矩阵、折扣因子gamma、学习率epsilon的设置说明训练循环与Q值更新步骤均有注释读完后还能利用最终Q矩阵规划最优路径为后续迁移到复杂任务打下扎实基础。1. Q-Learning 到底是什么一个 16 格的寻路游戏讲透无模型决策先给结论这份 MATLAB 源码不是工业级的强化学习框架而是一个把 Q-Learning 核心逻辑压缩到 60 行以内的教学样本。它用一个 4×4 网格的王子救公主游戏把状态、动作、奖赏、Q 值更新、ε-greedy 策略全部落地成可直接运行的代码。对刚接触强化学习的人它比任何教科书伪代码都直观对已经跑过 PyTorch 或 TensorFlow 的从业者这份代码反而是最干净的裸算法参考——没有框架封装、没有分布式训练、没有经验回放只有贝尔曼方程最朴素的表达。适合三类人一是想用 MATLAB 快速验证强化学习思路的研究生二是准备面试强化学习岗位、需要手推 Q-Learning 流程的求职者三是教《人工智能导论》需要可复现案例的教师。值得注意的是这份代码 900 次 episode 的训练量对 16 个状态来说绰绰有余但它刻意保留了可读性而不是性能优化所以别拿它去跑大规模连续状态空间的任务。2. 先建模再求解可移动矩阵与奖赏矩阵的设计逻辑2.1 环境建模16 个格子的状态空间与动作边界代码的核心数据结构是 16×16 的矩阵 TT(i,j)0 表示无法从 i 移动到 j1 表示可移动。这个设计很有意思它没有用常见的坐标偏移而是用一维编号直接索引。4×4 网格中每个格子的编号从上到下、从左到右依次是 1 到 16。四个基本动作被定义为上移是 i-1、下移是 i1、左移是 i-4、右移是 i4。边界条件的处理是这段代码最值得读的地方。上行动作检查 1、5、9、13 这四个编号因为它们在每一列的最顶端再往上就越界了。下行动作反过来检查 4、8、12、16这是每列的最底端。左行动作要求 i4右行动作要求 i13分别对应第一行和最后一行的边界。这种边界判断相比传统的 if-else 嵌套更紧凑但它把网格拓扑硬编码进了编号规则一旦改成更复杂的图结构比如带环路的迷宫就得重写整个矩阵。障碍物设置在源码里用了两行极简的代码。T(:,[10,11,14])0 把 10、11、14 三个位置的所有入边和出边全部切断这里有个技术细节需要注意该语句只设置入边为 0如果要彻底隔离障碍物还需要将障碍物位置的出边也置为 0。第 13 格的跳跃动作是另一个关键设计T(13,:)0 清空第 13 格的所有动作然后单独设置 T(13,15)1相当于给王子一个从 13 直接跳到 15 的传送门。这种清空再赋值的写法写得很清晰比逐个置 0 更不容易漏掉某个方向。2.2 奖赏矩阵的参数玄学为什么终点要设 10、陷阱要设 -5R 矩阵的初始化逻辑是理解整个算法收敛性的钥匙。R-1*ones(16) 给所有状态-动作对的即时奖赏都设为 -1这代表每走一步都有时间成本。然后 R(:,6)0 把第 6 格设为中性区域R(:,7)-5 把第 7 格设为陷阱R(:,16)10 把终点公主所在的位置设为最大正奖赏R(13,15)5 为跳跃动作设中间奖赏。这里的奖赏设计有很强的教学意图。如果所有非目标状态的奖赏都是 -1Q-Learning 会倾向于走最短路径因为每一步的即时惩罚在累积。如果某些格子设 0会引导 Agent 绕行这些区域它们不惩罚但也不奖励只作为过渡格。-5 的陷阱惩罚比 -1 大得多Agent 在训练初期会因为 Q 值尚不稳定而随机踩入但后期会被有效避开。10 的终点奖赏设置为超过一切路径累积惩罚之和否则 Agent 可能学到不走到终点循环绕行的投机策略这在连续任务里是个常见翻车点但在这里被 10 的绝对值压住了。还有个隐藏参数容易被忽略折扣因子 gamma0.8。0.8 表示未来奖励折算到当前的值越小越目光短浅越接近 1 越有远见。代码取 0.8 偏保守因为网格世界只有 16 个格子最长路径也不会超过 15 步0.8 的衰减足够把终点的 10 折算到沿途每个状态上。如果把 gamma 改成 0.1王子在第 1 格时看到终点奖励折算后只有 10×0.1^14几乎等于零训练效果会显著退化。这个参数是整个算法中最敏感的超参调试时优先动它。% 定义可移动矩阵 T T zeros(16); % T(i,j)0 表示不可从 i 位置移动至 j 位置1 则为可移动 for i 1:16 % 上行动作 N不能在第一列1,5,9,13执行 if not(ismember(i, [1, 5, 9, 13])) T(i, i - 1) 1; end % 下行动作 S不能在第四列4,8,12,16执行 if not(ismember(i, [4, 8, 12, 16])) T(i, i 1) 1; end % 左行动作 W不能在第一行1-4执行 if i 4 T(i, i - 4) 1; end % 右行动作 E不能在第四行13-16执行 if i 13 T(i, i 4) 1; end end % 障碍物10、11、14 三个格子不可进入 T(:, [10, 11, 14]) 0; % 跳跃从 13 可直接到达 15 T(13, :) 0; T(13, 15) 1;这段代码的逻辑很直白先用双层循环补齐所有合法移动再用两个赋值语句粗暴地砍掉障碍物和跳跃的例外。not(ismember(i, ...))的写法比逐列 if 判断更优雅但在大规模网格下性能会下降因为 ismember 是线性搜索。我一般习惯把边界编号预计算成集合比如边界集合 B然后if ~ismember(i, B)这样循环内只做一次集合查找。2.3 奖赏矩阵的完整结构从即时奖励到长期回报奖赏矩阵的完整赋值在代码中通过连续矩阵切片完成。这里把关键的奖赏设计逻辑整理成表格方便对照修改参数。位置或动作奖赏值含义修改建议所有非特殊位置-1每一步的时间成本调成 -0.5 会鼓励绕远路调成 -2 会更追求最短路径第 6 列R(:,6)00中性过渡区域在不改变路径长度的前提下可以多设几个训练会更快第 7 列R(:,7)-5-5陷阱惩罚增大到 -10 会让 Agent 绕行更果断但需要更多训练轮次第 16 列R(:,16)1010终点奖赏建议保持大于 10否则可能出现循环绕行不结束第 13 行到第 15 列R(13,15)55跳跃动作的即时奖赏这是传送门的代价设为 5 说明抄近道有额外收益R 矩阵和 T 矩阵的关系需要特别强调T 决定哪里能走R 决定走了以后划不划算。Q-Learning 的更新公式会同时受这两个矩阵影响如果 T 中某条边可以走但 R 中对应位置是 -5Agent 在探索初期会不断踩坑直到 Q 值收敛后学会避开。这个能走但不值得走的对比是整个强化学习里最难向新手讲清楚的部分这份代码通过 7 号陷阱格非常直观地呈现出来了。% 定义奖赏矩阵 R R -1 * ones(16); R(:, 6) 0; % 第 6 格为中性区域无额外惩罚 R(:, 7) -5; % 第 7 格为陷阱大幅惩罚 R(:, 16) 10; % 终点公主所在位置最大奖赏 R(13, 15) 5; % 跳跃动作的奖赏这段代码的执行顺序有讲究先全矩阵赋 -1再覆盖特殊位置。R(:, 6)0是把第 6 列全部置零这意味着从任意格子移动到第 6 格的即时奖赏都是 0注意这里矩阵的行是当前状态、列是下一状态。理解这个方向的映射是读懂后面 Q 值更新公式的前提一旦搞反了会把整条训练过程都带偏。3. epsilon-greedy 策略与 Q 值更新从贝尔曼方程到 MATLAB 实现3.1 训练循环结构900 个 episode 里发生了什么训练循环的核心代码不长但信息密度极高。外层 900 次 episode 迭代内层 while 循环持续到状态到达 16 为止。每次 episode 开始时stateunidrnd(16)在 1 到 16 之间随机取整然后while ismember(state,[10,11,14])把初始状态重新采样直到避开障碍物。这个做法在实际使用时要注意一个隐患如果障碍物占比过高比如超过 50%随机重采样可能死循环。这个案例只有三个障碍格重采样最多若干次就能跳出循环但我在跑自己的仿真网格20% 障碍时确实遇到过卡死后来改成了预生成可达状态列表再从中随机选。内层循环每走一步就更新一次 Q 值。possible_actionsfind(T(state,:)1)找出当前状态下所有合法动作的索引possible_QQ(state,possible_actions)取出这些动作对应的 Q 值。这里find返回的是动作编号即下一状态的编号整个代码用状态编号直接充当动作编号简化了实现但也让代码语义不够直观——对初学者容易造成困惑。判断是否探索的判断条件是if rand()epsilon小于 0.3 就随机选动作否则选 Q 值最大的动作。这段逻辑体现了 epsilon-greedy 策略的核心以 epsilon 概率探索否则利用。它最大的优点是简单且收敛性有理论保障缺点是 epsilon 固定不变石头策略训练后期最优动作已经找到后仍然有 30% 的随机扰动导致策略不稳定。如果要改进常见做法是设置衰减因子让 epsilon 从 0.9 逐渐下降到 0.01这份代码没有做这个处理是一个值得动手改的优化点。3.2 Q 值更新公式为什么这一行代码就是全部秘密Q 值更新的核心语句是Q(state,action)R(state,action)gamma*max(Q(action,:))。这是贝尔曼方程最简洁的实现。拆开看R(state,action)是当前状态执行动作得到的即时奖赏max(Q(action,:))是在下一状态中所有可能动作的 Q 值最大值即对未来回报的最优估计gamma是折扣系数把未来回报折算到当下。整个更新式表达的含义是新的 Q 值 当前回报 折扣 × 下一状态的最优未来回报。这行代码有个容易踩的坑更新完成后stateaction直接跳转到下一状态。如果action恰好是障碍物位置理论上如果 R 和 T 矩阵不一致就会发生比如 T 矩阵忘了清零某条边程序不会报错但 Q 值会沿着非法路径传播。判断 R 和 T 的一致性应该在做训练前就验证一次一个简单方法是检查所有T(i,j)1的位置对应的R(i,j)不为 NaN 且数值有界。还有一处隐蔽的设计max(Q(action,:))计算时把终点状态 16 也包括进去了。Q(16,:) 全为零这意味着到达终点后未来奖励的估算是 0。这个设计是否合理取决于任务定义如果是到达终点即终止的单幕任务终点后没有未来回报所以设为 0 完全合理。但如果是持续任务到达终点后重置并继续就需要给终点状态单独设计出口值。这个细节区分了回合制任务和连续任务是实际工程里最容易忽略的边界。% 初始化 Q 矩阵 Q zeros(16); % 折扣因子 gamma控制未来奖励的重要性 gamma 0.8; % epsilon-greedy 策略的探索概率 epsilon 0.3; % 训练循环 for episode 1:900 % 随机化初始状态确保不在障碍物上 state unidrnd(16); while ismember(state, [10, 11, 14]) state unidrnd(16); end % 内层循环直到到达终点状态 16 while state ~ 16 % 获取当前状态下所有合法动作 possible_actions find(T(state, :) 1); % 获取对应 Q 值 possible_Q Q(state, possible_actions); % epsilon-greedy 策略选择动作 if rand() epsilon % 随机探索 choose unidrnd(length(possible_actions)); action possible_actions(choose); else % 利用选 Q 值最大的动作 [~, index] max(possible_Q); action possible_actions(index); end % 核心贝尔曼方程更新 Q 值 Q(state, action) R(state, action) gamma * max(Q(action, :)); % 状态转移 state action; end % 每 100 个 episode 输出一次进度 if mod(episode, 100) 0 fprintf(训练的次数为:%d\n, episode); end end disp(训练结束);这段代码中rand()epsilon的判断是理解探索与利用平衡的关键。epsilon0.3 表示每次决策有 30% 概率随机选动作70% 概率选当前最优。这个比例在小型网格任务里效果不错但在更复杂的任务中固定 0.3 的探索率会让收敛速度变慢。我一般会在训练初期把 epsilon 设为 0.6 加速探索然后每个 episode 乘以 0.995 衰减到训练后期接近零这样既能找到最优解又能稳定收敛。3.3 策略评估与路径规划训练后如何用 Q 矩阵训练结束后代码进行了一次路径规划演示。start_01设定起点pathstart_0初始化路径向量。while path(end)~16循环中[~,next]max(Q(start_0,:))找到起点行中 Q 值最大的动作path[path,next]把下一步加入路径然后start_0next更新当前位置。这段代码有个隐含假设从起点出发一定能到达终点。如果 Q 矩阵还没完全收敛比如训练次数不够max(Q(start_0,:))可能返回一个 Q 值很小的动作甚至循环到某个状态后卡在局部最优不来。判断 Q 矩阵是否收敛的方法很简单对每个状态检查max(Q(state,:))是否在多次运行中保持稳定。更工程化的验证方法是设计一个独立测试集随机取 50 个起始状态分别用 Q 矩阵跑路径统计平均步数和成功率。这份代码没有做这个步骤我复现时一般会补上这段验证逻辑。还有一个细节值得注意max(Q(start_0,:))的语义是选择 Q 值最大的动作但如果两个动作 Q 值相同比如对称位置max 会取索引小的那个MATLAB 的约定这可能导致路径偏向某一侧。如果对路径多样性有要求可以在 max 之前加randperm打乱同值动作的顺序但这份代码为了演示简洁没有处理。% 训练后寻找路径 start_0 1; % 设置起始点 path start_0; % 初始化路径向量 while path(end) ~ 16 [~, next] max(Q(start_0, :)); % 找当前状态 Q 值最大的动作 path [path, next]; % 加入路径 start_0 next; % 更新当前状态 end % 输出最优路径 disp(path);这段测试代码是整个算法最直接的落地验证。路径的每一步都是贪心选择当前状态的 Q 最大值不涉及任何探索因此得到的路径一定是当前 Q 矩阵下的最优路径。如果训练充分这条路径就是全局最优路径如果训练不足路径会表现出明显的绕路或卡死可以用来反推训练是否收敛。4. 参数调节与避坑我把这份代码跑挂了五次才摸清的三类问题4.1 随机性陷阱同样的代码两次运行结果不同第一次跑这份代码时我连续运行了两次发现输出的一次路径偶有不同。原因很容易理解源程序里涉及随机生成初始状态的 unidrnd 和随机探索 rand每次实验产生的结果天然存在差异但这份代码没有设定随机种子导致每次运行产生的探索序列完全随机。如果希望实验可复现应该在脚本开头加上rng(0)或rng(default)固定随机数生成器的种子。对论文实验来说这是一条黄金法则不给随机种子意味着审稿人无法复现你的结果。我从那以后每次跑强化学习代码第一行都会强制写上rng(42)既保证可复现又避免改代码调参时分不清是参数影响还是随机性影响。4.2 终点 Q 值的自举陷阱Q(16,:) 全是零意味着什么细看 Q 更新公式会注意一个问题当state15且action16即走到终点时更新式为Q(15,16)R(15,16)gamma*max(Q(16,:))。由于Q(16,:)全部初始化为零所以max(Q(16,:))0最终Q(15,16)R(15,16)010。这意味着到达终点后的未来回报被定义为 0这个值是否合理完全取决于任务定义。如果你在原有代码基础上把终点改造为到达后自动跳转到起点并继续任务这是连续任务的标准玩法那么Q(16,:)应该改为R(16,:)gamma*max(Q(...))的某种设计否则 Agent 会永远选择在终点停留因为那里的 Q 值最高。这个终点状态的值函数设计是 Q-Learning 里区分回合任务与连续任务的分水岭也是初学者最容易翻车的点。正确做法是预先定义好终点的后续状态和奖赏而不是默认全零。4.3 跳跃边界的维度问题T(13,:)0 会不会误伤合法动作源码中T(13,:)0; T(13,15)1先把第 13 行的所有边清零再单独打开 13 到 15 的边。这个顺序让我一开始忽略了它清空了 13 到 9、13 到 14如果不在障碍物列表里等合法方向。好在原代码里第 14 格本来就是障碍物所以这里没出问题。但如果读者要复用到自己的网格遇到 13 有原本到 14 的需求就会被这行T(13,:)0一起砍掉。最稳妥的做法是显式地单独关掉不需要的边而不是整行清零再补一根。例如T(13,[9,10,14])0; T(13,15)1的写法语义更清晰。我不知道源代码这样写是有意为之还是为了简洁但从工程角度来说这种清空-再赋值的模式在代码审查中属于高危操作因为它极容易砍掉不该砍的边从而改变环境拓扑。4.4 障碍物状态初始化重采样的空转问题while ismember(state,[10,11,14])的重采样循环在障碍物较少时没问题但如果障碍物概率超过 50%比如你改成一个 8×8 的网格中间半块都是障碍这个重采样循环的平均迭代次数会急剧增加极端情况下接近死循环。更稳健的初始化方式是从合法状态集合中直接随机选一个valid_states find(~ismember(1:16, [10, 11, 14])); state valid_states(unidrnd(length(valid_states)));这段改进代码的思路是预计算所有合法状态的索引集然后直接从中采样根本不需要循环重试。对一个 16 格的网格原代码的重采样效率尚可接受但如果把状态空间扩大到上千格每次 episode 都做重采样会浪费不少计算时间。若你的环境中障碍物比例较大建议优先采用预计算合法状态集的方案。4.5 epsilon 固定带来的策略抖动问题源码固定 epsilon0.3训练后期最优策略已经出现但仍有 30% 概率随机探索。这种抖动的表现是明明沿着某条路能到终点Agent 却隔三差五跳去陷阱格绕一圈。解决这个问题最常见的做法是线性衰减。epsilon_start 0.9; epsilon_end 0.01; epsilon epsilon_start; for episode 1:900 epsilon epsilon_start - (episode / 900) * (epsilon_start - epsilon_end); % 后续训练逻辑保持不变 end这段代码在每个 episode 开始时更新 epsilon实现了从 0.9 到 0.01 的线性衰减。前期高探索率让 Agent 充分感知环境后期低探索率让策略稳定收敛。实际使用中这份改进可以将最优路径的收敛速度提升一个档位。如果环境变更复杂也可以尝试指数衰减或者基于 Q 值变化量动态调整 epsilon但那属于进阶调参需要更仔细的设计。5. 把这份 MATLAB 代码用到真实任务验证方法与三个进阶改动方向5.1 训练进度可视化画出 Q 值和路径长度随 episode 的收敛曲线原代码每隔 100 个 episode 输出一次文本进度但没有图形化展示。真实任务中我习惯把每次 episode 的步数记录下来训练结束后画一条收敛曲线能直观看到策略是否稳定、有没有发散风险。steps_history zeros(1, 900); for episode 1:900 % 训练逻辑与源码相同但同时记录步数 step_count 0; while state ~ 16 % 省略原动作选择和 Q 值更新逻辑 step_count step_count 1; end steps_history(episode) step_count; end plot(1:900, steps_history); xlabel(Episode); ylabel(Steps to Goal); title(Q-Learning Convergence);这段可视化代码把每一步记录到steps_history里理论上训练早期步数波动大Agent 在随机探索中后期步数应该单调下降并收敛到最优路径长度。如果曲线没有下降趋势说明奖赏设置或 epsilon 调度有问题应该回看第 4 章提到的参数坑。用图形来判断收敛比用文本输出直观得多这是我复现任何强化学习算法的习惯动作。补充一点判断收敛还有个更严格的方式把 Q 矩阵的差值范数norm(Q_new - Q_old, fro)作为监控指标当该值低于某个阈值比如 1e-3时认为训练完成。这个指标能更精确地反映 Q 值是否还在变化优于单纯看路径长度。5.2 从网格到连续状态把状态编号改成二维坐标这份代码最大的简化在于状态是线性编号而非二维坐标。真实世界的状态往往有空间结构比如机器人在 2D 平面上的位置。把这份代码升级成 2D 坐标的常见做法是维护一个状态索引映射表% 建立状态编号到坐标的映射 state_coords zeros(16, 2); idx 1; for row 1:4 for col 1:4 state_coords(idx, :) [row, col]; idx idx 1; end end这段代码将 1 到 16 的编号映射为 4×4 网格上的(row, col)坐标。这样在修改障碍物或奖赏时不必再关心编号而是直接用state_coords(11, :)获取第 11 格的坐标位置。这个映射表同样可以用于可视化比如画网格热力图时通过坐标索引对应位置。5.3 从 Q-Learning 到 SARSA一个 if 的区别Q-Learning 的更新用的是下一状态的最大 Q 值max(Q(action,:))而 SARSA 用的是实际执行动作后的 Q 值。这两种算法的差别是理解 off-policy 和 on-policy 的关键。修改这份源码得到 SARSA 的做法是在更新前先选好下一个动作更新公式里替换掉最大值部分。% SARSA 核心区别更新时使用实际执行的动作对应的 Q 值 next_possible_actions find(T(action, :) 1); next_possible_Q Q(action, next_possible_actions); if rand() epsilon next_choose unidrnd(length(next_possible_actions)); next_action next_possible_actions(next_choose); else [~, next_index] max(next_possible_Q); next_action next_possible_actions(next_index); end Q(state, action) R(state, action) gamma * Q(action, next_action);这段代码把原来max(Q(action,:))替换为Q(action,next_action)其中next_action是基于当前 Q 值选出的动作如果环境里没有明确的下一次决策就用贪心选出的动作代替。这样能保证更新的是实际遵循策略下的回报符合 on-policy 的要求。这类 if 级改动往往是理解 off-policyQ-Learning与 on-policySARSA差异的最佳练习结束后你可以比较两种算法在这个网格任务中的收敛速度和最终路径差异这种对比能让理论概念变得立体。这段代码的改进让我形成了自己的习惯拿到任何一份强化学习源码第一件事是把训练逻辑和测试逻辑分开第二件事是手动添加随机种子和收敛监控第三件事是研究如果终点状态的下一个状态不为空Q 更新会怎么变。这三步做完源代码基本上就能真正做到改得动、调得通、跑得明白。最后说一句当时跑这份代码时我在rng和max这两个点上各栽了一次跟头从那以后我每次复现强化学习代码都强制走一遍检查随机种子、验证终点 Q 更新、预计算合法状态这三步希望帮到你。本文还有配套的精品资源点击获取

相关新闻

人脸表情识别实战:从关键点对齐到轻量CNN部署

人脸表情识别实战:从关键点对齐到轻量CNN部署

简介:这是一套基于Python实现的人脸表情识别的完整项目资源,面向人工智能初学者与进阶学习者,适用于课程设计、毕设开发及工程实训等实践场景。项目采用卷积神经网络为主干模型,在FER2013、JAFFE和CK三大公开数据集上完成训练与评…

2026/10/11 16:33:44 阅读更多 →
三相微电网下垂控制阻感线路波形耦合分析与调试

三相微电网下垂控制阻感线路波形耦合分析与调试

搞微电网三相交流下垂控制的仿真和实验,总绕不开“阻感型线路阻抗”这个前提。传统下垂控制里P-f、Q-V那两套公式,看着简单,可真把线路阻抗设成纯感性去对波形时,问题就来了:负载一投,有功波形和频率倒是按…

2026/10/11 16:33:44 阅读更多 →
Agent 系列01|Agent 到底是什么?何时该用,何时不该用?

Agent 系列01|Agent 到底是什么?何时该用,何时不该用?

01|Agent 到底是什么?何时该用,何时不该用 Agent 工程实战系列 序章 一、问题场景:老板说“给客服做个 AI 助手” 你是 SupportPilot(客服工单助手)项目的开发。一周之内,业务方丢来三个需求&…

2026/10/11 16:33:44 阅读更多 →

最新新闻

YashanDB单机部署实操:从环境准备到实例启动的完整指南

YashanDB单机部署实操:从环境准备到实例启动的完整指南

数据库这玩意儿,平时看着没啥存在感,可真到要部署的时候,环境、依赖、权限、端口、内核参数,哪一个拎出来都能把人折腾得没脾气。最近一段时间,因为项目选型,我在几台机器上反复部署过YashanDB——一款国产…

2026/10/11 20:34:21 阅读更多 →
基于卷积神经网络的农作物病虫害识别系统实战:从数据集到部署

基于卷积神经网络的农作物病虫害识别系统实战:从数据集到部署

简介:这份资源是面向计算机相关专业毕业设计与项目实战学习者的农作物病虫害识别检测系统,基于深度学习卷积神经网络实现,涵盖从模型训练到Web端部署的完整链路。项目经导师指导并通过评审,源码均经本地编译调试可运行&#xff0c…

2026/10/11 20:34:21 阅读更多 →
基于动态分时电价的电动汽车有序充放电实时优化调度系统详解

基于动态分时电价的电动汽车有序充放电实时优化调度系统详解

做电动汽车充放电调度这个方向,算起来也有不短时间了。从最早单纯追求“充得便宜”,到后来加上V2G反向放电,再到把动态分时电价引入优化过程,每一步都踩过不少坑。今天趁项目收尾,把这套基于动态分时电价的电动汽车有序…

2026/10/11 20:34:21 阅读更多 →
从Excel到ERP:小微商家数字化转型的真实痛点与破局路径(附ROI测算)

从Excel到ERP:小微商家数字化转型的真实痛点与破局路径(附ROI测算)

写在前面网上管家婆成立于1993年,30余年服务超过80万中小客户。在对373家电商客户的调研中,52%的客户属于"初创型"——在引入系统之前只用过打单软件甚至纯靠Excel管理。以下内容从这些客户的真实痛点出发,分析从表格到ERP的转型难…

2026/10/11 20:34:21 阅读更多 →
MySQL中trx_mysql_thread_id为0的真相:XA事务与锁等待排查指南

MySQL中trx_mysql_thread_id为0的真相:XA事务与锁等待排查指南

1. 从一次诡异的锁等待说起 先讲个真实场景。某天中午,线上业务突然出现大量锁等待超时,监控面板上一片红色。当时我第一时间看了 information_schema.innodb_trx ,发现有一条事务状态为 RUNNING ,已经跑了快二十分钟&#xf…

2026/10/11 20:34:21 阅读更多 →
医院六大医疗信息系统集成实战:HIS、LIS、PACS、EMR、RIS、CDR数据流与接口详解

医院六大医疗信息系统集成实战:HIS、LIS、PACS、EMR、RIS、CDR数据流与接口详解

简介:本资源是一份面向医院信息科人员、医疗IT从业者及卫生信息管理专业学习者的系统性入门资料,全面梳理当前主流医疗信息化系统的核心定位、功能模块与协同关系,助力快速建立行业知识框架并支撑系统选型、实施或运维工作。文档为单文件Word…

2026/10/11 20:33:20 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →