基于YOLOv8的热成像人员检测系统:从原理到部署实践
在安防监控、消防救援、夜间巡检等场景中传统可见光摄像头受光线条件限制明显而热成像技术通过检测物体发出的红外辐射能够在完全黑暗、烟雾、雾霾等恶劣环境下清晰成像。结合YOLOv8这一当前最先进的实时目标检测算法可以构建出高精度的热成像人员识别系统为24小时不间断安防监控提供可靠技术支撑。本文将完整介绍基于YOLOv8的热成像人员检测系统从环境搭建、数据准备、模型训练到完整系统部署的全流程。无论你是刚接触深度学习的新手还是有一定计算机视觉基础的开发者都能通过本文掌握完整的项目实施方法。文章包含详细的代码示例、配置文件、常见问题解决方案所有内容均可直接复用到实际项目中。1. 项目背景与技术选型1.1 热成像技术优势与应用场景热成像相机通过检测物体表面的红外辐射强度来生成图像不同于传统相机依赖可见光反射。这种技术具有几大核心优势全天候工作能力完全不受光照条件影响可在漆黑环境中正常检测穿透能力能够穿透烟雾、薄雾等遮挡物在火灾救援等场景中尤为重要隐私保护只能检测人体轮廓无法识别具体面部特征适用于需要保护个人隐私的监控场景温度检测可同时获取目标的表面温度信息在疫情防控、工业检测中有额外价值典型应用场景包括夜间安防监控、森林防火人员搜救、化工厂危险区域监控、疫情防控体温筛查、电力设备巡检等。1.2 YOLOv8算法优势YOLOv8是Ultralytics公司在2023年发布的最新版本目标检测算法相比前代具有显著改进更高的检测精度采用新的骨干网络和检测头设计在COCO数据集上达到更高mAP更快的推理速度优化了网络结构和训练策略在相同硬件条件下速度提升明显更友好的使用体验提供了更简洁的API接口和更完善的文档支持多任务支持除了目标检测还支持实例分割、姿态估计等任务对于热成像人员检测这种需要实时处理的应用场景YOLOv8的效率和精度优势尤为明显。1.3 系统架构概述完整的系统包含以下几个核心模块数据采集模块热成像相机或热成像视频流输入预处理模块图像增强、尺寸标准化等预处理操作推理检测模块YOLOv8模型加载和推理计算后处理模块检测结果解析、非极大值抑制等可视化界面检测结果实时显示和报警功能2. 环境准备与依赖安装2.1 系统环境要求推荐使用以下环境配置其他版本可能需要适当调整操作系统Ubuntu 20.04/22.04或Windows 10/11Python版本3.8-3.10推荐3.9深度学习框架PyTorch 1.12.0及以上CUDA版本11.3-11.7GPU加速可选2.2 核心依赖安装创建并激活Python虚拟环境# 创建虚拟环境 python -m venv yolov8_thermal # 激活环境Linux/Mac source yolov8_thermal/bin/activate # 激活环境Windows yolov8_thermal\Scripts\activate # 升级pip版本 pip install --upgrade pip安装PyTorch根据CUDA版本选择# 如果使用GPUCUDA 11.7 pip install torch1.13.1cu117 torchvision0.14.1cu117 torchaudio0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117 # 如果仅使用CPU pip install torch1.13.1cpu torchvision0.14.1cpu torchaudio0.13.1 --extra-index-url https://download.pytorch.org/whl/cpu安装YOLOv8和其他依赖# 安装Ultralytics YOLOv8 pip install ultralytics # 安装图像处理和相关库 pip install opencv-python pillow numpy pandas matplotlib seaborn # 安装界面开发库 pip install PyQt5 pyqt5-tools # 安装其他工具库 pip install scipy tqdm tensorboard2.3 环境验证创建验证脚本检查环境是否正确安装# environment_check.py import torch import cv2 from ultralytics import YOLO import PyQt5 print(fPyTorch版本: {torch.__version__}) print(fCUDA可用: {torch.cuda.is_available()}) if torch.cuda.is_available(): print(fGPU设备: {torch.cuda.get_device_name(0)}) print(fOpenCV版本: {cv2.__version__}) print(fYOLOv8版本: {YOLO.__version__}) print(环境验证通过)运行验证脚本确保所有依赖正确安装。3. 热成像数据集准备与处理3.1 热成像数据特点热成像数据与普通RGB图像有显著差异单通道灰度图像通常为16位或8位灰度图温度值映射像素值对应实际温度或相对温度对比度较低需要适当的图像增强处理标注标准标注框需要适应热成像中的人体轮廓特征3.2 数据收集与标注热成像人员检测数据集可以通过以下方式获取公开数据集FLIR ADAS等公开热成像数据集自采集数据使用热成像相机实际采集数据合成将可见光数据转换为热成像风格创建数据标注规范文件# data.yaml path: /path/to/thermal_dataset # 数据集根目录 train: images/train # 训练图像路径 val: images/val # 验证图像路径 test: images/test # 测试图像路径 # 类别定义 nc: 1 # 类别数量仅检测人员 names: [person] # 类别名称 # 自动下载权重 download: https://ultralytics.com/static/assets/datasets/coco8.zip3.3 数据预处理增强针对热成像特点设计数据增强策略# data_augmentation.py import cv2 import numpy as np from PIL import Image, ImageEnhance class ThermalDataAugmentation: def __init__(self): self.augmentations [ self.adjust_contrast, self.adjust_brightness, self.gaussian_blur, self.thermal_noise ] def adjust_contrast(self, image, factor1.5): 增强热成像对比度 enhancer ImageEnhance.Contrast(Image.fromarray(image)) return np.array(enhancer.enhance(factor)) def adjust_brightness(self, image, factor1.2): 调整亮度 enhancer ImageEnhance.Brightness(Image.fromarray(image)) return np.array(enhancer.enhance(factor)) def gaussian_blur(self, image, kernel_size3): 高斯模糊模拟热成像模糊效应 return cv2.GaussianBlur(image, (kernel_size, kernel_size), 0) def thermal_noise(self, image, intensity0.01): 添加热噪声模拟真实热成像 noise np.random.normal(0, intensity, image.shape) noisy_image image noise * 255 return np.clip(noisy_image, 0, 255).astype(np.uint8) def apply_random_augmentation(self, image): 随机应用一种增强方法 aug_func np.random.choice(self.augmentations) return aug_func(image) # 使用示例 augmentor ThermalDataAugmentation() augmented_image augmentor.apply_random_augmentation(original_image)4. YOLOv8模型训练与优化4.1 模型选择与配置YOLOv8提供多种规模的预训练模型根据实际需求选择# model_config.py from ultralytics import YOLO class YOLOv8Config: # 模型规模选择 MODEL_SIZES { nano: yolov8n.pt, # 最轻量速度最快 small: yolov8s.pt, # 平衡型 medium: yolov8m.pt, # 精度较高 large: yolov8l.pt, # 高精度 xlarge: yolov8x.pt # 最高精度 } # 训练参数配置 TRAIN_CONFIG { epochs: 100, imgsz: 640, batch: 16, workers: 4, lr0: 0.01, # 初始学习率 lrf: 0.01, # 最终学习率 momentum: 0.937, # 动量 weight_decay: 0.0005, # 权重衰减 warmup_epochs: 3.0, # 热身轮数 warmup_momentum: 0.8,# 热身动量 box: 7.5, # 框损失权重 cls: 0.5, # 分类损失权重 dfl: 1.5 # DFL损失权重 } def select_model(sizemedium): 根据需求选择模型 model_name YOLOv8Config.MODEL_SIZES.get(size, yolov8m.pt) return YOLO(model_name)4.2 训练流程实现完整的模型训练流程# train_thermal_yolov8.py import os from ultralytics import YOLO import yaml class ThermalYOLOv8Trainer: def __init__(self, data_config, model_sizemedium): self.data_config data_config self.model YOLO(fyolov8{model_size[0]}.pt) # 加载预训练模型 def setup_training_config(self): 设置训练配置 config { data: self.data_config, epochs: 100, imgsz: 640, batch: 16, patience: 10, # 早停耐心值 save: True, exist_ok: False, # 不覆盖现有实验 pretrained: True, optimizer: auto, verbose: True, seed: 42, deterministic: True } return config def start_training(self): 开始训练 config self.setup_training_config() # 开始训练 results self.model.train( dataconfig[data], epochsconfig[epochs], imgszconfig[imgsz], batchconfig[batch], patienceconfig[patience], saveconfig[save], pretrainedconfig[pretrained], optimizerconfig[optimizer], verboseconfig[verbose], seedconfig[seed], deterministicconfig[deterministic] ) return results def evaluate_model(self): 模型评估 metrics self.model.val() print(fmAP50-95: {metrics.box.map:.4f}) print(fmAP50: {metrics.box.map50:.4f}) print(fPrecision: {metrics.box.precision:.4f}) print(fRecall: {metrics.box.recall:.4f}) return metrics # 使用示例 if __name__ __main__: trainer ThermalYOLOv8Trainer(thermal_data.yaml, medium) training_results trainer.start_training() evaluation_metrics trainer.evaluate_model()4.3 模型导出与优化训练完成后导出为不同格式以适应各种部署环境# model_export.py from ultralytics import YOLO class ModelExporter: def __init__(self, model_path): self.model YOLO(model_path) def export_onnx(self, output_path, simplifyTrue): 导出为ONNX格式 success self.model.export( formatonnx, imgsz640, simplifysimplify, opset12 ) return success def export_tensorrt(self, output_path): 导出为TensorRT引擎 success self.model.export( formatengine, imgsz640, device0 # GPU设备 ) return success def export_openvino(self, output_path): 导出为OpenVINO格式 success self.model.export( formatopenvino, imgsz640 ) return success def export_all_formats(self, base_name): 批量导出所有格式 formats [onnx, engine, openvino] results {} for fmt in formats: output_path f{base_name}.{fmt} try: success self.model.export(formatfmt, imgsz640) results[fmt] success print(f{fmt.upper()}导出{成功 if success else 失败}) except Exception as e: results[fmt] False print(f{fmt.upper()}导出失败: {e}) return results # 使用示例 exporter ModelExporter(runs/detect/train/weights/best.pt) exporter.export_all_formats(thermal_person_detector)5. 系统界面开发与集成5.1 PyQt5界面设计使用PyQt5开发用户友好的检测系统界面# thermal_ui.py import sys import cv2 from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QWidget, QFileDialog, QComboBox, QSlider, QSpinBox, QGroupBox, QTextEdit, QProgressBar) from PyQt5.QtCore import QTimer, Qt, pyqtSignal, QThread from PyQt5.QtGui import QImage, QPixmap from ultralytics import YOLO import numpy as np class DetectionThread(QThread): 检测线程避免界面卡顿 frame_processed pyqtSignal(np.ndarray, list) def __init__(self, model_path, camera_index0): super().__init__() self.model YOLO(model_path) self.camera_index camera_index self.is_running False self.cap None def run(self): 线程主循环 self.cap cv2.VideoCapture(self.camera_index) self.is_running True while self.is_running: ret, frame self.cap.read() if not ret: break # 执行检测 results self.model(frame, imgsz640, conf0.5) # 绘制检测结果 annotated_frame results[0].plot() # 获取检测信息 detections [] for box in results[0].boxes: detections.append({ class: results[0].names[int(box.cls)], confidence: float(box.conf), bbox: box.xyxy[0].tolist() }) # 发送处理后的帧和检测结果 self.frame_processed.emit(annotated_frame, detections) if self.cap: self.cap.release() def stop(self): 停止检测 self.is_running False class ThermalDetectionUI(QMainWindow): 热成像人员检测主界面 def __init__(self): super().__init__() self.detection_thread None self.init_ui() def init_ui(self): 初始化界面 self.setWindowTitle(YOLOv8热成像人员检测系统) self.setGeometry(100, 100, 1200, 800) # 中央窗口部件 central_widget QWidget() self.setCentralWidget(central_widget) # 主布局 main_layout QHBoxLayout() central_widget.setLayout(main_layout) # 左侧视频显示区域 left_layout QVBoxLayout() # 视频显示标签 self.video_label QLabel() self.video_label.setMinimumSize(800, 600) self.video_label.setStyleSheet(border: 2px solid gray;) self.video_label.setAlignment(Qt.AlignCenter) self.video_label.setText(视频显示区域) left_layout.addWidget(self.video_label) # 控制按钮 control_layout QHBoxLayout() self.start_btn QPushButton(开始检测) self.stop_btn QPushButton(停止检测) self.load_video_btn QPushButton(加载视频) self.snapshot_btn QPushButton(截图) self.start_btn.clicked.connect(self.start_detection) self.stop_btn.clicked.connect(self.stop_detection) self.load_video_btn.clicked.connect(self.load_video_file) self.snapshot_btn.clicked.connect(self.take_snapshot) control_layout.addWidget(self.start_btn) control_layout.addWidget(self.stop_btn) control_layout.addWidget(self.load_video_btn) control_layout.addWidget(self.snapshot_btn) left_layout.addLayout(control_layout) # 右侧信息面板 right_layout QVBoxLayout() # 检测设置组 settings_group QGroupBox(检测设置) settings_layout QVBoxLayout() # 置信度阈值设置 conf_layout QHBoxLayout() conf_layout.addWidget(QLabel(置信度阈值:)) self.conf_slider QSlider(Qt.Horizontal) self.conf_slider.setRange(10, 90) self.conf_slider.setValue(50) self.conf_value QLabel(0.5) conf_layout.addWidget(self.conf_slider) conf_layout.addWidget(self.conf_value) settings_layout.addLayout(conf_layout) # 模型选择 model_layout QHBoxLayout() model_layout.addWidget(QLabel(模型选择:)) self.model_combo QComboBox() self.model_combo.addItems([YOLOv8n, YOLOv8s, YOLOv8m, YOLOv8l]) self.model_combo.setCurrentIndex(2) model_layout.addWidget(self.model_combo) settings_layout.addLayout(model_layout) settings_group.setLayout(settings_layout) right_layout.addWidget(settings_group) # 检测结果组 results_group QGroupBox(检测结果) results_layout QVBoxLayout() self.results_text QTextEdit() self.results_text.setReadOnly(True) results_layout.addWidget(self.results_text) # 统计信息 stats_layout QHBoxLayout() stats_layout.addWidget(QLabel(检测人数:)) self.person_count QLabel(0) stats_layout.addWidget(self.person_count) stats_layout.addWidget(QLabel(平均置信度:)) self.avg_confidence QLabel(0.00) stats_layout.addWidget(self.avg_confidence) results_layout.addLayout(stats_layout) results_group.setLayout(results_layout) right_layout.addWidget(results_group) # 进度条 self.progress_bar QProgressBar() right_layout.addWidget(self.progress_bar) # 组合左右布局 main_layout.addLayout(left_layout, 3) main_layout.addLayout(right_layout, 1) def start_detection(self): 开始检测 if self.detection_thread and self.detection_thread.isRunning(): return model_map {YOLOv8n: yolov8n, YOLOv8s: yolov8s, YOLOv8m: yolov8m, YOLOv8l: yolov8l} selected_model model_map[self.model_combo.currentText()] self.detection_thread DetectionThread(f{selected_model}.pt) self.detection_thread.frame_processed.connect(self.update_frame) self.detection_thread.start() def stop_detection(self): 停止检测 if self.detection_thread: self.detection_thread.stop() self.detection_thread.wait() def update_frame(self, frame, detections): 更新视频帧显示 # 转换OpenCV BGR到Qt RGB rgb_image cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch rgb_image.shape bytes_per_line ch * w qt_image QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888) # 缩放图像适应显示区域 pixmap QPixmap.fromImage(qt_image) scaled_pixmap pixmap.scaled(self.video_label.size(), Qt.KeepAspectRatio) self.video_label.setPixmap(scaled_pixmap) # 更新检测结果 self.update_detection_results(detections) def update_detection_results(self, detections): 更新检测结果显示 person_detections [d for d in detections if d[class] person] self.person_count.setText(str(len(person_detections))) if person_detections: avg_conf sum(d[confidence] for d in person_detections) / len(person_detections) self.avg_confidence.setText(f{avg_conf:.3f}) else: self.avg_confidence.setText(0.00) # 更新文本显示 results_text f检测到 {len(person_detections)} 个人员\n\n for i, detection in enumerate(person_detections, 1): results_text f人员 {i}: 置信度 {detection[confidence]:.3f}\n self.results_text.setText(results_text) def load_video_file(self): 加载视频文件 file_path, _ QFileDialog.getOpenFileName( self, 选择视频文件, , 视频文件 (*.mp4 *.avi *.mov)) if file_path: # 实现视频文件加载逻辑 pass def take_snapshot(self): 截图功能 # 实现截图保存逻辑 pass def main(): app QApplication(sys.argv) window ThermalDetectionUI() window.show() sys.exit(app.exec_()) if __name__ __main__: main()5.2 实时视频流处理实现热成像相机视频流接入和处理# video_stream.py import cv2 import threading import time from queue import Queue class ThermalCameraStream: 热成像相机流处理类 def __init__(self, source0, model_pathyolov8m.pt): self.source source self.model YOLO(model_path) self.cap cv2.VideoCapture(source) self.frame_queue Queue(maxsize10) self.detection_queue Queue(maxsize10) self.is_running False self.threads [] # 相机参数设置根据具体热成像相机调整 self.setup_camera() def setup_camera(self): 设置热成像相机参数 if self.cap.isOpened(): # 设置分辨率根据相机支持调整 self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 设置帧率 self.cap.set(cv2.CAP_PROP_FPS, 30) def start_stream(self): 开始视频流处理 self.is_running True # 创建帧捕获线程 capture_thread threading.Thread(targetself.capture_frames) capture_thread.daemon True capture_thread.start() self.threads.append(capture_thread) # 创建检测线程 detection_thread threading.Thread(targetself.process_detections) detection_thread.daemon True detection_thread.start() self.threads.append(detection_thread) def capture_frames(self): 捕获视频帧 while self.is_running: ret, frame self.cap.read() if ret: # 如果队列已满丢弃最旧的帧 if self.frame_queue.full(): try: self.frame_queue.get_nowait() except: pass self.frame_queue.put(frame) time.sleep(0.01) # 控制捕获频率 def process_detections(self): 处理目标检测 while self.is_running: if not self.frame_queue.empty(): frame self.frame_queue.get() # 执行YOLOv8检测 results self.model(frame, imgsz640, conf0.5) # 获取检测结果 detections [] for box in results[0].boxes: detections.append({ class: results[0].names[int(box.cls)], confidence: float(box.conf), bbox: box.xyxy[0].tolist() }) # 绘制检测结果 annotated_frame results[0].plot() # 放入结果队列 if self.detection_queue.full(): try: self.detection_queue.get_nowait() except: pass self.detection_queue.put((annotated_frame, detections)) def get_latest_detection(self): 获取最新的检测结果 if not self.detection_queue.empty(): return self.detection_queue.get() return None, [] def stop_stream(self): 停止视频流 self.is_running False if self.cap: self.cap.release() # 等待线程结束 for thread in self.threads: thread.join(timeout1.0) # 使用示例 def demo_thermal_stream(): stream ThermalCameraStream(source0) # 0为默认相机 stream.start_stream() try: while True: frame, detections stream.get_latest_detection() if frame is not None: cv2.imshow(Thermal Detection, frame) # 显示检测信息 person_count len([d for d in detections if d[class] person]) print(f检测到 {person_count} 个人员) if cv2.waitKey(1) 0xFF ord(q): break finally: stream.stop_stream() cv2.destroyAllWindows()6. 系统部署与性能优化6.1 模型量化与加速针对边缘设备部署进行模型优化# model_optimization.py import torch from ultralytics import YOLO import onnxruntime as ort class ModelOptimizer: def __init__(self, model_path): self.model YOLO(model_path) def quantize_model(self, output_path): 模型量化减小尺寸 # 加载模型 model torch.jit.load(self.model) # 动态量化 quantized_model torch.quantization.quantize_dynamic( model, {torch.nn.Linear}, dtypetorch.qint8 ) # 保存量化模型 torch.jit.save(quantized_model, output_path) return output_path def optimize_for_inference(self): 推理优化 # 设置模型为评估模式 self.model.eval() # 启用推理优化 with torch.no_grad(): # 使用torch.jit.trace优化 example_input torch.rand(1, 3, 640, 640) traced_model torch.jit.trace(self.model, example_input) return traced_model def benchmark_performance(self, test_data, iterations100): 性能基准测试 model self.optimize_for_inference() # Warmup for _ in range(10): _ model(test_data) # 基准测试 start_time torch.cuda.Event(enable_timingTrue) end_time torch.cuda.Event(enable_timingTrue) start_time.record() for _ in range(iterations): _ model(test_data) end_time.record() torch.cuda.synchronize() inference_time start_time.elapsed_time(end_time) / iterations print(f平均推理时间: {inference_time:.2f}ms) print(f帧率: {1000/inference_time:.2f}FPS) return inference_time class ONNXInference: ONNX运行时推理优化 def __init__(self, onnx_path): self.session ort.InferenceSession(onnx_path) self.providers [CUDAExecutionProvider, CPUExecutionProvider] def optimize_session(self): 优化推理会话 # 设置优化选项 options self.session.get_provider_options() # CUDA优化设置 if CUDAExecutionProvider in self.providers: options[CUDAExecutionProvider] { arena_extend_strategy: kNextPowerOfTwo, cudnn_conv_algo_search: EXHAUSTIVE, do_copy_in_default_stream: True, } return self.session def inference(self, input_data): 执行推理 input_name self.session.get_inputs()[0].name output_name self.session.get_outputs()[0].name results self.session.run([output_name], {input_name: input_data}) return results6.2 多线程处理架构设计高效的多线程处理架构# multi_thread_processing.py import threading import queue import time from concurrent.futures import ThreadPoolExecutor import cv2 class PipelineProcessor: 流水线处理器 def __init__(self, model_path, num_workers4): self.model_path model_path self.num_workers num_workers self.input_queue queue.Queue(maxsize20) self.output_queue queue.Queue(maxsize20) self.is_running False self.workers [] def start_processing(self): 启动处理流水线 self.is_running True # 创建工作线程池 with ThreadPoolExecutor(max_workersself.num_workers) as executor: while self.is_running: try: # 从输入队列获取帧 frame_data self.input_queue.get(timeout1.0) if frame_data is None: # 停止信号 break # 提交检测任务 future executor.submit(self.process_frame, frame_data) future.add_done_callback(self.on_processing_done) except queue.Empty: continue def process_frame(self, frame_data): 处理单帧图像 frame, frame_id frame_data # 执行YOLOv8检测 from ultralytics import YOLO model YOLO(self.model_path) results model(frame, imgsz640, conf0.5) # 提取检测结果 detections [] for box in results[0].boxes: detections.append({ class: results[0].names[int(box.cls)], confidence: float(box.conf), bbox: box.xyxy[0].tolist() }) annotated_frame results[0].plot() return annotated_frame, detections, frame_id def on_processing_done(self, future): 处理完成回调 try: result future.result() self.output_queue.put(result) except Exception as e: print(f处理失败: {e}) def add_frame(self, frame, frame_id): 添加帧到处理队列 if self.input_queue.full(): # 队列满时丢弃最旧的帧 try: self.input_queue.get_nowait() except queue.Empty: pass self.input_queue.put((frame, frame_id)) def get_result(self): 获取处理结果 try: return self.output_queue.get_nowait() except queue.Empty: return None def stop_processing(self): 停止处理 self.is_running False self.input_queue.put(None) # 发送停止信号 # 使用示例 class ThermalDetectionSystem: 完整的检测系统 def __init__(self, model_path, camera_source0): self.camera_source camera_source self.processor PipelineProcessor(model_path) self.cap cv2.VideoCapture(camera_source) self.is_running False def start_system(self): 启动系统 self.is_running True self.processor.start_processing() frame_id 0 while self.is_running: ret, frame self.cap.read() if ret: self.processor.add_frame(frame, frame_id) frame_id 1 # 获取并显示结果 result self.processor.get_result() if result: annotated_frame, detections, fid result cv2.imshow(Thermal Detection, annotated_frame) # 显示检测统计 person_count len([d for d in detections if d[class] person]) print(f帧 {fid}: 检测到 {person_count} 人) if cv2.waitKey(1) 0xFF ord(q): break self.stop_system() def stop_system(self): 停止系统 self.is_running False self.processor.stop_processing() if self.cap: self.cap.release() cv2.destroyAllWindows()7. 常见问题与解决方案7.1 环境配置问题问题1CUDA out of memory错误解决方案# 方法1减小批处理大小 model.train(batch8) # 从16减小到8 # 方法2使用梯度累积 model.train(batch8, accumulate2) # 等效批大小16 # 方法3启用混合精度训练 model.train(ampTrue) #
