第19章:基于efficientNet实现的视频内容识别系统
目录
1.efficientNet 网络
2. 猫和老鼠
3. QT推理
4. 项目
1.efficientNet 网络
本章做了一个视频内容识别的系统
本文选用的模型是efficientNet b0版本
EfficientNet 是 Google 团队在 2019 年提出的一系列高效卷积神经网络模型,其核心思想是通过复合缩放(Compound Scaling)方法平衡网络的深度(depth)、宽度(width)和分辨率(resolution),从而在计算资源受限的条件下实现更高的性能。EfficientNet-B0 是该系列的基础模型,后续版本(B1-B7)基于 B0 进行缩放。
EfficientNet-B0 的核心设计
1. 基础架构:MobileNet-like + 优化
EfficientNet-B0 的骨干网络基于反向残差块(MBConv,Mobile Inverted Bottleneck),类似 MobileNetV2,但通过神经架构搜索(NAS)优化了层结构和连接方式。主要特点包括:
-
MBConv 模块:包含扩展(expansion)、深度可分离卷积(depthwise convolution)和压缩(squeeze-and-excitation)操作。
-
扩展层:先用 1x1 卷积扩展通道数(通常扩展比为 6)。
-
深度可分离卷积:3x3 或 5x5 的逐通道卷积,减少计算量。
-
SE 注意力机制:压缩激励(Squeeze-and-Excitation)模块动态调整通道权重。
-
残差连接:当输入输出维度相同时引入。
-
2. 复合缩放(Compound Scaling)
EfficientNet 提出统一的缩放规则,同时调整三个维度:
-
深度(d):网络层数,通过重复堆叠 MBConv 实现。
-
宽度(w):每层的通道数。
-
分辨率(r):输入图像的分辨率(如 224x224 → 更高分辨率)。
缩放公式:
depth:d=αϕ,width:w=βϕ,resolution:r=γϕ
其中 α,β,γα,β,γ 是通过网格搜索确定的基础缩放系数(B0 的 ϕ=1)。
EfficientNet-B0 的具体结构
以下是 B0 的详细层结构(输入分辨率 224x224):
Stage | Operator | Resolution | Channels | Layers |
---|---|---|---|---|
1 | Conv3x3 | 224x224 | 32 | 1 |
2 | MBConv1 (k3x3, stride1) | 112x112 | 16 | 1 |
3 | MBConv6 (k3x3, stride2) | 112x112 | 24 | 2 |
4 | MBConv6 (k5x5, stride2) | 56x56 | 40 | 2 |
5 | MBConv6 (k3x3, stride2) | 28x28 | 80 | 3 |
6 | MBConv6 (k5x5, stride1) | 14x14 | 112 | 3 |
7 | MBConv6 (k5x5, stride2) | 14x14 | 192 | 4 |
8 | MBConv6 (k3x3, stride1) | 7x7 | 320 | 1 |
9 | Conv1x1 + Pooling + FC | 7x7 | 1280 | 1 |
-
k:卷积核大小,stride:步长,MBConv6:扩展比为 6 的 MBConv 模块。
-
最后一层使用 1x1 卷积升维到 1280 通道,接全局平均池化和全连接分类层。
关键创新点
-
MBConv + SE 模块:
-
深度可分离卷积减少计算量。
-
SE 模块(通道注意力)提升特征表达能力。
-
-
复合缩放:
-
平衡深度、宽度、分辨率,避免单一维度的过度缩放导致性能饱和。
-
-
神经架构搜索(NAS):
-
基于 AutoML 搜索最优的基础结构(B0),再通过缩放得到 B1-B7。
-
性能对比
-
参数量:B0 仅 5.3M 参数,比 ResNet-50(25.5M)少 5 倍。
-
准确率:在 ImageNet 上达到 77.1% top-1 准确率(ResNet-50 为 76%),FLOPs 仅 0.39B。
应用场景
-
移动端/边缘设备:因低计算开销和高效率。
-
迁移学习:作为特征提取器用于下游任务(如检测、分割)。
代码实现(PyTorch 示例)
import torch
from efficientnet_pytorch import EfficientNetmodel = EfficientNet.from_pretrained('efficientnet-b0')
input = torch.randn(1, 3, 224, 224)
output = model(input)
print(output.shape) # [1, 1000]
EfficientNet-B0 通过智能设计和缩放策略,实现了在小模型中的卓越性能,成为轻量级网络的标杆之一。后续的 EfficientNetV2 进一步优化了训练速度和精度。
2. 猫和老鼠
数据集这里用的是猫和老鼠的例子:
训练参数在这里:
parser.add_argument("--model", default='b0', type=str,help='b0')parser.add_argument("--pretrained", default=False, type=bool) # 采用官方权重parser.add_argument("--freeze_layers", default=False, type=bool) # 冻结权重parser.add_argument("--batch-size", default=8, type=int)parser.add_argument("--epochs", default=200, type=int)parser.add_argument("--optim", default='Adam', type=str,help='SGD,Adam,AdamW') # 优化器选择parser.add_argument('--lr', default=0.001, type=float)parser.add_argument('--lrf',default=0.001,type=float) # 最终学习率 = lr * lrfparser.add_argument('--save_ret', default='runs', type=str) # 保存结果parser.add_argument('--data_train',default='./data/train',type=str) # 训练集路径parser.add_argument('--data_val',default='./data/val',type=str) # 测试集路径
这里不多介绍了,大概训练的流程和本专栏的差不多
最后一个epoch:
"epoch:199": {"train info": {"accuracy": 0.9873817034388839,"Jerry": {"Precision": 0.9798,"Recall": 1.0,"Specificity": 0.9909,"F1 score": 0.9898},"Tom": {"Precision": 0.9944,"Recall": 0.9889,"Specificity": 0.9927,"F1 score": 0.9916},"Tom and Jerry": {"Precision": 0.9744,"Recall": 0.95,"Specificity": 0.9964,"F1 score": 0.962},"mean precision": 0.9828666666666667,"mean recall": 0.9796333333333335,"mean specificity": 0.9933333333333333,"mean f1 score": 0.9811333333333333},"valid info": {"accuracy": 0.7619047617838246,"Jerry": {"Precision": 0.8333,"Recall": 0.9091,"Specificity": 0.9024,"F1 score": 0.8696},"Tom": {"Precision": 0.7187,"Recall": 0.8846,"Specificity": 0.7568,"F1 score": 0.7931},"Tom and Jerry": {"Precision": 0.7143,"Recall": 0.3333,"Specificity": 0.9583,"F1 score": 0.4545},"mean precision": 0.7554333333333334,"mean recall": 0.7090000000000001,"mean specificity": 0.8725,"mean f1 score": 0.7057333333333333}
3. QT推理
运行结果:
生成的视频:
视频检测记录:
代码参考:
import os
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,QPushButton, QLabel, QFileDialog, QCheckBox, QWidget,QProgressBar, QMessageBox, QGroupBox, QSpacerItem,QSizePolicy)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QImage, QPixmap, QFont
import cv2
from PIL import Image
from openpyxl import Workbook
from openpyxl.styles import Font
import datetime
import torch
import torchvision.models as m
from torchvision import transformsdef create_model(model,num,weights):net = m.efficientnet_b0(weights=m.EfficientNet_B0_Weights.DEFAULT if weights else False,progress=True)tmp = list(net.classifier)[-1].in_featuresnet.classifier = torch.nn.Linear(tmp,num,bias=True)return netdef data_trans(train_mean=[0.485, 0.456, 0.406], train_std=[0.229, 0.224, 0.225]):train_transform = transforms.Compose([transforms.Resize(256),transforms.RandomRotation(90), # 随机旋转transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(train_mean, train_std)])test_transform = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(train_mean, train_std)])return train_transform,test_transformdef get_device():device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print("Using device is: ", device)return deviceclass VideoProcessor(QThread):update_frame = pyqtSignal(QImage)update_progress = pyqtSignal(int)finished_processing = pyqtSignal(str, str) # 修改为返回两个路径error_occurred = pyqtSignal(str)def __init__(self, video_path, save_video, save_excel):super().__init__()self.video_path = video_pathself.save_video = save_videoself.save_excel = save_excelself.running = Truedef run(self):output_video_path = ""output_excel_path = ""try:device = get_device()_, data_transform = data_trans()labels = {"0": "Jerry","1": "Tom","2": "Tom and Jerry"}# 创建模型net = create_model(model='b0', num=len(labels), weights=False)net.load_state_dict(torch.load('./runs/weights/best.pth'), strict=False)net.to(device)net.eval()# 视频输入cap = cv2.VideoCapture(self.video_path)if not cap.isOpened():self.error_occurred.emit("无法打开视频文件")return# 获取视频信息fps = cap.get(cv2.CAP_PROP_FPS)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))# 创建Excel工作簿(如果需要)if self.save_excel:wb = Workbook()ws = wb.activews.title = "Video Classification Results"headers = ["时间范围(秒)", "识别类别"]for col, header in enumerate(headers, 1):ws.cell(row=1, column=col, value=header).font = Font(bold=True)# 创建视频输出(如果需要)if self.save_video:timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")output_video_path = os.path.splitext(self.video_path)[0] + f"_output_{timestamp}.mp4"fourcc = cv2.VideoWriter_fourcc(*'mp4v')out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))current_second = -1row_idx = 2last_class = Nonestart_time = 0end_time = 0frame_count = 0with torch.no_grad():while self.running and cap.isOpened():ret, frame = cap.read()if not ret:if last_class is not None and self.save_excel:time_range = f"{start_time}~{end_time}" if start_time != end_time else str(start_time)ws.cell(row=row_idx, column=1, value=time_range)ws.cell(row=row_idx, column=2, value=last_class)breakframe_count += 1progress = int((frame_count / total_frames) * 100)self.update_progress.emit(progress)current_time = frame_count / fpssecond = int(current_time)# 转换帧为PIL Image并进行预处理pil_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))img = data_transform(pil_img)img = torch.unsqueeze(img, dim=0)# 预测output = net(img.to(device))output = torch.softmax(output, dim=1)p, index = torch.topk(output, k=3)current_class = labels[str(index.to("cpu").numpy()[0][0])]# 在左上角显示三个类别的概率text_y = 30for i in range(3):class_idx = index.to("cpu").numpy()[0][i]class_name = labels[str(class_idx)]prob = p.to("cpu").numpy()[0][i]text = f'{class_name}: {prob:.4f}'cv2.putText(frame, text, (10, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)text_y += 30# 每秒检查一次结果if second != current_second:current_second = secondif current_class != last_class:if last_class is not None and self.save_excel:time_range = f"{start_time}~{end_time}" if start_time != end_time else str(start_time)ws.cell(row=row_idx, column=1, value=time_range)ws.cell(row=row_idx, column=2, value=last_class)row_idx += 1start_time = secondlast_class = current_classend_time = second# 转换为Qt图像并发送rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)h, w, ch = rgb_image.shapebytes_per_line = ch * wqt_image = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888)self.update_frame.emit(qt_image)# 保存结果(如果需要)if self.save_video:out.write(frame)# 保存Excel文件if self.save_excel:timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")output_excel_path = os.path.splitext(self.video_path)[0] + f"_classification_{timestamp}.xlsx"wb.save(output_excel_path)# 释放资源cap.release()if self.save_video:out.release()self.finished_processing.emit(output_video_path, output_excel_path)except Exception as e:self.error_occurred.emit(f"处理过程中发生错误: {str(e)}")def stop(self):self.running = Falseclass VideoClassifierApp(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("智能视频分类工具")self.setGeometry(100, 100, 900, 700)self.setMinimumSize(800, 600)self.video_path = ""self.init_ui()self.processor = Nonedef init_ui(self):main_widget = QWidget()main_layout = QVBoxLayout()main_layout.setContentsMargins(15, 15, 15, 15)main_layout.setSpacing(15)# 文件选择区域file_group = QGroupBox("视频文件选择")file_layout = QHBoxLayout()file_layout.setContentsMargins(10, 10, 10, 10)self.video_label = QLabel("未选择视频文件")self.video_label.setStyleSheet("QLabel { padding: 5px; }")self.video_label.setMinimumWidth(300)self.browse_button = QPushButton("选择视频")self.browse_button.setFixedWidth(120)self.browse_button.setStyleSheet("QPushButton { padding: 5px; font-weight: bold; }""QPushButton:hover { background-color: #e0e0e0; }")self.browse_button.clicked.connect(self.browse_video)file_layout.addWidget(self.video_label)file_layout.addWidget(self.browse_button)file_group.setLayout(file_layout)main_layout.addWidget(file_group)# 选项区域options_group = QGroupBox("输出选项")options_layout = QHBoxLayout()options_layout.setContentsMargins(10, 10, 10, 10)self.save_video_check = QCheckBox("保存识别结果视频")self.save_video_check.setChecked(True)self.save_video_check.setStyleSheet("QCheckBox { padding: 5px; }")self.save_excel_check = QCheckBox("保存Excel分类结果")self.save_excel_check.setChecked(True)self.save_excel_check.setStyleSheet("QCheckBox { padding: 5px; }")options_layout.addWidget(self.save_video_check)options_layout.addWidget(self.save_excel_check)options_group.setLayout(options_layout)main_layout.addWidget(options_group)# 视频显示区域display_group = QGroupBox("视频预览")display_layout = QVBoxLayout()display_layout.setContentsMargins(10, 10, 10, 10)self.video_display = QLabel()self.video_display.setAlignment(Qt.AlignCenter)self.video_display.setMinimumSize(640, 360)self.video_display.setStyleSheet("QLabel { background-color: black; border: 1px solid #ccc; }")display_layout.addWidget(self.video_display)display_group.setLayout(display_layout)main_layout.addWidget(display_group)# 进度条区域self.progress_bar = QProgressBar()self.progress_bar.setStyleSheet("QProgressBar { height: 20px; text-align: center; }""QProgressBar::chunk { background-color: #4CAF50; }")main_layout.addWidget(self.progress_bar)# 按钮区域button_layout = QHBoxLayout()button_layout.setSpacing(20)spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)button_layout.addItem(spacer)self.start_button = QPushButton("开始分类")self.start_button.setFixedWidth(150)self.start_button.setStyleSheet("QPushButton { padding: 8px; font-weight: bold; background-color: #4CAF50; color: white; }""QPushButton:hover { background-color: #45a049; }""QPushButton:disabled { background-color: #cccccc; }")self.start_button.clicked.connect(self.start_processing)self.stop_button = QPushButton("停止")self.stop_button.setFixedWidth(150)self.stop_button.setStyleSheet("QPushButton { padding: 8px; font-weight: bold; background-color: #f44336; color: white; }""QPushButton:hover { background-color: #d32f2f; }""QPushButton:disabled { background-color: #cccccc; }")self.stop_button.clicked.connect(self.stop_processing)self.stop_button.setEnabled(False)button_layout.addWidget(self.start_button)button_layout.addWidget(self.stop_button)button_layout.addItem(spacer)main_layout.addLayout(button_layout)# 状态栏self.status_bar = QLabel()self.status_bar.setStyleSheet("QLabel { color: #666666; font-style: italic; border-top: 1px solid #eeeeee; padding: 5px; }")self.update_status("准备就绪")main_layout.addWidget(self.status_bar)main_widget.setLayout(main_layout)self.setCentralWidget(main_widget)def browse_video(self):file_path, _ = QFileDialog.getOpenFileName(self,"选择视频文件","","视频文件 (*.mp4 *.avi *.mov);;所有文件 (*.*)")if file_path:self.video_path = file_pathself.video_label.setText(os.path.basename(file_path))self.update_status(f"已选择视频: {os.path.basename(file_path)}")def start_processing(self):if not self.video_path:QMessageBox.warning(self, "警告", "请先选择视频文件")returnself.start_button.setEnabled(False)self.stop_button.setEnabled(True)self.browse_button.setEnabled(False)self.update_status("正在处理视频...")self.processor = VideoProcessor(self.video_path,self.save_video_check.isChecked(),self.save_excel_check.isChecked())self.processor.update_frame.connect(self.update_frame)self.processor.update_progress.connect(self.update_progress)self.processor.finished_processing.connect(self.processing_finished)self.processor.error_occurred.connect(self.show_error)self.processor.start()def stop_processing(self):if self.processor:self.processor.stop()self.processor = Noneself.reset_ui()self.update_status("处理已停止")def update_frame(self, image):pixmap = QPixmap.fromImage(image)self.video_display.setPixmap(pixmap.scaled(self.video_display.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))def update_progress(self, value):self.progress_bar.setValue(value)self.update_status(f"处理中... {value}% 完成")def processing_finished(self, video_path, excel_path):self.reset_ui()message = "处理完成!"if video_path:message += f"\n视频已保存到: {video_path}"if excel_path:message += f"\nExcel已保存到: {excel_path}"self.update_status(message)QMessageBox.information(self, "完成", message)def show_error(self, message):self.reset_ui()self.update_status(f"错误: {message}")QMessageBox.critical(self, "错误", message)def reset_ui(self):self.start_button.setEnabled(True)self.stop_button.setEnabled(False)self.browse_button.setEnabled(True)self.progress_bar.setValue(0)def update_status(self, message):self.status_bar.setText(f"状态: {message}")def closeEvent(self, event):if self.processor and self.processor.isRunning():self.processor.stop()self.processor.wait()event.accept()if __name__ == '__main__':os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'app = QApplication(sys.argv)# 设置全局字体font = QFont()font.setFamily("Microsoft YaHei")font.setPointSize(10)app.setFont(font)window = VideoClassifierApp()window.show()sys.exit(app.exec_())
4. 项目
下载地址:猫和老鼠
关于图像分类、分割网络的改进:图像分类网络改进_听风吹等浪起的博客-CSDN博客
相关文章:
第19章:基于efficientNet实现的视频内容识别系统
目录 1.efficientNet 网络 2. 猫和老鼠 3. QT推理 4. 项目 1.efficientNet 网络 本章做了一个视频内容识别的系统 本文选用的模型是efficientNet b0版本 EfficientNet 是 Google 团队在 2019 年提出的一系列高效卷积神经网络模型,其核心思想是通过复合缩放&…...
【Java面试系列】Spring Cloud微服务架构中的分布式事务解决方案与Seata框架实现原理详解 - 3-5年Java开发必备知识
【Java面试系列】Spring Cloud微服务架构中的分布式事务解决方案与Seata框架实现原理详解 - 3-5年Java开发必备知识 引言 在微服务架构中,分布式事务是一个不可避免的挑战。随着业务复杂度的提升,如何保证跨服务的数据一致性成为了面试中的高频问题。本…...
div(HTML标准元素)和view(微信小程序专用组件)的主要区别体
div(HTML标准元素)和view(微信小程序专用组件)的主要区别体现在以下方面: 一、应用场景与开发框架 适用平台不同 div是HTML/CSS开发中通用的块级元素,用于Web页面布局;view是微信小程序专…...
AI在多Agent协同领域的核心概念、技术方法、应用场景及挑战 的详细解析
以下是 AI在多Agent协同领域的核心概念、技术方法、应用场景及挑战 的详细解析: 1. 多Agent协同的定义与核心目标 多Agent系统(MAS, Multi-Agent System): 由多个独立或协作的智能体(Agent)组成ÿ…...
03_Americanas精益管理项目_StarRocks
文章目录 03_StarRocks(一)StarRocks简介1、什么是StarRocks【理解】1)概述2)适用场景2、系统架构【理解】1)系统架构图2)数据管理3、使用【熟悉】(二)表设计4、StarRocks表设计【理解】1)列式存储2)索引3)加速处理5、数据模型【掌握】5-1 明细模型1)适用场景2)创…...
CSS进度条带斑马纹动画(有效果图)
效果图 .wxml <view class"tb"><view class"tb-line" style"transform:translateX({{w%}})" /> </view> <button bind:tap"updateLine">增加进度</button>.js Page({data: {w:0,},updateLine(){this.…...
C++ static的使用方法及不同作用
在 C 里,static 是一个用途广泛的关键字,在不同场景下有不同含义,下面为你详细介绍: 1. 全局变量前的 static 当 static 用在全局变量前时,它会改变变量的链接属性。 默认全局变量:默认的全局变量具有外…...
CSS 美化页面(四)
一、浮动float属性 属性值描述适用场景left元素向左浮动,腾出右侧空间供其他元素使用,其他内容会围绕在其右侧。横向排列元素(如导航菜单)、图文混排布局。right元素向右浮动,腾出左侧空间供其他元素使…...
驱动-原子操作
前面 对并发与竞争进行了实验, 两个 app 应用程序之间对共享资源的竞争访问引起了数据传输错误, 而在 Linux 内核中, 提供了四种处理并发与竞争的常见方法: 分别是原子操作、 自旋锁、 信号量、 互斥体, 这里了解下原子…...
Flutter ListView 详解
ListView 是 Flutter 中用于构建滚动列表的核心组件,支持垂直、水平滚动以及复杂的动态布局。本文将深入解析其核心用法、性能优化策略和高级功能实现,助你打造流畅高效的列表界面。 一、基础篇:快速构建各类列表 1. 垂直列表(默…...
关于视频的一些算法内容,不包含代码等
视频算法: 视频降噪, 去除视频中的噪音,提高图像质量 工作原理: 时域降噪:利用相邻帧之间的相似性,通过平均或滤波来减少随机噪声。 空域降噪:在单帧内使用滤波器(高斯滤波器&am…...
OpenCV 图形API(43)颜色空间转换-----将 BGR 图像转换为 LUV 色彩空间函数BGR2LUV()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将图像从BGR色彩空间转换为LUV色彩空间。 该函数将输入图像从BGR色彩空间转换为LUV。B、G和R通道值的传统范围是0到255。 输出图像必须是8位无符…...
keil报错 ..\..\Libraries\CMSIS\stm32f10x.h(298): error: #67: expected a “}“
报错原因: 通常是由于启动文件、头文件定义或驱动选择不一致导致的。以下是一些具体的解决方案,可以帮助你解决这个问题: 检查步骤: 1. 检查启动文件 确保你的启动文件与你的芯片型号相匹配。例如,如果你的芯片是S…...
图像预处理-添加水印
一.ROI切割 类似裁剪图片,但是原理是基于Numpy数组的切片操作(ROI数组切片是会修改原图数据的),也就是说这个“裁剪”不是为了保存“裁剪”部分,而是为了方便修改等处理。 import cv2 as cv import numpy as npimg cv.imread(../images/dem…...
扩展欧几里得算法【Exgcd】的内容与题目应用
1.简介 exgcd的目的是表示出二元一次不定方程的通解。 形式化地,exgcd算法就是输入a,b,c的值,返回一组x,y,满足 a x b y c axbyc axbyc。 2.1方程无整数解的情况 当 c 不能被 a ,b最小公倍…...
OpenCV day5
函数内容接上文:OpenCV day4-CSDN博客 目录 9.cv2.adaptiveThreshold(): 10.cv2.split(): 11.cv2.merge(): 12.cv2.add(): 13.cv2.subtract(): 14.cv2.multiply(): 15.cv2.divide(): 1…...
Spring DI 详解
学习过 IoC 后,就知道我们可以将对象交给 Spring 进行管理,但是我们在一个类会有若干属性,也就是这个类依赖于这若干个属性,那么我们就可以将交给 Spring 管理的对象注入到这个类中,这也就是依赖注入。 依赖注入有三种…...
解锁动态规划的奥秘:从零到精通的创新思维解析(9)
前言: 小编在前几日写了关于动态规划中的多状态dp的问题,此时小编将会讲述一个动态规划我们常常会遇到的一类问题——股票问题,股票问题就类似小编上一篇所讲述的粉刷房子的问题,可以通过一个二维的dp表来代替多个一维的dp表。买卖…...
redis 配置日志和数据存储位置
Redis配置日志和数据存储位置 介绍 Redis是一个开源的高性能键值存储数据库,常用于缓存、消息队列和实时分析等场景。在使用Redis时,我们需要配置日志和数据存储位置,以便更好地管理和监控Redis的运行状态。本文将介绍如何配置Redis的日志和数…...
STL详解 - stack与queue的模拟实现
目录 一、容器适配器 1. 什么是适配器模式 2. stack与queue的底层结构 3. deque的原理与缺陷 3.1 deque的原理 3.2 deque的缺陷 4. 为何选择deque作为默认底层容器 二、stack与queue的模拟实现 1. stack的实现 2. queue的实现 一、容器适配器 1. 什么是适配器模式 适…...
Chromium 134 编译指南 macOS篇:获取源代码(四)
1. 引言 在Chromium 134的开发之旅中,获取源代码是一个至关重要的里程碑。本文将引导您完成这一关键步骤,为后续的编译和开发工作奠定坚实的基础。无论您是出于学习目的,还是计划开发自己的浏览器项目,掌握获取Chromium源码的方法…...
关于 IntelliJ IDEA 中频繁出现的 Kotlin 及其核心作用
关于 IntelliJ IDEA 中频繁出现的 Kotlin 及其核心作用 1. Kotlin 是什么? Kotlin 是由 JetBrains(IntelliJ IDEA 的开发商)设计的一种现代化编程语言,2016年正式发布,2017年被 Google 指定为 Android 官方开发语言。…...
MYOJ_11700(UVA10591)Happy Number(快乐数)(超快解法:图论思想解题)
原题(English) Let the sum of the square of the digits of a positive integer S0S0 be represented by S1S1. In a similar way, let the sum of the squares of the digits of S1S1 be represented by S2S2 and so on. If Si1Si1 for some i≥1i≥1, then the or…...
2843. 统计对称整数的数目
2843. 统计对称整数的数目 题目链接:2843. 统计对称整数的数目 代码如下: class Solution { public:int countSymmetricIntegers(int low, int high) {int res 0;for (int i low;i < high;i) {string s to_string(i);int n s.size();if (n % 2 …...
【模块化拆解与多视角信息6】自我评价:人设构建的黄金50字——从无效堆砌到精准狙击的认知升级
写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...
ServletRequestAttributeListener 的用法笔记250417
ServletRequestAttributeListener 的用法笔记250417 以下是关于 ServletRequestAttributeListener 的用法详解,涵盖核心方法、实现步骤、典型应用场景及注意事项,帮助您有效监听请求级别属性(ServletRequest 中的属性)的变化&…...
大模型在胃十二指肠溃疡预测及诊疗方案制定中的应用研究
目录 一、引言 1.1 研究背景与目的 1.2 国内外研究现状 1.3 研究方法和创新点 二、大模型相关理论基础 2.1 大模型的基本原理 2.2 适用于医疗领域的大模型类型 2.3 大模型在医疗领域的应用现状和潜力 三、胃十二指肠溃疡的疾病特征 3.1 疾病概述 3.2 诊断方法 3.3 …...
第九节:React HooksReact 18+新特性-React 19的use钩子如何简化异步操作?
对比:useEffect vs use处理Promise 代码题:用use改写数据请求逻辑 React 19 use 钩子:异步操作革命性简化方案(附完整代码对比) 一、useEffect vs use 处理 Promise 核心差异对比 对比维度useEffect 方案use 钩子方案…...
【React】项目的搭建
create-react-app 搭建vite 搭建相关下载 在Vue中搭建项目的步骤:1.首先安装脚手架的环境,2.通过脚手架的指令创建项目 在React中有两种方式去搭建项目:1.和Vue一样,先安装脚手架然后通过脚手架指令搭建;2.npx create-…...
方案精读:华为数字化转型实践案例合集【附全文阅读】
华为数字化转型旨在通过数字化变革实现全连接的智能华为,成为行业标杆,提升客户满意度和运营效率。其以客户为中心,基于 “双轮驱动” 理念,从转意识、方法、文化、组织、模式等方面入手,构建数字化平台,推进数据治理,保障安全,开展业务重构。通过合同 360、产品设计与…...
VScode使用Pyside6(环境篇)
Pyside6的环境搭建: cmd命令窗口输入:pip install pyside6 使用everthing进行查找:(非常好用的一款搜索工具 ) 进入PySide6文件夹中,点击designer.exe,查看是否能够点开。 VScode环境搭建: 下…...
智能云图库-12-DDD重构
本节重点 之前我们已经完成了本项目的功能开发。由于本项目功能丰富、代码量大,如果是在企业中维护开发的项目,传统的 MVC 架构可能会让后续的开发协作越来越困难。所以本节鱼皮要从 0 带大家学习一种新的架构设计模式 —— DDD 领域驱动设计。 大纲…...
Linux 网络配置
文章目录 网络基础知识IP地址子网掩码DNS Linux操作系统网络配置 网络基础知识 IP地址 IP地址是用于区分同一个网络中的不同主机的唯一标识。 Internet中的主机要与其他机器通信必须具有一个IP地址,因为网络中传输的数据包必须携带目的IP地址和源IP地址ÿ…...
05-DevOps-Jenkins自动拉取构建代码2
通过前面的操作,已经成功完成了源代码的打包工作,具体操作参见下面的文章: 05-DevOps-Jenkins自动拉取构建代码-CSDN博客 验证打包文件 验证打包后的文件是否存在,进入到Jenkins的工作目录中,找到对应的jar包&#x…...
ESP32之OTA固件升级流程,基于VSCode环境下的ESP-IDF开发,基于阿里云物联网平台MQTT-TLS连接通信(附源码)
目录 1.创建产品和设备 2.准备工作 2.1 获取基础工程 2.2 基本知识概述 2.2.1 OTA升级流程 2.2.2 主题和数据格式 (1)设备上报版本号 ①请求主题(设备 -> 阿里云): ②响应主题(阿里云->设备…...
【秣厉科技】LabVIEW工具包——OpenCV 教程(20):拾遗 - imgproc 基础操作(下)
文章目录 前言imgproc 基础操作(下)8. 霍夫检测9. 滤波与模糊10. 拟合与包围 总结 前言 需要下载安装OpenCV工具包的朋友,请前往 此处 ;系统要求:Windows系统,LabVIEW>2018,兼容32位和64位。…...
kafka发送消息,同时支持消息压缩和不压缩
1、生产者配置 nacos中增加配置,和公共spring-kafka配置字段有区分 需要发送压缩消息时,使用该配置类发送即可 import org.apache.kafka.clients.producer.ProducerConfig; import org.springframework.beans.factory.annotation.Autowired; import or…...
AOSP世界时间的更新
在 AOSP(Android Open Source Project)中,世界时间的更新主要涉及设备时区数据的管理和更新,以确保设备能够正确显示全球各地的时间。AOSP 依赖 IANA 时区数据库(也称为 tzdata)来提供时区规则和世界时间数…...
Python + 链上数据可视化:让区块链数据“看得懂、用得上”
Python + 链上数据可视化:让区块链数据“看得懂、用得上” 区块链技术的透明性和去中心化特性,使得链上数据成为金融、供应链、NFT 以及 DeFi 领域的关键参考。可是,对于普通用户而言,链上数据往往晦涩难懂,难以直接利用。那么,如何利用 Python 提取、分析并直观展示链上…...
方德桌面操作系统V5.0-G23 vim无法复制粘贴内容
1.修改 Vim 配置文件 rootyuhua-virtualmachine:/etc/docker# sudo vim /usr/share/vim/vim82/defaults.vim 2.在第82行找到set mousea行,将其为set mouse-a。如果文件中没有set mousea,则修改添加set mouse-a。 3.保存文件并退出 Vim: 4…...
[linux] vim 乱码
1. 确保终端支持中文 设置终端编码为 UTF-8,运行: echo $LANG如果不是 UTF-8(如 en_US.UTF-8),你可以设置为: export LANG=zh_CN.UTF-8 export LC_ALL=zh_CN.UTF-8 2. 确保 Vim 使用 UTF-8 编码 打开 .vimrc 或输入以下命令: :set encoding=utf-8 :set fileencodin…...
天洑参加人工智能校企产学研及人才对接活动——走进南京大学人工智能学院
4月15日,人工智能校企产学研及人才对接——走进南京大学人工智能学院活动在南京大学成功举办。此次活动由江苏省人工智能学会、南京大学人工智能学院主办,江苏省工业和信息化厅党组成员、副厅长池宇,南京大学副校长周志华出席。江苏省工业和信…...
33、单元测试实战练习题
以下是三个练习题的具体实现方案,包含完整代码示例和详细说明: 练习题1:TDD实现博客评论功能 步骤1:编写失败测试 # tests/test_blog.py import unittest from blog import BlogPost, Comment, InvalidCommentErrorclass TestBl…...
《AI大模型应知应会100篇》第22篇:系统提示词(System Prompt)设计与优化
第22篇:系统提示词(System Prompt)设计与优化 摘要 在大语言模型(LLM)应用中,系统提示词(System Prompt)是控制模型行为的核心工具之一。它不仅定义了模型的身份、角色和行为规范,还直接影响输…...
【KWDB 创作者计划】_深度学习篇---松科AI加速棒
文章目录 前言一、简介二、安装与配置硬件连接驱动安装软件环境配置三、使用步骤初始化设备调用SDK接口检测设备状态:集成到AI项目四、注意事项兼容性散热固件更新安全移除五、硬件架构与技术规格核心芯片专用AI处理器内存配置接口类型物理接口虚拟接口能效比散热设计六、软件…...
【Quest开发】在虚拟世界设置具有遮挡关系的透视窗口
软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72 硬件:Meta Quest3 仅针对urp管线 参考了YY老师这篇,可以先看他的再看这个可能更好理解一些:Unity Meta Quest MR 开发(七):使…...
Spark on K8s 在vivo大数据平台的混部实战
作者:vivo 互联网大数据团队- Qin Yehai 在离线混部可以提高整体的资源利用率,不过离线Spark任务部署到混部容器集群需要做一定的改造,本文将从在离线混部中的离线任务的角度,讲述离线任务是如何进行容器化、平台上的离线任务如何…...
Mac配置Java的环境变量
刚拿到手的Mac mini M4如何去设置java的环境变量? 第一步: 首先,你先下载好intelliJ IDEA,然后在里面自带的jdk列表里选择你自己想要使用的jdk的版本以及供应商。 下面是我自己使用的jdk版本以及供应商: 第二步&am…...
RPCRT4!OSF_CCONNECTION::OSF_CCONNECTION函数分析之创建一个RPCRT4!OSF_CCALL--RPC源代码分析
RPCRT4!OSF_CCONNECTION::OSF_CCONNECTION函数分析之创建一个RPCRT4!OSF_CCALL 第一部分: 1: kd> p RPCRT4!OSF_CCONNECTION::OSF_CCONNECTION0x167: 001b:77bf6957 393dec35c877 cmp dword ptr [RPCRT4!gfRPCVerifierEnabled (77c835ec)],edi 1: kd> …...
6、事件处理法典:魔杖交互艺术——React 19 交互实现
一、魔杖启灵:交互魔法的本质 "记住,巫师们!魔杖的每一次挥动都是与魔法世界的对话,"麦格教授的魔杖在空中划出金色事件流,"React 19的useTransition如同时间转换器,让麻瓜设备也能感知魔杖…...