水表数字识别4:C/C++实现水表数字识别(含源码 可实时检测)

水表数字识别4:C/C++实现水表数字识别(含源码 可实时检测)

目录

水表数字识别4:C/C++实现水表数字识别(含源码 可实时检测)

1. 前言

2. 水表数字分割模型

(1) 将Pytorch模型转换ONNX模型

(2) 将ONNX模型转换为NCNN模型

3. 水表数字识别模型(PlateNet)

(1) 将Pytorch模型转换ONNX模型

(2) 将ONNX模型转换为NCNN模型

4. 水表数字识别C++端上部署

(1) 项目结构

(2) 配置开发环境(OpenCV+vulkan+base-utils+NCNN)

(3) 部署NCNN模型

(4)CMake配置

(5)main源码

(6)源码编译和运行

5.水表识别数字识别效果(C/C++版本)

6.水表识别数字识别效果(Android版本)

7. 项目源码下载


1. 前言

本项目将实现水表数字识别,整套方案采用二阶段方法实现,即首先使用文本(数字)检测模型DBNet定位水表数字的区域,然后进行校正并裁剪水表数字区域,再使用CRNN模型对水表数字的区域进行文本(数字)识别。

整套项目分为:数据集说明,DBNet文本(数字)检测模型训练、CRNN文本(数字)识别模型训练,以及水表数字识别边缘侧部署C++/Android等多个章节,本篇是项目《​​​​水表数字识别》系列文章之《C++实现水表数字识别》;为了方便后续模型工程化和Android平台部署,项目对文字检测模型和文字识别模型进行轻量化,并提供Python/C++/Android多个版本;

整套水表数字检测和识别系统,在普通Android手机上可以达到实时的检测效果,CPU(4线程)约40ms左右,GPU约30ms左右 ,基本满足业务的性能需求。下表格给出CRNN,LPRNet和PlateNet模型的计算量和参数量以及其数字识别的准确率:

模型input-sizeparams(M)GFLOPsAccuracy
LPRNet94×240.48M0.147GFlops0.9000
CRNN160×328.35M1.06GFlops0.9150
PlateNet168×481.92M1.25GFlops0.9275

【尊重原创,转载请注明出处】https://blog.csdn.net/guyuealian/article/details/139998800


更多项目《水表数字识别》系列文章请参考:

  • 水表数字识别1:水表数字数据集说明(含下载链接) 
  • 水表数字识别2:Pytorch  DBNet实现水表数字检测(含训练代码和数据集)
  • 水表数字识别3:Pytorch  CRNN实现水表数字识别(含训练代码和数据集)
  • 水表数字识别4:C++实现水表数字识别(含源码 可实时检测)
  • 水表数字识别5:Android实现水表数字识别(含源码 可实时检测)

      


2. 水表数字分割模型

关于水表数字分割模型训练,请参考《水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集)》

项目提供两个版本的水表数字分割模型DBNet和Fast-SCNN模型;DBNet属于高精度版本,参数量和计算量较大,检测精度较高,但比较耗时;Fast-SCNN模型属于轻量化版本,参数量和计算量较小,检测精度一般,速度较快,适合手机移动端部署。

下表格给出文本(数字)检测模型DBNet和Fast-SCNN的计算量和参数量,以及其预测结果的均方误差MSE:

模型input-sizeparams(M)GFLOPsMSEmIOU

DBNet

320×320

9722.27M

12.22M

0.1508

0.9333

Fast-SCNN

320×320

1.24M

939.01M

0.1997

0.9531

考虑到手机端比较弱鸡的性能,项目最终使用Fast-SCNN模型进行端上部署。水表数字分割模型在C++端上部署过程,请参考如下

(1) 将Pytorch模型转换ONNX模型

训练好Pytorch模型后,我们需要先将模型转换为ONNX模型,以便后续模型部署。

  • 原始项目提供转换脚本,你只需要修改model_file和config_file
    为你模型和配置文件路径即可
  • convert_torch_to_onnx.py实现将Pytorch模型转换ONNX模型的脚本
python libs/converter/convert_torch_to_onnx.py

(2) 将ONNX模型转换为NCNN模型

目前CNN模型有多种部署方式,可以采用NCNN、TNN、MNN以及TensorRT等部署工具,鄙人采用NCNN进行C++和Android端上部署:

NCNN转换工具:

  • (1)将ONNX模型转换为NCNN模型,请参考NCNN官方说明:GitHub - Tencent/ncnn: ncnn is a high-performance neural network inference framework optimized for the mobile platform
  • (2)一键转换,懒人必备:一键转换 Caffe, ONNX, TensorFlow 到 NCNN, MNN, Tengine   (可能存在版本问题,这个工具转换的NCNN模型可能不兼容,建议还是自己build源码进行转换,2022年9约25日测试可用)


3. 水表数字识别模型(PlateNet)

关于水表数字识别模型训练,请参考《水表数字识别3:Pytorch CRNN实现水表数字识别(含训练代码和数据集)》

项目基于CRNN或LPRNet模型构建水表数字识别算法;为方便后续工程化,项目对CRNN模型进行魔改,提出一个PlateNet模型,用于支持部署到Android平台或者开发板上

整套水表数字识别系统,在OpenCL加速下,可以达到实时的检测效果,基本满足业务的性能需求。下表格给出CRNN,LPRNet和PlateNet模型的计算量和参数量以及其识别的准确率:

模型input-sizeparams(M)GFLOPsAccuracy
LPRNet94×240.48M0.147GFlops0.9000
CRNN160×328.35M1.06GFlops0.9150
PlateNet168×481.92M1.25GFlops0.9275

考虑到LPRNet和CRNN模型,存在某些OP算子,NCNN不支持,项目最终使用PlateNet模型进行端上部署。水表数字识别模型在C++端上部署过程,请参考如下

PlateNet识别模型在C++端上部署过程,请参考如下

(1) 将Pytorch模型转换ONNX模型

水表数字识别项目源码demo.py文件中参数--export设置为True,可将Pytorch的模型转换为ONNX模型文件,且ONNX文件会默认保存在Pytorch的模型文件同一目录下。

(2) 将ONNX模型转换为NCNN模型

NCNN转换工具,请参考:

  • (1)将ONNX模型转换为NCNN模型,请参考NCNN官方说明:GitHub - Tencent/ncnn: ncnn is a high-performance neural network inference framework optimized for the mobile platform
  • (2)一键转换,懒人必备:一键转换 Caffe, ONNX, TensorFlow 到 NCNN, MNN, Tengine   (可能存在版本问题,这个工具转换的NCNN模型可能不兼容,建议还是自己build源码进行转换,2022年9约25日测试可用)

4. 水表数字识别C++端上部署

(1) 项目结构

(2) 配置开发环境(OpenCV+vulkan+base-utils+NCNN)

项目仅在Ubuntu18.04进行测试,Windows系统下请自行配置和编译

  • 安装OpenCV:图像处理

图像处理(如读取图片,图像裁剪等)都需要使用OpenCV库进行处理

安装教程:Ubuntu18.04安装opencv和opencv_contrib

OpenCV库使用opencv-4.3.0版本,opencv_contrib库暂时未使用,可不安装

  • 安装vulkan:模型加速

 安装教程:Ubuntu18.04安装Vulkan SDK教程方法

vulkan用于模型GPU加速,若不使用vulkan进行模型推理加速,纯C++推理模型,速度会特别特别慢

  • base-utils:C++库

GitHub:https://github.com/PanJinquan/base-utils (无需安装,项目已经配置了)

base_utils是个人开发常用的C++库,集成了C/C++ OpenCV等常用的算法

  • NCNN:模型推理

GitHub:https://github.com/Tencent/ncnn (无需安装,项目已经配置了)

ncnn 是一个为手机端极致优化的高性能神经网络前向计算框架。 ncnn 从设计之初深刻考虑手机端的部署和使用。 无第三方依赖,跨平台,手机端 cpu 的速度快于目前所有已知的开源框架。 基于 ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行, 开发出人工智能 APP,将 AI 带到你的指尖。 ncnn 目前已在腾讯多款应用中使用,如:QQ,Qzone,微信,天天 P 图等。

(3) 部署NCNN模型

项目实现了C/C++版本的水表数字识别,水表数字分割模型采用Fast-SCNN和水表数字识别模型采用PlateNet,模型推理采用NCNN部署框架(支持多线程CPU和GPU加速推理);图像处理采用OpenCV库,模型加速采用vulkan,在普通设备即可达到实时处理。

如果你想在这个 Demo部署你自己训练的水表数字分割模型Fast-SCNN和识别模型PlateNet,你可将训练好的Pytorch模型转换ONNX ,再转换成NCNN模型,然后把原始的模型替换成你自己的NCNN模型即可。

(4)CMake配置

这是CMakeLists.txt,其中主要配置OpenCV+vulkan+base-utils+NCNN这四个库,Windows系统下请自行配置和编译

cmake_minimum_required(VERSION 3.14.0)
project(Detector)#set(CMAKE_BUILD_TYPE Debug)
add_compile_options(-fPIC) # fix Bug: can not be used when making a shared object
set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -pthread")
#set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
#set(CMAKE_CXX_FLAGS_DEBUG "-g")if (NOT CMAKE_BUILD_TYPE)# -DCMAKE_BUILD_TYPE=Debug# -DCMAKE_BUILD_TYPE=Releasemessage(STATUS "No build type selected, default to Release")set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Debug)" FORCE)
endif ()# NCNN set
set(NCNN_OPENMP ON CACHE BOOL "" FORCE)
set(NCNN_VULKAN ON CACHE BOOL "" FORCE)
set(NCNN_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
set(NCNN_COMPILER_SUPPORT_X86_AVX OFF CACHE BOOL "" FORCE)
set(NCNN_COMPILER_SUPPORT_X86_AVX2 OFF CACHE BOOL "" FORCE)
set(NCNN_AVX OFF CACHE BOOL "" FORCE)
set(NCNN_AVXVNNI OFF CACHE BOOL "" FORCE)
#set(NCNN_SHARED_LIB ON CACHE BOOL "" FORCE)
set(NCNN_THREADS ON CACHE BOOL "" FORCE)
set(NCNN_BF16 ON CACHE BOOL "" FORCE)
set(NCNN_DISABLE_RTTI OFF CACHE BOOL "" FORCE)if (CMAKE_SYSTEM_NAME MATCHES "Android")add_definitions(-DDEBUG_ANDROID_ON)            # for Android Logadd_definitions(-DPLATFORM_ANDROID)
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")add_definitions(-DDEBUG_ON)                    # for WIN/Linux Logadd_definitions(-DDEBUG_LOG_ON)                # for WIN/Linux Logadd_definitions(-DDEBUG_IMSHOW_OFF)            # for OpenCV showadd_definitions(-DPLATFORM_LINUX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")add_definitions(-DDEBUG_ON)                    # for WIN/Linux Logadd_definitions(-DDEBUG_LOG_ON)                # for WIN/Linux Logadd_definitions(-DDEBUG_IMSHOW_OFF)            # for OpenCV showadd_definitions(-DPLATFORM_WINDOWS)
endif ()
add_subdirectory(3rdparty/ncnn ncnn_build)
include_directories(3rdparty/ncnn/src)# VULKAN set
set(VULKAN_SDK "3rdparty/vulkansdk/1.3.280.1/x86_64")# opencv set
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS} ./src/)
#MESSAGE(STATUS "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}")# base_utils
set(BASE_ROOT 3rdparty/base-utils) # 设置base-utils所在的根目录
add_subdirectory(${BASE_ROOT}/base_utils/ base_build) # 添加子目录到build中
include_directories(${BASE_ROOT}/base_utils/include)
include_directories(${BASE_ROOT}/base_utils/src)
MESSAGE(STATUS "BASE_ROOT = ${BASE_ROOT}")# Detector
include_directories(src)
set(SRC_LISTsrc/Interpreter.cppsrc/segment.cppsrc/regress.cppsrc/crnn.cpp)
add_library(dlcv SHARED ${SRC_LIST})
target_link_libraries(dlcv ncnn ${OpenCV_LIBS} base_utils)
MESSAGE(STATUS "DIR_SRCS = ${SRC_LIST}")add_executable(Detector src/main_crnn.cpp)
target_link_libraries(Detector dlcv -lpthread)

(5)main源码

主程序中实现水表数字分割+水表数字识别,其中test_image_file()实现测试图片,test_video_file()实现测试视频文件,test_camera()实现测试摄像头

//
// Created by Pan on 2018/6/24.
//
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <vector>
#include <string>
#include "crnn.h"
#include "Types.h"
#include "regress.h"
#include "file_utils.h"
#include "image_utils.h"using namespace dl;
using namespace vision;
using namespace std;int numThread = 8;
//DeviceType device = GPU; // 使用GPU运行,需要配置好vulkan
DeviceType device = CPU; // 使用CPU运行string det_bin_file = "../data/model/watermeter/fast-scnn-reg-320.bin";
string det_pam_file = "../data/model/watermeter/fast-scnn-reg-320.param";string rec_bin_file = "../data/model/watermeter/platenet-168-48.bin";
string rec_pam_file = "../data/model/watermeter/platenet-168-48.param";// 设置检测阈值
RegressParam param = REG_MODEL320;
Regress *detector = new Regress(det_bin_file,det_pam_file,param,numThread,device);CRNNRecognizeParam crnn_param = CRNN_MODEL;
CRNNRecognize *recognize = new CRNNRecognize(rec_bin_file,rec_pam_file,crnn_param,numThread,device);/**** 测试已裁剪图片文件* @return*/
int test_image_crops() {// 测试图片string image_dir = "../data/test_image/watermeter";vector<string> image_list = get_files_list(image_dir);for (string image_path:image_list) {cv::Mat bgr_image = cv::imread(image_path);if (bgr_image.empty()) continue;int w = bgr_image.cols;int h = bgr_image.rows;FrameInfo resultInfo;ObjectInfo info;info.x1 = 0;info.y1 = 0;info.x2 = w;info.y2 = h;info.score = 1.0;resultInfo.info.push_back(info);// 开始检测recognize->detect(bgr_image, &resultInfo);// 可视化代码recognize->visualizeResult(bgr_image, &resultInfo);}printf("FINISHED.\n");return 0;
}/**** 测试图片文件* @return*/
int test_image_file() {// 测试图片string image_dir = "../data/test_image/watermeter";vector<string> image_list = get_files_list(image_dir);for (string image_path:image_list) {cv::Mat frame = cv::imread(image_path);if (frame.empty()) continue;FrameInfo resultInfo;// 开始检测detector->detect(frame, &resultInfo);// 可视化代码// detector->visualizeResult(frame, &resultInfo, true, 5, true);// 开始识别recognize->detect(frame, &resultInfo);// 可视化代码recognize->visualizeResult(frame, &resultInfo, 0);}printf("FINISHED.\n");return 0;
}/**** 测试视频文件* @return*/
int test_video_file() {string video_file = "../data/video/test-video.mp4"; //视频文件cv::VideoCapture cap;bool ret = get_video_capture(video_file, cap);cv::Mat frame;while (ret) {cap >> frame;if (frame.empty()) break;FrameInfo resultInfo;// 开始检测detector->detect(frame, &resultInfo);// 可视化代码cv::Mat dst = detector->visualizeResult(frame, &resultInfo, true, 5, true);// 开始识别recognize->detect(frame, &resultInfo);// 可视化代码recognize->visualizeResult(dst, &resultInfo, 20);}cap.release();delete detector;detector = nullptr;printf("FINISHED.\n");return 0;
}/**** 测试摄像头* @return*/
int test_camera() {int camera = 0; //摄像头ID号(请修改成自己摄像头ID号)cv::VideoCapture cap;bool ret = get_video_capture(camera, cap);cv::Mat frame;while (ret) {cap >> frame;if (frame.empty()) break;FrameInfo resultInfo;// 开始检测detector->detect(frame, &resultInfo);// 可视化代码//cv::Mat dst = detector->visualizeResult(frame, &resultInfo, true, 5, true);// 开始识别recognize->detect(frame, &resultInfo);// 可视化代码recognize->visualizeResult(frame, &resultInfo, 20);}cap.release();delete detector;detector = nullptr;printf("FINISHED.\n");return 0;}int main() {test_image_file();test_video_file();//test_camera();return 0;
}

(6)源码编译和运行

编译脚本,或者直接:bash build.sh

#!/usr/bin/env bash
if [ ! -d "build/" ];thenmkdir "build"
elseecho "exist build"
fi
cd build
cmake ..
make -j4
sleep 1
./demo
  • 如果你要测试GPU运行的性能,请修改src/main_crnn.cpp 

DeviceType device = CPU;

  • 如果你要测试GPU运行的性能,请修改src/main_crnn.cpp (需配置好vulkan) 

DeviceType device = GPU;

下面截图给出开启vulkan加速的性能对比截图,纯C++推理模式需要耗时几百毫秒的时间,而开启vulkan加速后,GPU模式耗时仅需十几毫秒,性能极大的提高。


5.水表识别数字识别效果(C/C++版本)

 C++版本的opencv不支持中文显示,暂时未解决这个BUG,不过LOG会打印水表数字的信息,凑合的用吧

下图GIF这是Python版本的水表数字分割和识别效果,C++版本与Python版本的结果几乎是一致

   


6.水表识别数字识别效果(Android版本)

项目已经完成Android版本水表数字检测分割和识别算法开发,APP在普通Android手机上可以达到实时的检测和识别效果,CPU(4线程)约40ms左右,GPU约30ms左右 ,基本满足业务的性能需求。详细说明请查看:水表数字识别5:Android实现水表数字识别(含源码 可实时检测)

Android Demo体验:https://download.csdn.net/download/guyuealian/89537381


7. 项目源码下载

【水表数字分割和识别C/C++源码下载】C/C++实现水表数字识别(含源码 可实时检测)

整套项目源码内容包含:

  1. 提供Fast-SCNN水表数字分割模型
  2. 提供PlateNet水表数字识别模型,识别准确率可以达到0.9275左右
  3. 提供整套项目水表数字分割和识别C++项目源码
  4. C++ Demo源码支持二次开发
  5. C++ Demo支持透视变换倾斜矫正
  6. C++ Demo支持图片,视频和摄像头测试
  7. C++ Demo支持CPU和GPU,GPU模型加速需要配置好vulkan,否则速度很慢;CPU模式推理需要耗时几百毫秒的时间,而开启vulkan加速后,GPU模式耗时仅需十几毫秒

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/399256.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NoSQL 之Redis集群模式

目录 案例概述 redis工作模式 主从模式 哨兵模式 redis cluster模式 Redis集群介绍 Redis集群的优势 Redis集群的实现方法 Redis-Cluster数据分片 Redis-Cluster的主从复制模型 Redis集群部署 案例部署 安装redis 检查redis的状态 修改配置文件 重启启动redis服…

C#小桌面程序调试出错,如何解决??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

pythonUI自动化007::pytest的组成以及运行

pytest组成&#xff1a; 测试模块&#xff1a;以“test”开头或结尾的py文件 测试用例&#xff1a;在测试模块里或测试类里&#xff0c;名称符合test_xxx函数或者示例函数。 测试类&#xff1a;测试模块里面命名符合Test_xxx的类 函数级&#xff1a; import pytestclass Test…

大数据面试SQL(七):累加刚好超过各省GDP40%的地市名称

文章目录 累加刚好超过各省GDP40%的地市名称 一、题目 二、分析 三、SQL实战 四、样例数据参考 累加刚好超过各省GDP40%的地市名称 一、题目 现有各省地级市的gdp数据,求从高到低累加刚好超过各省GDP40%的地市名称&#xff0c;临界地市也需要。 例如&#xff1a; 浙江省…

物理网卡MAC修改器v3.0-直接修改网卡内部硬件MAC地址,重装系统不变!

直接在操作系统里就能修改网卡硬件mac地址&#xff0c;刷新网卡mac序列号硬件码机器码&#xff0c;电脑主板集成网卡&#xff0c;pcie网卡&#xff0c;usb有线网卡&#xff0c;usb无线网卡&#xff0c;英特尔网卡&#xff0c;瑞昱网卡全支持&#xff01; 一键修改mac&#xff0…

求1000以内的水仙花数【C语言】

求1000以内的水仙花数 #include <stdio.h> //包含标准输入输出头文件&#xff0c;用于使用printf函数int main() { //程序的主函数开始int a, b, c, i; //i用于循环遍历100到999之间的所有数&#xff08;三位数&#xff09;&#xff0c;a, b, c分别用于存储当前数i的百位…

SPSS 数据分析,掌握这 6 大模块就够

SPSS 全称为「社会科学统计软件包」&#xff0c;是 IBM 公司推出的一系列用于统计学分析运算、数据挖掘、预测分析和决策支持任务的软件产品及相关服务的总称。 图中我们看到 SPSS 有 23 个方法模块&#xff0c;虽然我们不能每个模块都能用到&#xff0c;但作为一个科研工作者…

C++-类与对象(上篇)

一、目标&#xff1a; 1. 面向过程和面向对象初步认识 2. 类的引入 3. 类的定义 4. 类的访问限定符及封装 5. 类的作用域 6. 类的实例化 7. 类的对象大小的计算 8. 类成员函数的 this 指针 二、对类与对象的介绍&#xff1a; 1.面向过程和面向对象初步认识 &#xff1a…

前端代码编辑神器:sublime text 4(WinMac)中文注册版

Sublime Text 4 是一款广受欢迎的文本和代码编辑器&#xff0c;由程序员 Jon Skinner 于2008年开发。这款编辑器以其漂亮的用户界面和强大的功能而著称&#xff0c;适用于多种编程语言的开发。 主要特点&#xff1a; 用户界面&#xff1a;Sublime Text 4 拥有一个简洁且美观的…

旧手机拍摄的视频模糊可以修复清晰吗?

你是否时常“考古”一些老电影、老动漫来回忆旧日时光&#xff1f;你是否也有一些珍贵的录像&#xff0c;带你重温过去的美好&#xff1f;然而&#xff0c;我们已经习惯了高清体验&#xff0c;回头再看曾经的旧影像&#xff0c;画质或许“渣”的让人不忍直视。 旧手机像素不好&…

[VBA]使用VBA在Excel中 操作 形状shape 对象

excel已关闭地图插件,对于想做 地图可视化 的,用形状来操作是一种办法,就是要自行找到合适的 地图形状,修改形状颜色等就可以用于 可视化展示不同省市销量、人口等数据。 引言 在Excel中,通过VBA(Visual Basic for Applications)可以极大地增强数据可视化和报告自动化…

【ARM CoreLink 系列 5.5 -- CI-700 Debug trace and PMU 】

文章目录 Debug trace and PMUCI-700 Debug trace 系统概述DTC DomainDTC Domain 约束条件DTM device portsDTM FIFO BufferDTM FIFO 缓冲区特点Debug trace and PMU 本篇文章主要是介绍 CI-700中实现的 Debug Trace (DT) and Performance Monitoring Unit (PMU). CI-700 Deb…

运维高级内容--lvs按权重值轮询调度

创建5台主机(一些配置是基于实验一的基础)&#xff1a; 客户端client 172.25.254.200路由器route 172.25.254.100 192.168.0.100 &#xff08;需要eth0、eth1两个网关&#xff09;LVS 192.168.0.50webserver1 192.168.0.10webserver2 192.168.0.20 1.LVS主机&#xff1a; vim…

pytorch多GPU训练简明教程

1. Torch 的两种并行化模型封装 1.1 DataParallel DataParallel 是 PyTorch 提供的一种数据并行方法&#xff0c;用于在单台机器上的多个 GPU 上进行模型训练。它通过将输入数据划分成多个子部分&#xff08;mini-batches&#xff09;&#xff0c;并将这些子部分分配给不同的 G…

python爬取B站视频实验

实验17&#xff1a;爬虫2 文章目录 实验17&#xff1a;爬虫21.实验目标及要求2. 实验主要内容3.实验小结 1.实验目标及要求 &#xff08;1&#xff09;掌握有关爬虫的包 &#xff08;2&#xff09;掌握爬虫方法 &#xff08;3&#xff09;爬取B站卡塔尔世界杯若干视频 2. 实验…

day09——集合ArrayList

ArrayList类 ArrayList表示一种集合&#xff0c;它是一个容器&#xff0c;用来存储数据的&#xff0c;类似于数组。但不同于数组&#xff0c;数组一旦创建大小不变&#xff0c;而集合大小是可变的。 ArrayList常用方法 ArrayList是泛型类&#xff0c;可以约束存储的数据类型…

MapReduce入门教程

这可不是目录 入门定义与说明数据分析Map和Reduce阶段的任务<Kn,Vn>分析MapReduce的数据类型其他说明(持续更新) 开发案例(持续更新)自定义的wordcountcsv文件操作序列化操作 入门 定义与说明 数据分析 以下未数据分析示意图 Map和Reduce阶段的任务 Map阶段的任务&a…

AVL树模拟实现

目录 前言 什么叫平衡呢&#xff1f; 平衡因子 代码实现 基础结构 函数部分 构造部分 Insert函数 旋转情况(敲重点&#xff01;&#xff01;&#xff01;~\(≧▽≦)/~) 1、右右情况 ——— 左单旋 左旋总步骤 拆解 为什么叫左旋呢&#xff1f; 代码 2、左左情况 …

考研概率论如何复习最高效?能拿满分

概率论跟哪写老师的课程&#xff1f; 推荐三个老师&#xff1a; 喻老&#xff1a;基础讲的很好 喻老的线性代数课在今年已经非常有名&#xff0c;但其实他讲授的概率论课程同样十分出色。喻老的课程特点在于讲解非常细致&#xff0c;特别适合基础较为薄弱的学生。此外&#…

如何评估一个APP是否适合进行ASO优化呢

ASO&#xff08;App Store Optimization&#xff09;优化是提升APP在各类应用商店排行榜和搜索结果排名的过程。那么怎么评估一个APP是否适合进行ASO优化呢&#xff0c;可以从以下几个方面进行考量&#xff1a; 一、市场竞争情况 1.行业竞争激烈程度 首先分析APP所在行业的竞…