EP进化规划Python实现:从原理到黑盒优化实战
EP进化规划的Python实现听起来像是一篇课程作业的标题但真正上手之后你会发现这套算法在工程优化里意外地好用。进化规划Evolutionary Programming算得上进化计算里最朴素的一支它不搞遗传算法那套“选择、交叉、变异”三步走而是只靠两板斧高斯变异生成候选解锦标赛选择保留优良个体。我第一次写EP是为了在一个不可导的仿真模型里找参数目标函数有噪声、有平台梯度类方法直接失效当时试了几种启发式算法都差点意思最后把EP落地跑通了。这篇就把实现过程、Python代码、调参经验都留着想学进化算法或者准备用EP做黑盒优化的人可以直接抄作业。1. EP进化规划到底是什么1.1 进化计算里的“极简派”进化计算家族里有很多分支遗传算法最出名进化策略在连续优化上很强但进化规划往往被一笔带过。实际上EP是最早被提出的进化算法之一核心思路非常简单种群里的每个个体表示一个候选解通过随机变异产生后代再通过竞争机制决定谁留下来。EP跟遗传算法的区别最关键的一点是EP不用交叉算子。很多人第一次听会觉得别扭觉得“没交叉还算进化吗”但EP的设计哲学恰恰在这里。它强调个体行为的进化而不是基因结构的重组。在连续参数优化里两个实数解的线性组合未必能产生更好的解甚至很容易破坏已经找到的下降方向。EP选择用高斯噪声在个体附近游走每次只做小幅扰动靠多次迭代积累优势这种策略在实值优化里往往比交叉更稳定。我见过不少初学者把EP当成遗传算法的简化版用遗传算法的思路去调EP的参数最后效果不好就怪算法不行。其实它们各自适合的问题类型并不一样。EP最适合的是那种“没有梯度信息、甚至目标函数都带噪声”的连续优化问题你只需要能算出每个解的适应度剩下的交给变异和选择。1.2 为什么EP不强调交叉既然都叫进化为什么EP不用交叉算子要回答这个问题得回到“什么时候交叉有用”。遗传算法处理离散编码时交叉可以把两个父代中表现好的基因块拼接起来这在很多组合优化问题里是有效的。但EP最初面向的是连续行为空间个体就是一个实数向量。举个例子两个父解都接近某个局部最优如果对它们做算术交叉子代大概率落在两个父解的中间但如果适应度函数在中间是隆起的子代反而不如父代。更麻烦的是连续空间中的“基因块”概念很模糊你很难判断解的哪几个维度是“优质模块”。强行交叉等于在未知地形上随机跳变还不如老老实实做邻域搜索。EP把交叉去掉之后整个算法只剩两个操作变异产生新解选择淘汰差解逻辑一下子干净很多。这并不意味着EP永远不用交叉后来也有人做过带交叉的EP变体但经典EP不包含交叉。你在实现时没必要硬加加了反而让算法失去原本的简洁特性。1.3 用一句话概括EP的搜索模型EP的搜索过程可以用一个非常紧凑的形式表达每个个体携带参数向量和变异步长下一代从父代加噪声产生然后在父代与子代的混合池里进行锦标赛选择。这里有个细节容易被忽略变异步长并不是手工设定的常数它可以作为个体的一部分共同进化。个体 (x, sigma) x_new x sigma * N(0, 1) sigma_new sigma * exp(tau * N(0,1) tau * N(0,1))x是要优化的变量sigma控制变异幅度。sigma跟着x一起进化好的sigma会让个体更容易产生优质后代于是自然被选择保留下来。这种“参数自适应”是EP的一大亮点也是它比固定变异步长的方法稳得多的原因。2. 算法流程与每个环节的设计理由2.1 初始化与适应度评估EP的初始化没什么花哨的在搜索范围内均匀随机采样N个个体每个个体附带一个sigma然后计算每个个体的适应度。这里最值得注意的就是“边界范围要真实反映问题的可行域”。我第一次实现时偷懒把边界设得特别宽想着算法自己能搜到好区域。结果种群发散得厉害前期全在无意义的区域里浪费评估次数。后来我学乖了先把工程约束捋清楚能缩小边界就缩小边界。对于有不等式约束的问题还可以在适应度里加罚函数把不可行解的适应度压得很差让选择过程自然淘汰它们。初始化时还有一个容易被忽略的点sigma的初始值。很多人只设x不设sigma直接默认用固定步长结果有的维度震荡、有的维度挪不动。EP的sigma初始值应该根据搜索范围来确定一般是搜索范围宽度的10%左右。比如某个变量的取值范围是[-10, 10]那初始sigma可以取2左右。这样前期探索步长不会太大也不会太小。2.2 变异算子的门道EP真正的主角是变异算子。标准EP使用高斯变异也就是在父代基础上加一个均值为0、标准差为sigma的高斯噪声。为什么选高斯噪声因为连续优化问题中搜索步长服从正态分布在理论上能保证算法的遍历性和收敛性而且实现简单只需要调用随机数生成器。但固定sigma有个致命缺陷如果sigma太大个体即使已经接近最优解下一步扰动也会把它弹开如果sigma太小又很难跳出局部最优。自适应的思路是把sigma也做成可进化的“策略参数”让每个个体自己带上步长信息。这里有两个tau参数通常按维度设置tau 1 / sqrt(2 * sqrt(dim)) tau_prime 1 / sqrt(2 * dim)tau_prime控制全局步长变化tau控制每个维度的独立步长变化。这个公式不是我拍脑袋编的它来自经典进化策略的参数推导目的是让sigma在进化过程中既能整体调整又能按维度松紧不同。实际调试时维度变化后需要按公式重新算tau如果沿用固定tau高维条件下sigma更新会变得过于激进或者过于迟钝。2.3 锦标赛选择的“胜负手”选择机制直接决定搜索方向。EP最常用的选择是锦标赛选择把父代和子代放在一起总共2N个个体对每个个体从2N中随机挑q个对手比较适应度计算赢了多少场然后按胜利场次排序取前N个。为什么用锦标赛而不是直接取适应度最小的N个因为EP场景里适应度往往有噪声、有量纲差异直接排序容易被极端值带偏。锦标赛只依赖两两比较的胜负关系就算适应度整体乘以一个正数或者加上一个常数排名基本不变抗干扰能力更强。q的选择很有讲究。q越大每个个体需要打败的对手越多选择压力越强收敛越快但也越容易早熟。q越小选择压力越弱群体会保留更多多样性但搜索效率会下降。我常用的经验值是q取总个体数的一半也就是让每个个体和一半的池子成员比过再决定去留。对大多数连续优化问题这个设置已经够用。2.4 精英保留和边界处理没有精英保留的EP理论上可能丢掉当前找到的最优解。虽然最终通过随机变异有机会再找回来但会浪费大量评估次数。所以我几乎总是会把历史最优个体单独留一份在新一代产生后检查它是否存在于种群中如果不存在就把新一代里最差的个体替换掉。边界处理也要小心。最简单的做法是np.clip把子代限制在上下界内但代价是会让很多个体贴在边界上劣化搜索多样性。另一种做法是反射越界的变量按边界对称弹回相当于“撞墙反弹”能保留更多变异信息。如果你只是想快速跑通流程clip完全够用如果问题边界对解的影响很大建议改成反射边界。2.5 完整流程梳理把上面的环节串起来EP的一次迭代就是五步随机初始化N个个体每个个体包含变量x和步长sigma。计算所有个体的适应度。对每个父代用当前sigma生成一个子代并计算子代的适应度。把父代和子代合成一个大池子做锦标赛选择挑出N个胜者作为下一代。检查并保留历史最优个体重复迭代直到满足终止条件。这个流程没有交叉没有复杂的编码解码核心代码量可以控制在很短的时间内。就算你从零写半小时也能跑起来一个可用版本。3. Python实现从零写一个EP优化器3.1 环境准备实现EP只需要numpyPython版本在3.8以上就行。如果想画收敛曲线可以安装matplotlib。我不建议一开始就引入一堆第三方优化库自己从零写一遍能把算法的每个环节都看透后面再换库也知道它在做什么。我习惯把EP封装成一个类方便复用到不同问题。类的输入是目标函数、维度、边界和参数配置输出是历史最优值和最优解。这样切换测试函数时只需要改一行不用改算法逻辑。3.2 完整代码下面是我常用的一个模板包含了自适应变异、锦标赛选择、精英保留和边界裁剪。这个版本没有过度优化目的是把逻辑讲清楚。import numpy as np class EvolutionaryProgramming: def __init__(self, fitness_func, dim, bounds(-10., 10.), pop_size50, max_iter200, sigma_initNone, q_rate0.5, keep_eliteTrue, adaptiveTrue): self.fitness_func fitness_func self.dim dim self.bounds np.array(bounds, dtypefloat) if self.bounds.ndim 1: self.bounds np.tile(self.bounds, (dim, 1)) self.lb self.bounds[:, 0] self.ub self.bounds[:, 1] self.range_len self.ub - self.lb self.pop_size pop_size self.max_iter max_iter self.sigma_init sigma_init if sigma_init is not None \ else 0.1 * self.range_len self.q_rate q_rate self.keep_elite keep_elite self.adaptive adaptive self.tau 1.0 / np.sqrt(2.0 * np.sqrt(self.dim)) self.tau_prime 1.0 / np.sqrt(2.0 * self.dim) self.pop None self.sigma None self.fitness None self.best_x None self.best_fitness np.inf self.history [] def evaluate(self, x): return float(self.fitness_func(x)) def initialize(self): self.pop np.random.uniform(self.lb, self.ub, size(self.pop_size, self.dim)) self.sigma np.tile(self.sigma_init, (self.pop_size, 1)) self.fitness np.array([self.evaluate(ind) for ind in self.pop]) order np.argsort(self.fitness) self.pop self.pop[order] self.sigma self.sigma[order] self.fitness self.fitness[order] self.best_x self.pop[0].copy() self.best_fitness self.fitness[0] def mutate(self): n self.pop_size if self.adaptive: global_noise np.random.normal(0, 1, size(n, 1)) local_noise np.random.normal(0, 1, size(n, self.dim)) sigma_child self.sigma * np.exp( self.tau_prime * global_noise self.tau * local_noise ) else: sigma_child self.sigma.copy() noise np.random.normal(0, 1, size(n, self.dim)) x_child self.pop sigma_child * noise x_child self.clip_bound(x_child) sigma_child np.clip(sigma_child, 1e-12, 10.0 * self.range_len) return x_child, sigma_child def clip_bound(self, x): return np.clip(x, self.lb, self.ub) def tournament_select(self, all_pop, all_sigma, all_fitness): total len(all_fitness) q max(1, int(self.q_rate * total)) records [] for i in range(total): opponents np.random.choice(total, q, replaceFalse) win_count 0 for j in opponents: if all_fitness[i] all_fitness[j]: win_count 1 records.append((win_count, i)) records.sort(keylambda r: (-r[0], r[1])) selected_idx [idx for _, idx in records[:self.pop_size]] return (all_pop[selected_idx], all_sigma[selected_idx], all_fitness[selected_idx]) def run(self, verboseFalse): self.initialize() for it in range(self.max_iter): x_child, sigma_child self.mutate() fitness_child np.array([self.evaluate(ind) for ind in x_child]) all_pop np.vstack([self.pop, x_child]) all_sigma np.vstack([self.sigma, sigma_child]) all_fitness np.concatenate([self.fitness, fitness_child]) new_pop, new_sigma, new_fitness self.tournament_select( all_pop, all_sigma, all_fitness ) if self.keep_elite and self.best_fitness new_fitness.min(): worst_idx np.argmax(new_fitness) new_pop[worst_idx] self.best_x new_sigma[worst_idx] self.sigma[0] new_fitness[worst_idx] self.best_fitness self.pop new_pop self.sigma new_sigma self.fitness new_fitness best_idx np.argmin(self.fitness) if self.fitness[best_idx] self.best_fitness: self.best_fitness self.fitness[best_idx] self.best_x self.pop[best_idx].copy() self.history.append(self.best_fitness) if verbose and (it 1) % 20 0: print(fIter {it 1}: best {self.best_fitness:.6e}) return self.history, self.best_x, self.best_fitness代码里有两个我觉得很关键的细节。一是sigma_child做了下限截断到1e-12防止自适应过程中某些维度sigma退化到零导致那些维度永远不再变化。二是锦标赛选择时用了而不是这样适应度相同的情况下个体也能算一场胜利避免平局时胜场过少。如果你要复现实验可以把随机种子固定住比如np.random.seed(42)。3.3 代码拆解初始化、变异、选择initialize方法里做了一件事容易被漏掉初始化后按照适应度升序排序。为什么要排序因为后面跑迭代时我们希望第一个个体就是当前代最优个体方便记录best_x也方便精英保留时取self.sigma[0]作为最优个体的步长。虽然不排序也能通过argmin找到最优但排序之后整个种群看起来更有序调试时打印前几个个体就能知道当前状态。mutate方法把自适应变异拆成了全局噪声和局部噪声。全局噪声是对整个向量所有维度施加同一个随机数用来调整整体搜索步长局部噪声则是每个维度独立的随机数让不同维度可以有不同幅度的扰动。这个设计对应的就是前面提到的tau和tau_prime两个参数。如果不想要自适应直接把adaptive设为False变异就退化成固定sigma适合用来验证“自适应到底有没有用”。tournament_select里q的值由q_rate乘上总个体数得到。比如q_rate0.5池子里有100个个体那每个个体要随机抓50个对手比一比。q_rate越大选择越残酷基本只有适应度特别好的一小撮人能留下。我在代码里用了最直观的两两比较循环没有做向量化加速。当种群规模在几百以下时这点循环时间可以忽略如果你要跑上千个体建议用numpy批量计算胜场减少Python循环开销。3.4 在测试函数上跑一把写完类我们来实测。用两个经典测试函数一个是单峰的Sphere函数一个是多峰的Rastrigin函数。Sphere的目的是验证EP能不能收敛到全局最优Rastrigin的目的是看EP在布满局部最优的地形里会不会卡住。def sphere(x): return np.sum(x ** 2) def rastrigin(x): x np.asarray(x) return 10 * len(x) np.sum(x ** 2 - 10 * np.cos(2 * np.pi * x))Sphere 20维边界[-5.12, 5.12]种群60迭代300代。一次典型运行的输出大概是Iter 20: best 6.231e-01 Iter 40: best 7.504e-02 Iter 60: best 2.218e-02 Iter 80: best 5.362e-03 Iter 100: best 1.109e-03 ... Iter 300: best 1.082e-09Rastrigin 10维同样参数下一次典型运行的输出可能到1e-3量级附近而且不同随机种子之间的波动会更明显。因为Rastrigin在原点之外还有很多局部最优点EP如果没有足够的种群多样性很容易停在一个非零的局部坑里。这两种结果恰好能反映EP的特点对平滑单峰问题收敛非常干净对崎岖多峰问题能不能找到全局最优很大程度上取决于初始sigma和种群规模。下面这组是我的经验值测试函数维度种群规模初始sigma迭代次数典型最优值Sphere2060搜索范围10%300 1e-8Rastrigin1080搜索范围15%5001e-3 ~ 1e-14. 参数调优与经验值4.1 种群规模N、sigma、q会怎么影响搜索EP最核心的三个参数是种群规模N、初始sigma和锦标赛对手比例q_rate。它们不是独立的我会把它们放到一起调。种群规模N决定了一次迭代里能探索多少区域。N太小比如10变异出来的后代很快就挤到同一个小区域搜索很难展开。N太大比如500每一代都要算几百次目标函数如果目标函数本身很贵性能就撑不住。连续优化问题里我一般从50开始调高维或崎岖地形加到100以上。初始sigma决定了第一代变异步长。如果sigma太小种群只能在很小的邻域里爬容易漏掉远处的全局最优如果sigma太大前几十代到处乱跳最优值下降很慢等于白烧预算。我的经验是先把每个变量按实际工程意义缩放到一个大致范围sigma从范围宽度的10%起步观察收敛曲线再微调。q_rate是选择压力的旋钮。q_rate1时每个个体要跟所有个体比较选择压力最强收敛快但多样性差q_rate0.2时选择压力弱种群保持得比较多样化但收敛可能拖沓。我习惯在0.3到0.6之间试没有一个通吃值。4.2 不同场景下的参数配置参考下面这张表是我在不同类型问题上调出来的比较稳的参数组合你可以拿来当起点不一定最优但至少能跑得动。场景Nsigma_initq_ratemax_iter低维平滑函数优化dim1030范围10%0.5200高维函数优化dim20~5060~100范围10%0.4300~500多峰强非凸问题100范围20%0.3500神经网络权重进化200范围5%0.5视数据量而定神经网络权重进化的sigma为什么只取5%因为网络权重的有效范围通常比较小过大的sigma会把前几代权重打得稀烂模型直接退化到随机状态。4.3 自适应变异参数tau怎么设tau和tau_prime的公式我在代码里直接算了但很多人会问能不能手动调理论上当然能但我不建议随便改。这个公式有名堂它按照维度做了归一化保证sigma在对数尺度上随机游走的步长与维度无关。如果你非要改记住一个原则tau太大sigma波动剧烈搜索步长忽大忽小tau太小sigma几乎不变自适应就名存实亡。如果要追求更稳的收敛还可以给sigma加一个上限。我在前面的代码里就用了np.clip(sigma_child, 1e-12, 10.0 * self.range_len)一防sigma缩到零二防sigma涨到超过搜索范围。这个上限看起来有点宽但实际运行中很少顶到。5. 常见问题与排查技巧5.1 收敛太慢怎么加速收敛慢最常见的三个原因初始sigma太小、选择压力太弱、最大迭代次数不够。初始sigma太小种群一直在局部区域磨蹭最优值下降很慢。你可以把history画出来看曲线斜率如果是一条很缓的下降线大概率是sigma问题。选择压力太弱可以通过调大q_rate解决但同时要小心早熟。还有一个非常容易忽略的工程问题目标函数量级没归一化。如果适应度本身是几万量级EP的优选过程对微小改进不敏感收敛看起来就很慢。我建议把目标函数做归一化或者在选择时比较排序值而不是原始适应度。5.2 早熟卡在局部最优怎么办早熟在Rastrigin这类多峰函数上特别常见。现象是迭代前几十代快速下降然后就一动不动最优值停在某个非零水平。这时候先别急着加迭代次数加再多也是在同一个坑里打转。我一般按这个顺序排查先加大种群规模到100以上再调低q_rate到0.3再适当增大初始sigma到范围20%左右。三步都做完还卡着就考虑“重启策略”每跑一定代数如果最优值连续停滞就把种群重新撒开只保留最优个体其他个体重新随机初始化。这个技巧简单粗暴但非常有效。5.3 结果不稳定怎么办EP本身是随机算法每次运行结果不一样是正常的。但如果同一个问题连续跑十次最优值有时候1e-8有时候1e-1那就要小心参数处于临界状态和问题地形不匹配。我的建议是不要只跑一次就下结论。同一组参数跑5到10个随机种子记录最优值的中位数和最小方差。中位数代表算法的典型表现最小值代表上限。如果中位数很稳定说明参数没大问题如果中位数波动大继续调参数。真实项目里最后真正上线用的应该是多次运行里表现最好的那组个体而不是单次随机结果。5.4 快速判断EP实现是否正常如果你是自己从零实现的EP建议先跑一个最简单的问题Sphere函数。因为Sphere是单峰、光滑、凸问题任何正常工作的EP都应该在几十代内显著下降。如果Sphere都收敛不好问题多半出在变异或选择上先检查sigma是否更新、是否把父代和子代正确拼接、是否只按适应度排序而没有做锦标赛。如果Sphere正常但Rastrigin很差基本可以确定是探索与利用的平衡没调好按5.2的方法调参数即可。把这两个问题当成“体检项”每次改完代码先跑一遍能省很多排查时间。6. 扩展案例用EP进化神经网络权重6.1 把神经网络训练转成优化问题很多项目里会遇到“不能梯度反传”的尴尬。比如自定义算子不可导、仿真器黑盒、或者目标函数本身就是一段外部程序这时候反向传播根本走不了。EP的优势就体现出来了把神经网络的全部权重摊平成一个向量作为EP的个体。假设一个只有几百个权重的小网络每个权重对应EP变量向量的一维。适应度函数可以设计成在验证集或小批量数据上的损失。EP不管网络内部结构只把“权重”当普通连续变量来优化天然绕开了梯度问题。6.2 实现要点这里有几个要点和普通函数优化不一样。第一权重维度往往比普通优化问题高动辄几百上千种群规模要相应加大。否则每个个体在高维空间里彼此离得很远变异很难产生有效后代。我建议从200开始权重大于一千时考虑分阶段优化。第二网络权重尺度差异很大。偏置项、卷积核、全连接层权重的最佳范围不一样同一个sigma去管所有维度不合理。我给每个维度设置独立sigma初始值按该层权重的标准差估计而不是全局统一。第三评估成本高。每算一次适应度就要前向跑一遍网络如果数据集很大单次评估很慢。于是我把评估改成小批量每个个体随机抽一小批样本算损失个体之间还可以并行评估。这样虽然损失有噪声但EP的锦标赛选择天然不害怕噪声反而更稳。6.3 我的建议如果你打算用EP做神经进化先从很小的网络开始。我见过有人一上来就想进化一个深度网络参数十几万结果跑了一天也没收敛。先拿几百个权重的模型验证EP实现的正确性等调参手感找到了再逐步放大。对少于几千参数的轻量模型EP完全能作为反向传播之外的备选方案尤其在评估函数不可导或带随机性的场景里EP往往比强行用一个替代梯度更靠谱。我自己实际用下来的体验是EP这种“少就是多”的算法特别适合黑盒优化。它没有交叉算子带来的重组假设也没有复杂的编码方案唯一需要你花心思去理解的就是sigma和选择压力的配合。只要把这两个点拿捏住了后面移植到任何问题都只是换适应度函数的事。写到最后还想分享一个小技巧在跑EP之前最好花十分钟把搜索边界和初始sigma范围可视化地画出来。哪怕是二维问题画个等高线图你也能直观看到种群散落在哪些区域迭代后往哪里聚拢。这种“眼见为实”的调试方式比单纯盯着一堆print输出高效得多。EP的实现本身不复杂复杂的是对问题地形的理解而这一步恰恰是任何算法调参都无法替你完成的。

相关新闻

自主机器人开发的四层物理现实约束

自主机器人开发的四层物理现实约束

1. 为什么“自主机器人基础”不是入门课,而是分水岭“自主机器人基础”这六个字,乍看像大学选修课的名称,或者某本教材的副标题。但在我带过三十多个机器人项目、从学生团队到工业落地一线摸爬滚打的十年里,它从来不是起点——而是…

2026/10/14 14:08:20 阅读更多 →
Vue+Java篮球馆场地预约系统实战:从表设计到并发控制

Vue+Java篮球馆场地预约系统实战:从表设计到并发控制

篮球馆场地预约这事儿,只要在校园或商业球馆跑过一阵子,都能切身体会到痛点有多具体:场地就那么几块,要打的时段全都挤在一起,以前靠微信群报名接龙、前台手写登记,一到周末高峰期,不是时间撞车…

2026/10/14 14:07:20 阅读更多 →
深度学习实战:工业级神经网络预处理、正则化与部署优化指南

深度学习实战:工业级神经网络预处理、正则化与部署优化指南

1. 这不是又一本“从零开始”的书——为什么第八篇才真正进入实战深水区很多人看到《Python 神经网络与深度学习 实用指南(八)》这个标题,第一反应是:“哦,又是系列教程的续篇,估计还在讲sigmoid函数求导或…

2026/10/14 14:07:20 阅读更多 →

最新新闻

Codex 部署踩坑终结,一键安装包简化整套搭建流程

Codex 部署踩坑终结,一键安装包简化整套搭建流程

前言 很多想体验 Codex 的开发者,卡在前期环境部署环节。手动安装 Node.js、配置依赖,还要敲大量命令行,对于新手十分不友好,很容易出现各种报错。 Codex 一键安装包把环境配置、依赖安装、客户端部署全部打包封装。不需要手动配…

2026/10/14 14:53:19 阅读更多 →
大模型应用写不出单测?用 Mock 把 LLM 调用做成可回归的工程

大模型应用写不出单测?用 Mock 把 LLM 调用做成可回归的工程

授权与合规声明 本文为原创技术分享,所有示例代码均运行于作者自建的隔离环境,仅供学习交流。文中涉及的第三方模型与服务以各自官方文档为准,请在服务条款范围内使用。转载请保留出处。一、为什么 LLM 应用难测 1.1 依赖不可控:模…

2026/10/14 14:53:19 阅读更多 →
VLAct:基于Qwen3-VL的可迁移视觉语言动作基座

VLAct:基于Qwen3-VL的可迁移视觉语言动作基座

1. 项目概述:当机器人开始“理解”动作,而不是“执行”指令具身智能这个词最近在技术圈里火得有点烫手,但很多人聊了半天,还是分不清它和传统机器人控制、甚至大模型多模态能力的根本区别。我干这行十多年,从工业机械臂…

2026/10/14 14:53:19 阅读更多 →
VLAct:解耦视觉语言动作的可迁移VLA主干模型

VLAct:解耦视觉语言动作的可迁移VLA主干模型

1. 这不是又一个“视觉语言”模型,而是让机器人真正学会“看懂世界、想清楚、再动手”的新范式最近在具身智能开源社区 xbotics 的技术讨论区里,我看到不少朋友反复问一个问题:“为什么训练一个能开门的机器人,换到抽屉场景就完全…

2026/10/14 14:53:19 阅读更多 →
PDF 水印去除的代码实现:检测、指令级删除与保存净化全流程

PDF 水印去除的代码实现:检测、指令级删除与保存净化全流程

上一篇《PDF 水印去除的技术迷宫:为什么 90% 的工具都会失败》讲了原理层:水印在技术上分六层,主流方法各有射程边界。这篇讲工程层——用代码把"检测 → 定位 → 分类 → 处理 → 验证"这条管线完整实现出来。 先说背景&#xff…

2026/10/14 14:53:19 阅读更多 →
VOC格式吸烟检测数据集解析:从标注规范到YOLO转换避坑指南

VOC格式吸烟检测数据集解析:从标注规范到YOLO转换避坑指南

简介:本资源是一套面向计算机视觉初学者与算法工程师的吸烟行为检测专用数据集,聚焦室内与室外多场景下人员吸烟动作识别任务,可直接用于YOLO、Faster R-CNN等目标检测模型的训练与验证。数据集共2000个文件,包含1507个VOC格式XML…

2026/10/14 14:52:19 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →