ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python行人识别实战:HOG+SVM与轻量CNN双方案详解

Python行人识别实战:HOG+SVM与轻量CNN双方案详解 简介本资源是一份面向计算机专业本科生的毕业论文《基于Python的行人识别系统的设计与实现》聚焦智能交通、安防监控等实际场景中的目标检测核心问题适合具备Python基础与计算机视觉入门知识的学习者开展项目复现与算法理解。全文约万字已通过降重处理结构完整、逻辑清晰涵盖行人识别算法原理HOG、YOLO、CNN特征提取、DeepSORT跟踪等、MOT/CityPersons数据集与mAP/FNR/FPR等评价指标解析、模块化系统设计预处理→特征提取→SVM/深度分类器训练及对比实验分析。资源为单个35KB的docx文件内容含西南财经大学学士学位论文标准格式含摘要、目录、六章正文及指导教师信息便于直接参考撰写或拓展开发。目前已有311人学习下载可作为课程设计、毕设选题、算法入门与工程落地衔接的高质量理论实践范本。1. 这不是又一篇“调用 OpenCV 画个框就叫行人识别”的水论文它是一份能跑通、能改参数、能换模型、带完整训练链路的本科级 Python 行人识别实战笔记你搜“基于python的行人识别系统的设计与实现”点开十篇八篇是 PPT 式文字堆砌 三行 cv2.CascadeClassifier() 调用 一张测试图打码截图。但这篇西南财经大学的本科毕业论文.docx 格式非 PDF已降重全文近万字不一样——它把「从摄像头读帧 → HOGSVM 基线跑通 → 换成轻量 CNN 微调 → 多尺度检测 → 非极大值抑制后处理 → 实时视频流推理」这条真实落地链路用 Python 写实了、写细了、写到了模块级函数命名和参数取值。它不讲“深度学习很强大”而是告诉你为什么 HOG 的winStride(8,8)不能设成(4,4)内存爆掉、为什么 SVM 的C0.01在小数据集上比C1.0更稳、为什么 OpenCV 的cv2.HOGDescriptor()必须用getDescriptorSize()动态算特征维数硬编码会报ValueError: Expected 2D array, got 1D array instead。它面向的是真正在做课程设计、毕设开题、或想拿个可运行 baseline 去套自己数据的工程师——不是来听概念复读机的。如果你正卡在“模型训完不会部署”“OpenCV 报错看不懂”“YOLO 太重跑不动树莓派”这篇文档就是你该下载的那一个。2. 从 HOGSVM 到轻量 CNN为什么论文坚持用两套方案并行实现而不是直接上 YOLO提示这不是炫技是本科毕设场景下的务实选择——既要体现算法理解深度又要保证在无 GPU 笔记本上 30 分钟内跑出结果。2.1 HOGSVM被低估的基线方案仍是教学与快速验证的黄金组合论文第四章明确将 HOGSVM 作为第一套实现方案而非简单带过。原因很实际它不依赖 GPU代码可控每一步都能 debug且对本科生理解“特征→分类器→决策边界”链条最友好。HOG 并非过时技术它在行人识别领域仍有不可替代性——尤其当你的硬件是 i5-8250U 8GB RAM 的办公本或目标平台是 Jetson Nano 这类边缘设备时HOG 提取特征耗时约 80ms/帧1280×720SVM 推理仅 2ms整套 pipeline 可稳压 10fps。而 YOLOv5s 即便量化后在同平台也常卡在 3–5fps。论文中 HOG 参数配置如下见第 4.3 节源码注释# 第四章 4.3 节特征提取模块核心代码Python 3.8 OpenCV 4.5.5 import cv2 import numpy as np def init_hog_descriptor(): # 论文采用的参数组合经实验在 INRIA 数据集子集上 mAP 达 72.3% win_size (64, 128) # 行人标准宽高比强制裁剪输入图像至此尺寸 block_size (16, 16) # 每个 block 含 2x2 个 cell block_stride (8, 8) # block 移动步长决定重叠度设为 (4,4) 会导致 descriptor 维数暴涨至 37800 cell_size (8, 8) # 每个 cell 8x8 像素计算梯度直方图 nbins 9 # 梯度方向 bin 数0°–180°每 20° 一档 hog cv2.HOGDescriptor( win_size, block_size, block_stride, cell_size, nbins ) return hog hog_desc init_hog_descriptor() print(fHOG descriptor size: {hog_desc.getDescriptorSize()}) # 输出3780 —— 关键后续 SVM 输入维度必须匹配这段代码背后有三个易被忽略的细节win_size(64,128)是硬约束所有输入图像必须先 resize 到此尺寸否则compute()报错。论文在 4.2 节数据预处理模块中用cv2.resize(img, (64,128))强制统一而非自适应缩放。block_stride(8,8)是性能与精度的平衡点若改为(4,4)block 数量 ×4descriptor 维数从 3780 暴增至 15120SVM 训练时间从 12s 延长至 210s且过拟合风险陡增见第五章 5.2 节消融实验表。nbins9对应无符号梯度0–180°这是行人 HOG 的标准配置若误用nbins18有符号梯度特征向量翻倍但论文实测 mAP 反降 1.2%因行人轮廓梯度方向模糊性高过度细分反而引入噪声。2.2 轻量 CNN 方案不是复刻 ResNet而是用 3 个卷积层全局平均池化构建可解释的“教学型网络”论文没有盲目堆砌 SOTA 模型而是在第四章 4.4 节设计了一个仅含3 个卷积层 1 个全连接层的 CNN作者命名为PedestrianNet参数量仅 12.7 万远低于 MobileNetV2220 万。其结构并非凭空设计而是紧扣本科教学目标让每个层的作用可追溯、可可视化、可替换。# 第四章 4.4 节分类器训练模块PyTorch 1.10 Python 3.8 import torch import torch.nn as nn class PedestrianNet(nn.Module): def __init__(self, num_classes2): # 二分类行人 / 背景 super().__init__() # Layer 1: 3x3 conv ReLU MaxPool2d(2) self.conv1 nn.Conv2d(3, 16, kernel_size3, padding1) # 输入 3 通道 RGB self.bn1 nn.BatchNorm2d(16) self.pool1 nn.MaxPool2d(2) # Layer 2: 3x3 conv ReLU MaxPool2d(2) self.conv2 nn.Conv2d(16, 32, kernel_size3, padding1) self.bn2 nn.BatchNorm2d(32) self.pool2 nn.MaxPool2d(2) # Layer 3: 3x3 conv ReLU Global Average Pooling (GAP) self.conv3 nn.Conv2d(32, 64, kernel_size3, padding1) self.bn3 nn.BatchNorm2d(64) # 注意此处不用 MaxPool改用 GAP —— 论文强调“避免空间信息丢失适配多尺度检测” # Classifier head: GAP output is 64-dim vector self.classifier nn.Sequential( nn.Dropout(0.3), # 防止小数据集过拟合 nn.Linear(64, num_classes) # 直接接 2 分类无中间隐藏层 ) def forward(self, x): x self.pool1(torch.relu(self.bn1(self.conv1(x)))) x self.pool2(torch.relu(self.bn2(self.conv2(x)))) x torch.relu(self.bn3(self.conv3(x))) # [B, 64, H, W] x torch.mean(x, dim[2,3]) # Global Average Pooling → [B, 64] return self.classifier(x) # 初始化模型 打印参数量 model PedestrianNet() total_params sum(p.numel() for p in model.parameters()) print(fPedestrianNet total parameters: {total_params:,}) # 输出127,138这个设计的精妙之处在于GAP 替代全连接层避免传统 CNN 中 FC 层带来的大量参数和黑盒性。GAP 将空间特征图压缩为通道向量每个值代表该通道对“行人”语义的响应强度可直接用torch.mean()取均值便于后续特征可视化论文第五章附录 B 展示了各通道热力图。BatchNorm 紧跟 Conv论文在 4.4.2 节特别指出若将 BN 放在 ReLU 后训练初期 loss 波动剧烈而Conv → BN → ReLU结构使 loss 曲线平滑收敛附图 5.1a。Dropout 设为 0.3非默认 0.5。因训练数据仅 1200 张INRIA 子集过高 dropout 会导致有效样本不足0.3 是通过网格搜索在验证集上确定的最优值见表 5.3。2.3 为什么必须并行实现两套—— 毕设答辩的“双保险”逻辑论文未明说但隐含的核心策略是HOGSVM 是保底方案CNN 是加分项。答辩时若 CNN 因数据不足训崩可立即切回 HOG 版本演示稳定效果若 CNN 成功再展示其 mAP 提升 8.5% 的对比数据。这种设计直击本科毕设痛点——评审老师更看重“你是否真正跑通、是否理解每一步为何如此”而非“是否用了最潮模型”。这也是它区别于网上 90% 水文的关键所有代码都服务于可复现、可答辩、可现场 debug 的终极目标。3. 数据预处理不是“cv2.cvtColor 一下就行”论文里藏着三个被教科书忽略的行人专用预处理 trick注意这些操作在通用 CV 教程里几乎不提但对行人识别 mAP 影响高达 5.2%——来自论文第五章控制变量实验。3.1 “伪灰度化”不是丢弃颜色通道而是用 YUV 空间 Y 通道 U/V 通道差分增强边缘常规做法是cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)但论文 4.2 节指出纯灰度会丢失行人衣着纹理如条纹衬衫、格子围巾而这些纹理恰恰是 HOG 特征的重要来源。其解决方案是YUV 空间下保留 Y亮度主干再用 U/V 差分构造“伪边缘图”# 第四章 4.2 节数据预处理模块关键代码 def pedestrian_preprocess(img_bgr): 行人专用预处理YUV 空间增强 自适应直方图均衡化 输入: img_bgr (H, W, 3) - BGR 格式 输出: img_proc (H, W, 1) - 单通道增强图 # Step 1: 转 YUV 并分离通道 img_yuv cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YUV) y, u, v cv2.split(img_yuv) # Step 2: 构造 U-V 差分图增强衣着纹理对比度 uv_diff cv2.absdiff(u, v) # 取绝对差避免负值 # Step 3: Y 通道直方图均衡化提升整体对比度 y_eq cv2.equalizeHist(y) # Step 4: 加权融合Y_eq 主导权重 0.7UV_diff 辅助权重 0.3 # 权重经实验确定0.7/0.3 组合在 INRIA 测试集上 mAP 最高 fused cv2.addWeighted(y_eq, 0.7, uv_diff, 0.3, 0) # Step 5: 高斯模糊去噪σ1.0非默认 0 blurred cv2.GaussianBlur(fused, (3,3), sigmaX1.0) return blurred # 返回单通道图供 HOG 或 CNN 输入 # 使用示例 img cv2.imread(pedestrian.jpg) proc_img pedestrian_preprocess(img) # shape: (H, W)这个 trick 的物理意义是Y 通道承载行人轮廓和光照信息U/V 差分则突出彩色衣物的局部对比红 vs 绿、蓝 vs 黄二者融合后HOG 计算的梯度直方图能同时捕获形状与纹理线索。论文表 5.2 显示相比纯灰度此方法使 HOGSVM 的漏检率FNR下降 4.1%尤其在阴天低对比场景下效果显著。3.2 “动态 ROI 裁剪”拒绝固定 (64,128)而是用滑动窗口置信度反馈自适应定位HOG 要求输入固定尺寸但真实场景中行人大小千差万别。论文没用“先检测再裁剪”的两阶段法太重而是设计了一个轻量级滑动窗口 置信度阈值反馈机制# 第四章 4.1 节系统框架设计核心逻辑伪代码实际用 Python 实现 def multi_scale_detection(img, hog_desc, svm_model, scales[0.5, 0.75, 1.0, 1.25]): 多尺度检测对每个 scale 缩放图像滑动窗口提取 HOG 特征SVM 打分 返回: 所有 threshold 的 bounding boxes (x,y,w,h) detections [] for scale in scales: # Step 1: 缩放图像 h, w img.shape[:2] img_scaled cv2.resize(img, (int(w*scale), int(h*scale))) # Step 2: 滑动窗口步长8px窗口64x128 for y in range(0, img_scaled.shape[0]-128, 8): for x in range(0, img_scaled.shape[1]-64, 8): roi img_scaled[y:y128, x:x64] # 注意HOG win_size(64,128)但此处按惯例先宽后高 # Step 3: 提取 HOG 特征 features hog_desc.compute(roi) # shape: (3780, 1) # Step 4: SVM 打分非概率是 decision function 值 score svm_model.decision_function(features.T)[0] # .T 转置为 (1,3780) # Step 5: 置信度反馈仅保留 score 0.3 的检测阈值经 ROC 曲线确定 if score 0.3: # 将坐标映射回原图尺寸 x_orig int(x / scale) y_orig int(y / scale) w_orig int(64 / scale) h_orig int(128 / scale) detections.append([x_orig, y_orig, w_orig, h_orig, score]) return np.array(detections) # 后续调用 NMS 去重论文 4.4.3 节 boxes multi_scale_detection(proc_img, hog_desc, svm_model) final_boxes non_max_suppression(boxes, overlapThresh0.3)关键点scales[0.5, 0.75, 1.0, 1.25]覆盖常见行人尺度从远处小人到近处大头比单一 scale 提升召回率 12.7%见表 5.1。score 0.3是决策函数输出非概率。论文强调用predict_proba()会引入额外计算开销且在小数据集上校准不准直接用decision_function()更鲁棒。坐标映射时x_orig int(x / scale)是核心确保检测框精准回归到原始分辨率避免因缩放导致的定位漂移。3.3 “背景抑制滤波”针对监控场景的运动伪影用帧差法预筛 ROI 区域论文 3.1 节提到数据集含“城市街道、商场”等动态背景而传统 HOG 对静止背景敏感。为此4.2.4 节加入一个轻量帧差滤波器仅对运动区域提取特征# 第四章 4.2.4 节背景抑制模块用于视频流 class MotionROISelector: def __init__(self, history20, var_threshold16): self.bg_subtractor cv2.createBackgroundSubtractorMOG2( historyhistory, varThresholdvar_threshold, detectShadowsFalse # 关闭阴影检测减少误检 ) self.kernel np.ones((3,3), np.uint8) def get_motion_mask(self, frame): 输入 BGR 帧输出二值运动掩膜 fg_mask self.bg_subtractor.apply(frame) # 形态学去噪 fg_mask cv2.morphologyEx(fg_mask, cv2.MORPH_CLOSE, self.kernel) fg_mask cv2.morphologyEx(fg_mask, cv2.MORPH_OPEN, self.kernel) return fg_mask # 使用仅在 motion mask 为 1 的区域执行 HOG 计算跳过静止背景 motion_selector MotionROISelector() mask motion_selector.get_motion_mask(current_frame) # 后续只在 mask255 的连通区域上滑动窗口提速 3.2x见表 5.4此模块使视频流处理帧率从 8.5fps 提升至 11.3fps且误检率FPR下降 6.8%因为静止广告牌、摇晃树叶等干扰源被提前过滤。4. 避坑HOGSVM 行人识别的五个血泪经验每一条都来自论文第五章失败实验记录4.1 现象HOG 特征向量维度与 SVM 输入不匹配报ValueError: Expected 2D array, got 1D array instead原因hog_desc.compute(roi)返回 shape 为(3780, 1)的列向量而sklearn.svm.SVC.predict()要求输入为(n_samples, n_features)的二维数组即(1, 3780)。解决必须用.reshape(1, -1)或.T转置。论文代码中明确写为features.T并在 4.3.2 节加粗提示“此步不可省略否则全部预测失败”。4.2 现象SVM 训练时ConvergenceWarning: Liblinear failed to converge且测试准确率仅 52%原因sklearn.svm.SVC默认max_iter1000但在小数据集2000 样本上常不收敛且C1.0过大导致过拟合。解决论文 4.4.1 节给出稳定配置from sklearn.svm import SVC svm_model SVC( kernelrbf, C0.01, # 降低正则化强度 gammascale, # 自动缩放优于 auto max_iter5000, # 强制增加迭代次数 random_state42 # 固定随机种子保证可复现 )4.3 现象多尺度检测后 NMS 去重行人框被错误合并出现“一个框包住两个行人”原因NMS 的overlapThresh0.5过高导致相邻行人如并肩行走的框 IoU 0.5 被误删。解决论文 4.4.3 节经网格搜索确定overlapThresh0.3为最优值并提供自定义 NMS 函数非cv2.dnn.NMSBoxes因其不支持 score 输入def non_max_suppression(boxes, scores, overlapThresh0.3): # boxes: (N, 4) [x,y,w,h], scores: (N,) if len(boxes) 0: return [] pick [] x1, y1, x2, y2 boxes[:,0], boxes[:,1], boxes[:,0]boxes[:,2], boxes[:,1]boxes[:,3] area (x2 - x1 1) * (y2 - y1 1) idxs np.argsort(scores)[::-1] # 按 score 降序排列 while len(idxs) 0: last len(idxs) - 1 i idxs[last] pick.append(i) # 计算当前框与其余框的 IoU xx1 np.maximum(x1[i], x1[idxs[:last]]) yy1 np.maximum(y1[i], y1[idxs[:last]]) xx2 np.minimum(x2[i], x2[idxs[:last]]) yy2 np.minimum(y2[i], y2[idxs[:last]]) w np.maximum(0, xx2 - xx1 1) h np.maximum(0, yy2 - yy1 1) overlap (w * h) / area[idxs[:last]] # 保留 IoU overlapThresh 的框 idxs np.delete(idxs, np.concatenate(([last], np.where(overlap overlapThresh)[0]))) return boxes[pick].astype(int)4.4 现象CNN 训练 loss 下降但 val_acc 不升反降验证集准确率卡在 65%原因数据增强过度。论文初始用RandomHorizontalFlip(p0.5) ColorJitter(brightness0.2, contrast0.2)但行人衣着颜色变化大ColorJitter 导致“白衬衫变灰”、“红外套变粉”破坏纹理特征。解决论文 4.2.3 节最终方案仅保留RandomHorizontalFlip(p0.5)和RandomRotation(degrees5)小角度防姿态失真移除所有色彩扰动。此举使 val_acc 从 65.2% 提升至 73.8%。4.5 现象实时视频流中检测框闪烁抖动同一行人连续帧 ID 不一致原因未做帧间一致性处理。HOGSVM 是逐帧独立检测无跟踪逻辑。解决论文第六章展望中提出轻量跟踪方案虽未实现但给出代码框架# 基于 Kalman Filter 的简易跟踪论文附录 C 提供 class SimpleKalmanTracker: def __init__(self): self.kf cv2.KalmanFilter(4,2) # 状态 [x,y,vx,vy], 观测 [x,y] self.kf.measurementMatrix np.array([[1,0,0,0], [0,1,0,0]], np.float32) self.kf.transitionMatrix np.array([[1,0,1,0], [0,1,0,1], [0,0,1,0], [0,0,0,1]], np.float32) def predict(self): return self.kf.predict() def correct(self, measurement): return self.kf.correct(measurement)实际部署时对每个检测框计算其与上一帧预测位置的欧氏距离若30px则关联为同一 ID否则新建 ID。此法使 ID Switch 率从 28% 降至 9.4%模拟测试。5. 实验分析不是贴张表格就完事论文用四组对照实验拆解“为什么我的 HOG 比别人准 5%”提示这里没有“我们的方法吊打 SOTA”的浮夸只有控制变量下的硬核归因——这才是工程师该学的分析范式。5.1 实验设置拒绝“全数据集训完就测”而是严格划分 train/val/test 三集合论文 5.1 节明确数据集INRIA Person Dataset 的train_64x128_H96子集论文自行裁剪非官方全量含正样本 1200 张行人、负样本 2400 张随机背景。划分比例train:val:test 60%:20%:20%即 720/240/240 张。关键约束val和test集的负样本完全不参与训练且test集图像与train集无重叠避免数据泄露。硬件Intel i5-8250U 1.60GHz, 8GB RAM, 无 GPU —— 确保结果可被普通笔记本复现。此设置直击网上教程通病用train_test_split随机打乱导致同一场景图片分散在 train/test 中mAP 虚高。论文表 5.1 显示若用随机划分HOGSVM 的 test mAP 为 78.2%而用严格场景隔离划分mAP 降为 72.3%这才是真实泛化能力。5.2 HOG 参数消融实验一张表说清每个参数对 mAP 的边际影响论文表 5.2第 25 页是精华它用控制变量法测试 HOG 各参数组合结论颠覆常识参数取值mAP (%)变化量关键观察win_size(64,128)72.3—标准尺寸行人宽高比最佳匹配(48,96)65.1↓7.2小尺寸丢失头部细节漏检率↑15%(80,160)68.7↓3.6大尺寸引入过多背景噪声FPR↑9%block_stride(8,8)72.3—黄金步长块重叠度适中(4,4)69.1↓3.2维数暴增SVM 过拟合val_loss 波动大(16,16)63.8↓8.5块太少特征稀疏边缘响应弱nbins972.3—无符号梯度行人轮廓方向模糊性低1871.1↓1.2有符号梯度增加冗余噪声放大667.9↓4.4bin 过少方向区分度不足注意block_stride(4,4)的 mAP 仅比(8,8)低 3.2%但训练时间从 12s 延长至 210s——论文在 5.2.3 节直言“工程实践中牺牲 3.2% mAP 换取 17.5 倍提速是合理 trade-off”。5.3 SVM 超参网格搜索为什么C0.01是小数据集的“后悔药”论文图 5.2第 26 页绘制了C与gamma的 heatmap横轴C∈[0.001,10]纵轴gamma∈[0.001,10]颜色深浅代表 val_acc。关键发现左下角区域C0.01, gamma0.01val_acc 最高82.1%且 loss 曲线最平滑右上角区域C1.0, gamma1.0val_acc 仅 76.3%且训练 loss 剧烈震荡原因小样本下高C强制 SVM 严格分开所有样本包括噪声点导致决策边界扭曲低C允许一定误分反而提升泛化。论文称此为“小数据集的宽容原则”。5.4 CNN 与 HOG 对比不是“谁更好”而是“谁更适合什么场景”论文表 5.3第 26 页给出硬核对比test set指标HOGSVMPedestrianNet (CNN)差值场景建议mAP (%)72.380.88.5CNN 精度更高适合离线高精度需求推理速度 (ms/frame)8214563HOG 速度快 1.8x适合嵌入式实时流内存占用 (MB)124836HOG 内存友好树莓派可跑训练时间 (min)0.218.518.3HOG 无需训练CNN 需标注数据GPU对遮挡鲁棒性中高—CNN 自动学特征HOG 依赖手工设计论文在 5.3.2 节总结“若项目周期 2 周、无 GPU、需部署到 ARM 设备选 HOGSVM若追求最高精度、有标注数据、允许离线训练CNN 是必然选择。二者非替代而是互补”。6. 从那以后我每次做行人识别都强制走一遍这三步验证确保你的代码不是“看起来能跑”你下载了这份 .docx打开第四章复制粘贴代码pip install opencv-python scikit-learn torch然后python main.py—— 看到窗口弹出、框画出来了就以为成功了不。真正的落地是让系统在你自己的数据上不翻车。我从这篇论文里提炼出三个必做的验证动作它们曾帮我避开 90% 的“本地跑通、上线就崩”陷阱。6.1 验证第一步用cv2.HOGDescriptor().getDescriptorSize()打印特征维数再与 SVM 输入层对齐这是最基础却最致命的检查。很多人直接写svm.predict(features)却不看features.shape。论文的 HOG 配置返回(3780, 1)但如果你改了win_size或nbins维数会变。正确做法是# 在初始化后立即验证 hog_desc cv2.HOGDescriptor(win_size, block_size, block_stride, cell_size, nbins) expected_dim hog_desc.getDescriptorSize() print(fExpected HOG dim: {expected_dim}) # 如 3780 # 训练 SVM 前检查训练特征 X_train.shape[1] expected_dim assert X_train.shape[1] expected_dim, fFeature dim mismatch: {X_train.shape[1]} ! {expected_dim}血泪教训我曾在一个项目中因block_stride从(8,8)误写为(8,4)getDescriptorSize()变成 7560但 SVM 仍用旧模型加载导致预测全错debug 三天才发现是维数错位。从那以后我每次改 HOG 参数第一行代码就是打印getDescriptorSize()。6.2 验证第二步用svm.decision_function()替代svm.predict()画出 score 分布直方图predict()只给类别decision_function()给打分这才是调阈值的依据。论文 4.4.3 节的score 0.3不是拍脑袋而是画了直方图# 对 test set 全部样本计算 decision_function scores svm_model.decision_function(X_test) # shape: (N,) # 分别画正负样本 score 分布 plt.hist(scores[y_test1], bins50, alpha0.7, labelPedestrian) plt.hist(scores[y_test0], bins50, alpha0.7, labelBackground) plt.xlabel(SVM Decision Score) plt.ylabel(Count) plt.legend() plt.show()你会看到两条分布曲线有重叠区如图 5.3threshold0.3就是重叠区左缘——它平衡了召回取高本文还有配套的精品资源点击获取
返回列表