多模型检测结果融合:WBF原理、实现与调参实战
做目标检测的同行应该都被 NMS 教育过。模型输出一大堆边界框每个框带一个置信度和类别标签怎么把它们整理成最终结果NMS 是最常见的选择。但如果你做过多个模型的集成或者搞过多尺度测试时增强TTA就会撞到一个 NMS 解决不好的问题多个模型各自预测出的同一个目标位置和分数都不一样NMS 只能保留一个框剩下那些框里携带的位置信息全被浪费掉了。Weighted Boxes FusionWBF就是专门解决这个问题的它不把框粗暴地删掉而是把多个模型对同一个目标的预测框聚成一簇再用置信度做加权平均合成一个更稳、更准的框。这篇文章我从头讲清楚 WBF 的原理、实现、调参和实战中的坑尽量让看完的人能直接在自己的检测流程里用起来。1. 从 NMS 到 Weighted Boxes Fusion为什么多模型结果不能简单“挑一个”1.1 NMS 擅长的事和不擅长的事先回顾一下 NMS 的逻辑。假设一个模型输出了一组框NMS 会先把它们按置信度从高到低排序然后从最高分的框开始把和它 IoU 超过阈值的其他框全部压掉逐个处理完剩下的框。这个策略对单个模型是非常有效的因为单个模型在同一个目标周围往往会产出很多高度重叠的候选框其中大部分都是冗余的留下最自信的那个就够了。但 NMS 的“留下一个”在集成场景里就很浪费。我举一个很常见的例子两个模型看同一个目标模型 A 觉得边框左边在 x10置信度 0.9模型 B 觉得左边在 x14置信度 0.8。真实位置可能接近 x12。如果直接用 NMS它大概率只看置信度更高的那个框把 0.8 的框全部删除结果是 x10 或 x14而不是两个模型综合出来的 x12。如果这两个模型的误差方向是互补的那丢掉任何一个框就意味着丢掉一部分信息。有人会说先用 NMS 挑出每个模型的框再对两个框的坐标求平均不就行了听起来合理但实现起来没那么简单。求平均之前你得先知道哪两个框对应同一个目标这不是一个“按 label 相同就合并”的简单问题因为两个模型框的位置有偏差IoU 可能只有 0.6 或 0.7阈值怎么定、权重怎么给都需要一个统一框架。WBF 做的事情就是把你本来要手写的“匹配、聚类、加权、融合”变成一个明确流程。1.2 WBF 的思路先聚类再加权平均WBF 的核心思路可以概括成一句话不把框“删掉”而是把框“融合”。它先维护一组簇cluster每个簇代表一个疑似目标。处理每个候选框时如果这个框和某个簇里已经融合出的代表框 IoU 足够高并且类别一致就把它加入这个簇否则就新建一个簇。所有框都归好簇之后每个簇内部用置信度做权重把坐标加权平均成一个新框。这个思路很像多个专家给同一个目标画框最后不是听最响的那个专家而是把所有专家的意见按可信度加权汇总。单个专家的随机误差会被平均掉系统性的偏差虽然还在但多个模型如果结构差异大系统性偏差往往不会同时出现在同一个方向上。我特别想强调一点WBF 并不是 NMS 的替代品它是一种更上层的融合策略。单模型内部如果已经产生了大量重复框还是要先用 NMS 或置信度阈值把这些明显冗余的框清掉WBF 更适合做“多模型之间”或“多种增强方式之间”的融合。这一点在后面实战部分还会展开说。2. WBF 算法拆解聚类、加权平均与置信度归一化2.1 输入到底长什么样WBF 的输入不是一张图而是多个模型对同一张图的输出结果。具体说需要三样东西boxes_list、scores_list、labels_list。它们都是列表列表长度等于参与融合的模型数量 M。每个元素分别是某个模型输出的所有框坐标、所有置信度、所有类别标签。用代码来看更直观boxes_list [model_1_boxes, model_2_boxes, ..., model_M_boxes] scores_list [model_1_scores, model_2_scores, ..., model_M_scores] labels_list [model_1_labels, model_2_labels, ..., model_M_labels]每个模型输出多少框都可以不一样不用对齐。比如模型 A 检出 10 个框模型 B 检出 8 个框这不影响 WBF 工作因为它本身就是一对多匹配聚类。这地方有个隐藏前提所有框必须使用同一套坐标系。要么都是像素坐标x1,y1,x2,y2要么都是归一化坐标绝不允许一个模型给像素坐标、另一个模型给 0 到 1 的归一化坐标。第 4 部分我会专门讲这个坑但先在这里打个预防针。2.2 聚类阶段怎么匹配聚类阶段的处理顺序建议按置信度从高到低排列。高分框先出现先建立簇的“中心”后面的低分框只能去匹配已有簇这样就避免了一个低分框先占住位置、高分框后来匹配它的尴尬局面。匹配规则有两条候选框的类别必须和簇的类别一致不一致直接跳过候选框和簇当前融合框的 IoU 必须大于阈值iou_thr并且取 IoU 最大的那个簇。如果候选框同时和两个簇的 IoU 都高于阈值那就选 IoU 最大的那个而不是就近乱进。这个策略保证了每个框只归到一个簇里。这里有个细节值得注意匹配是用“簇当前的加权平均框”去算 IoU不是用簇里任意一个原始框去算。这样做的好处是随着簇内元素不断加入代表框会越来越接近真实位置后面来的框匹配会更稳定。我最初自己写实现时用的是“和簇内第一个框比较”结果在高 IoU 阈值下经常出现本该合并的框被拆成两个簇改成和融合框比较之后问题立刻缓解。2.3 融合框与融合分数的计算当所有候选框都归好簇之后对每个簇计算最终结果。假如一个簇里有 n 个框第 i 个框的坐标是 (box_i)它对应的置信度贡献值是 (w_i)那么融合后的框坐标是[ box_{fused} \frac{\sum_i w_i \cdot box_i}{\sum_i w_i} ]这里的 (w_i) 不是模型输出的原始置信度而是“原始置信度乘以该模型权重”。默认情况下每个模型权重都是 1所以 (w_i) 就等于原始置信度。你可以把模型权重理解成给不同模型“投票权”更可靠的模型投出的票更值钱。融合分数则是另一套计算逻辑。常用的一种做法是[ score_{fused} \frac{\sum_i w_i}{M} ]M 是参与融合的模型总个数。这个公式看起来像是求平均实际上是在表达“多个模型对同一个目标达成共识的程度”。两个模型都给出 0.8 的置信度融合分还是 0.8但如果只有一个模型给了 0.8另一个模型根本没检出这个目标融合分就会变成 0.4相当于因为缺少共识而打折。我在实际使用中会把算出来的融合分再做一次min(1.0, ...)裁剪因为当某个模型权重设得比较大或者三个模型同时给出接近 1.0 的分数时原始公式可能算出大于 1 的数。虽然排序不受影响但如果你后续要拿它当概率去算损失或者做可视化大于 1 的“置信度”会带来很多麻烦。2.4 三个关键参数分别管什么WBF 最核心的参数是iou_thr、skip_box_thr和模型权重weights。iou_thr控制什么才算“同一个目标”。默认值是 0.55 左右。这个参数调大匹配更严格一个簇只吸收 IoU 很高的框最终输出的框数量会变多适合目标本身比较密集、稍微偏一点就是另一个目标的场景。调小匹配更宽松更多框会被吸进同一个簇最终框数量变少适合模型之间框位置差异较大的情况。skip_box_thr是预过滤阈值。在 WBF 开始聚类之前低于这个置信度的框直接丢掉。默认可以设 0.0即完全不丢但在工程落地时我会设一个很小的值比如 0.01把明显是噪声的低分框先清掉避免它们污染簇的加权平均位置。weights是每个模型的权重。注意权重一般会做一次归一化让权重平均值等于 1这样融合分数不会因为权重整体放大而虚高。你不需要单独去“补”高模型的权重真正管用的是不同模型之间的相对比例。3. 自己实现一个最小可用的 WBF3.1 先写一个干净的 IoU 函数WBF 依赖的底层操作就是 IoU 计算。这里我用x1,y1,x2,y2格式也就是左上角和右下角坐标。IoU 的实现有很多版本但核心都差不多算交集面积除以并集面积。import numpy as np def compute_iou(a, b): a np.asarray(a, dtypefloat) b np.asarray(b, dtypefloat) ix1 max(a[0], b[0]) iy1 max(a[1], b[1]) ix2 min(a[2], b[2]) iy2 min(a[3], b[3]) iw max(0.0, ix2 - ix1) ih max(0.0, iy2 - iy1) inter iw * ih area_a (a[2] - a[0]) * (a[3] - a[1]) area_b (b[2] - b[0]) * (b[3] - b[1]) union area_a area_b - inter return inter / union if union 0 else 0.0注意这里的坐标必须是浮点数并且保证x2 x1、y2 y1。如果你的模型输出的是xywh格式需要先转成x1y1x2y2再送入 WBF。3.2 聚类与融合的完整实现有了 IoU 函数就可以写出 WBF 主逻辑了。我写一个偏教学风格的完整版本用 dict 而不是类方便你把每一步拆开看。def _update_cluster(cluster): 用簇内所有框的加权平均更新代表框 arr np.asarray(cluster[boxes], dtypefloat) w np.asarray(cluster[scores], dtypefloat) if w.sum() 0: return cluster[fused_box] (arr * w[:, None]).sum(axis0) / w.sum() def wbf(boxes_list, scores_list, labels_list, weightsNone, iou_thr0.55, skip_box_thr0.0): M len(boxes_list) if weights is None: weights np.ones(M) else: weights np.asarray(weights, dtypefloat) weights weights / weights.mean() # 让权重均值保持为 1 # 收集所有候选框记为 (排序分数, 模型编号, 框, 标签) records [] for m in range(M): for box, score, label in zip(boxes_list[m], scores_list[m], labels_list[m]): if score skip_box_thr: continue records.append({ sort_key: score * weights[m], m: m, box: np.asarray(box, dtypefloat), label: int(label) }) # 按加权置信度从高到低处理高分框先建立簇 records.sort(keylambda x: x[sort_key], reverseTrue) clusters [] for rec in records: score rec[score] if score in rec else rec[sort_key] / weights[rec[m]] m rec[m] box rec[box] label rec[label] # 计算这个框对簇的贡献权重 w_score (score if score in rec else rec[sort_key]) * weights[m] # 为了代码简洁这里直接从 sort_key 反推原始分会有数值误差 # 更稳妥的做法是在 records 里同时保存原始 score 和 w_score。 best_idx -1 best_iou iou_thr for i, cluster in enumerate(clusters): if cluster[label] ! label: continue cur_iou compute_iou(box, cluster[fused_box]) if cur_iou best_iou: best_iou cur_iou best_idx i if best_idx 0: cluster clusters[best_idx] cluster[boxes].append(box) cluster[scores].append(w_score) _update_cluster(cluster) else: cluster { label: label, boxes: [box], scores: [w_score], fused_box: box.copy() } clusters.append(cluster) # 输出融合结果 out_boxes, out_scores, out_labels [], [], [] for cluster in clusters: arr np.asarray(cluster[boxes], dtypefloat) w np.asarray(cluster[scores], dtypefloat) fused_box (arr * w[:, None]).sum(axis0) / w.sum() fused_score min(1.0, w.sum() / M) out_boxes.append(fused_box) out_scores.append(fused_score) out_labels.append(cluster[label]) # 按融合分数从高到低排序 order np.argsort(out_scores)[::-1] return (np.asarray(out_boxes)[order], np.asarray(out_scores)[order], np.asarray(out_labels)[order])上面这段代码里我对 records 的原始分数处理有点绕主要是想先保证“排序按权重后的分数”。工程化实现时我建议在 records 里同时保存score和w_score两个字段不要像我这样从排序分数反推否则会有不必要的数值误差。下面给一个更清晰的骨架版本for m in range(M): for box, score, label in zip(boxes_list[m], scores_list[m], labels_list[m]): if score skip_box_thr: continue records.append({ score: float(score), w_score: float(score) * weights[m], model_idx: m, box: np.asarray(box, dtypefloat), label: int(label) }) records.sort(keylambda x: x[w_score], reverseTrue)后面的聚类逻辑就用record[w_score]作为贡献值record[score]只用来排序和展示。这样整个流程就清楚很多。3.3 跑一个两模型融合的小例子我用一个极简例子演示 WBF 的效果。假设两个模型对同一个目标各输出一个框一个稍微偏左一个稍微偏右。boxes1 np.array([[10, 10, 50, 50]], dtypefloat) scores1 np.array([0.9]) labels1 np.array([1]) boxes2 np.array([[14, 12, 52, 53]], dtypefloat) scores2 np.array([0.8]) labels2 np.array([1]) fused_boxes, fused_scores, fused_labels wbf( [boxes1, boxes2], [scores1, scores2], [labels1, labels2], iou_thr0.55 ) print(fused_boxes) # 大致会输出 [12, 10.9, 50.8, 51.3] 附近的框 print(fused_scores) # 大约 0.85因为两个模型置信度平均这个例子里两个模型对同一目标的真实位置存在互补误差WBF 输出的坐标会落在两个模型预测框之间比单独取任何一个模型都更接近真实值。这就是 WBF 最核心的收益。3.4 实现时容易踩的三个坑第一个坑是坐标格式不统一。我用归一化坐标做过一个项目某个模型输出的是[center_x, center_y, width, height]另一个模型输出的是[x1, y1, x2, y2]结果 WBF 出来的框全是乱的。后来我把所有模型的输出统一转成x1y1x2y2格式并且确认都在同一坐标尺度下才恢复正常。第二个坑是类别标签不一致。多模型集成时模型 A 的类别 ID 为 1 表示“人”模型 B 的类别 ID 为 1 可能表示“车”。如果直接按 ID 匹配WBF 会把两个完全不同的目标混在一个簇里。正确的做法是先建立一个类别名到统一 ID 的映射表把所有模型的标签都映射到同一套 ID 上再做融合。第三个坑是没有做 weight 归一化。如果某个模型权重直接设成 5另一个模型权重设成 1融合分数很容易超过 1。虽然不至于影响排序但会让人对分数失去直觉。我习惯先把权重除以权重均值让权重中心落在 1 附近既保留相对关系又让融合分数大概率维持在 0 到 1 之间。4. 在真实检测任务里怎么用好 WBF4.1 多模型集成模型差异越大WBF 越划算WBF 在多模型集成里收益最明显。但并不是模型越多越好关键在于模型之间的“互补性”。如果两个模型结构几乎一样训练数据也一样它们犯的错大概率也类似WBF 融合后提升有限甚至只是把置信度平滑一下。真正提升大的是不同骨干网络、不同训练策略、不同输入分辨率组合出的模型。我在一次检测需求里用过一个简单组合一个基于卷积网络的检测器一个基于 Transformer 结构的检测器再加一个多尺度训练的版本。单独看三个模型里最强的那一个也就到 0.81 的 mAP用 WBF 把三个模型融合后直接到 0.84。提升主要来自那些单个模型都犹豫不决的目标模型 A 认为是小目标模型 B 认为是中等目标模型 C 没检出来但 WBF 没有直接丢弃任何一个结果而是把 A 和 B 的框平均了一下最终框反而更贴合标注。当然如果所有模型都是同一个模型在不同 epoch 下存的权重WBF 的收益通常很小。这种时候模型之间高度相关平均框的方差下降有限不如老老实实做 TTA 或选一个最优单模型。4.2 TTA 场景下的 WBF别忽略了坐标还原WBF 也经常用在测试时增强中。常见做法是原图预测一次水平翻转图预测一次可能还有多尺度预测几次然后把所有预测结果送进 WBF。这里特别要注意坐标还原。水平翻转后的预测框需要变换回原图坐标公式是x1 image_width - x2 x2 image_width - x1 y1 y1 y2 y2如果你忘了这一层还原翻转模型的 x 坐标会和原图坐标完全相反WBF 融合出来的框会是一堆横跨左右的大框位置偏得离谱。多尺度增强则要注意缩放关系模型输入是 800 像素宽原图是 1600 像素宽那么预测框坐标要乘 2 才能回到原图坐标系。TTA 场景下的 WBF 还有一个细节同一个模型的不同增强结果并不完全独立所以融合分数的“共识折扣”会显得偏保守。我个人做法是给原始输入对应的模型权重稍微高一点增强版本权重低一点避免 TTA 结果把原本非常确定的目标分数拉低。4.3 WBF 和 NMS 的前后搭配顺序很多人第一次用 WBF 时会直接把每个模型的原始输出一股脑塞进去。理论上可以但不是最优。检测模型在推理时已经在内部做过 NMS所以输出的框本身已经是“收敛”过的但也有开源检测框架会提供“NMS 之前”的 RAW 输出那种输出包含大量重复框直接送 WBF 会很慢而且重复框会主导加权平均把融合框拉偏。我建议的流程是三步每个模型独立输出后先用一个比较宽松的 NMS 把高重叠框压掉比如iou_thr0.7把每个模型剩下的框统一坐标格式和类别映射送入 WBF设置iou_thr0.55左右做融合。WBF 输出了融合结果之后如果你发现仍然存在少数高度重叠的框可以再做一次最终 NMSiou_thr设在 0.5 到 0.6 之间。这一步主要是清理 WBF 聚类时因为 IoU 刚刚低于阈值而漏掉的残余重复结果但不要设太大否则会把真实重叠的物体也删掉。4.4 类别与坐标系对齐看似简单踩过才知道多模型集成中类别对齐和坐标系对齐是最容易被忽略但后果最严重的两个问题。类别对齐可以用一张映射表解决。比如模型 A 的 0 号类是“背景”1 号类是“人”模型 B 的 0 号类是“人”1 号类是“车”。你不能直接拿 ID 去匹配而要先把模型 A 的“人”转成统一 ID 1模型 B 的“人”也转成统一 ID 1。这样 WBF 才能把不同模型对“人”的预测聚到同一个簇里。坐标系对齐则要确认三件事坐标格式是不是都是x1y1x2y2、坐标基准是不是都是像素或都是归一化、图像尺寸和缩放比例是否一致。我接手过另一个项目同一个模型在一组图上做多尺度推理小尺度的框没缩放回原图送到 WBF 后这些框全都集中在图像左上角最后整个融合结果在验证集上掉了十几个点。排查半天才发现是坐标没有做尺度还原。这类问题一旦发生光看单张图很难看出来一定要写一段自动化断言比如检查所有框坐标范围是否落在图像尺寸内再开始融合。5. 调参与问题排查我的实践笔记5.1 WBF 参数速查表我把 WBF 的常用参数和调整方向整理成了一张表方便对照。参数默认值参考作用调低调高iou_thr0.55控制哪些框能归为一簇合并更多框输出框变少匹配更严格输出框变多skip_box_thr0.0预过滤低置信度框保留更多低分结果去掉更多噪声框weights全 1每个模型的投票权重弱化某个模型影响强调某个模型影响最终分数阈值视验证集而定过滤融合分过低的输出提高召回降低误检最终 NMS IoU0.5~0.6清理残余重叠保留更多重叠框去掉更多重叠框这里最容易被误解的是iou_thr。很多人觉得“IoU 阈值调高不是应该保留更多框吗”实际上在 WBF 里iou_thr越高候选框越难匹配进已有簇也就更容易新建簇所以输出框会变多。反过来iou_thr越低框之间越容易并入同一个簇输出框数量下降。调整时一定要记得这个方向不然很容易反着调。5.2 典型异常现象与处理我整理几个 WBF 使用中非常典型的异常以及我在排查时的思路。现象一融合框位置明显偏大或偏小。这通常是低置信度、低质量的框混进了簇拉低了加权平均的位置精度。处理办法有两个先调大skip_box_thr把噪声低分框过滤掉或者调大iou_thr让距离较远的低分框不会被硬融进来。如果还不行就要检查是不是某些模型的框本身系统性偏移降低对应模型权重。现象二融合置信度低得离谱。如果你按“同一个目标只在部分模型中被检出”的场景来看这其实是正常的。但如果目标明明很清晰所有模型都检出了高置信度框融合分还是很低那就要看模型数量 M 是不是设错了。比如你只把两个模型的框传进来但内部代码里 M 被写成了 4融合分就会被除以 4。我遇到过类似问题定位方式是打印每个簇里scores数组的和再和M做对比。现象三输出框数量比想象中多很多。优先检查类别标签是否对齐因为不同类别的框永远不会合并。如果类别没问题多半是iou_thr太高导致很多本应并成一簇的框被拆散了。适当降低iou_thr并在 WBF 后加一次最终 NMS 兜底。现象四某些目标漏检。如果某个目标只被一个模型检出而其余模型都没检出WBF 的融合分会因为除以模型数量而变低最终被阈值过滤掉。这不是 bug而是 WBF 的“共识偏好”。如果你希望保留这类罕见目标需要降低最终分数阈值或者给能检出这个目标的模型更高权重。5.3 一条可复用的调参路径我通常不在测试集上调参而是在验证集上走一条比较机械的流程。第一步固定skip_box_thr0、weights全 1把iou_thr从 0.4 到 0.65 每隔 0.05 扫一遍直接在验证集上算 mAP。正常情况下会存在一个平台期选平台期中间的值作为初始参数。第二步观察验证集上的错误类型。如果误检多就逐步提高skip_box_thr看 mAP 是否上升如果漏检多就保持skip_box_thr在 0 附近靠最终分数阈值来控制精度和召回。第三步在验证集上评估每个单模型的 mAP按模型质量给一个粗略初始权重。比如最强模型权重给 1.2最弱给 0.8归一化之后跑一轮看 mAP 是否变化。模型权重网格搜索一般不需要太精细0.5 间隔就够用了。最后把 WBF 输出的融合分数在验证集上重新校准一次。注意融合分数和单模型的置信度分布完全不同不能用单模型的 0.5 阈值直接套到融合分数上。一定要基于融合分数重新画 Precision-Recall 曲线再选阈值。在整个调参过程中我最大的体会是WBF 是一个集成层工具它不会把烂模型救活但能把好模型的互补信息充分压榨出来。如果你的单个模型本身质量差或者模型之间高度相似那 WBF 带不来奇迹不如先回头优化单个模型。最后再分享一个小技巧。我在项目里会把 WBF 的输出结果和每个簇的“成员明细”一起保存下来包括每个模型对这个簇贡献了哪些框、权重是多少、原始置信度是多少。一旦后续发现某个模型在特定场景下总给错误框我可以按模型编号单独降权而不是重新调全局参数。这种细粒度的可观测性比只看最终 mAP 有用得多。WBF 的实现并不复杂复杂的是把它放到检测链路里时你能不能快速定位是哪一环出了问题。把坐标统一、类别对齐、参数方向和分数校准这四件事做扎实WBF 基本就能稳定发挥作用了。

相关新闻

单片机毕设选题推荐:基于51单片机的洗衣机水位洗涤与烘干消毒系统设计 基于单片机的智能洗衣机水位检测与洗涤消毒装置设计(032802)

单片机毕设选题推荐:基于51单片机的洗衣机水位洗涤与烘干消毒系统设计 基于单片机的智能洗衣机水位检测与洗涤消毒装置设计(032802)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/10/14 5:50:17 阅读更多 →
openJiuwen Agent Core Java legacy 多智能体默认路由控制器 DefaultGroupController 深度解析

openJiuwen Agent Core Java legacy 多智能体默认路由控制器 DefaultGroupController 深度解析

人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习 【免费下载链接】agent-core-java openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。 项目地址: https://gitco…

2026/10/14 5:50:17 阅读更多 →
通义万相Wan2.2实战指南:从模型部署到视频生成调参

通义万相Wan2.2实战指南:从模型部署到视频生成调参

1. 通义万相Wan2.2到底升级了什么1.1 从Wan2.1到Wan2.2:最值得关注的三个变化Wan2.2,准确说是2025年4月这一版开源的视频生成大模型,属于通义万相(Wan)系列的一次重要迭代。如果你之前折腾过Wan2.1,拿到2.2…

2026/10/14 5:50:17 阅读更多 →

最新新闻

Vue 3.6 Vapor 模式结合 WebGL/Canvas:打造 60fps 极速实时数据流图表

Vue 3.6 Vapor 模式结合 WebGL/Canvas:打造 60fps 极速实时数据流图表

在构建出海 SaaS 的实时监控大屏、高频金融行情图、或者双 11 大促流量实时态势感知系统时,前端工程师常常会遇到一个令人头疼的性能瓶颈:高频数据流与框架渲染开销的冲突。 当服务端通过 WebSocket 以每秒 60 次到 100 次的频率向前端推送成千上万个指标…

2026/10/14 6:33:28 阅读更多 →
人工智能课程(配套AIMA(Artificial Intelligence: A Modern Approach))

人工智能课程(配套AIMA(Artificial Intelligence: A Modern Approach))

一、1 AI简介27 道德与安全四种理解 AI 的方式:Think like a human —— 像人一样思考 Act like a human —— 像人一样行动 Think rationally —— 理性地思考 Act rationally —— 理性地行动这门课把 AI 的核心看成:构造能够在环境中“理性行动&#…

2026/10/14 6:33:28 阅读更多 →
级联H桥储能变流器双层SOC均衡:相内相间错峰控制策略

级联H桥储能变流器双层SOC均衡:相内相间错峰控制策略

调到级联H桥储能变流器项目上的人,迟早都会撞上同一样东西:屏幕上几十条SOC曲线像炸开的梳子,A相第3簇还顶着72%在放电,B相最差的那簇已经报到58%。你要是不管,顶多几分钟,最弱的那一簇就会先触底&#xff…

2026/10/14 6:33:28 阅读更多 →
级联H桥储能变流器SOC均衡:0.3s/0.7s分时投入策略解析

级联H桥储能变流器SOC均衡:0.3s/0.7s分时投入策略解析

做储能变流器调试这些年,级联H桥拓扑的电池SOC均衡算是最让人挠头的问题之一。最近在某高压直挂储能项目上又遇到电池簇SOC严重不一致的典型工况,靠着一组“0.3s投入相内控制,0.7s投入相间控制”的分时策略把极差从接近12%压回到了3%以内。这…

2026/10/14 6:33:28 阅读更多 →
单商户商城软件开发案例:整合积分抵扣、抽奖奖励与分销身份

单商户商城软件开发案例:整合积分抵扣、抽奖奖励与分销身份

单商户商城的基础功能通常是商品展示、规格选择、订单结算和在线支付,但当商品与积分、抽奖资格、分销身份和线下门店提货结合后,商城中的不同商品就不再只有普通购买属性。根据某公司的商城业务需求,海拔网络完成了一套单商户商城软件的定制…

2026/10/14 6:33:28 阅读更多 →
AI日报系统设计:轻量级信息流处理流水线

AI日报系统设计:轻量级信息流处理流水线

1. 项目概述:这不是一份“新闻简报”,而是一套可复用的AI信息流处理系统“AI 日报(2026-10-11)”这个标题乍看像一份时效性极强的行业快讯,但作为从业十年、亲手搭建过7套不同规模信息聚合系统的老手,我一眼…

2026/10/14 6:32:28 阅读更多 →

日新闻

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/12 18:11:17 阅读更多 →