从数据采集到部署,手把手带你训练一个高质量的图像分类模型

本文来自社区投稿,作者李剑锋

MMPreTrain 是一款基于 PyTorch 的开源深度学习预训练工具箱,本文将从数据采集到部署,手把手带大家使用 MMPreTrain 算法库训练一个高质量的图像分类模型。

MMPreTrain 项目链接:

https://github.com/open-mmlab/mmpretrain

环境配置

对于MMPreTrain的环境配置我们可以通过官方的教程来实现

首先,我们要创建一个MMPreTrain的虚拟环境并安装Pytorch。安装GPU版本我们可以选择CPU或者GPU进行预测,而安装CPU版本就只能使用CPU进行预测。而我之所以采用下面这个方式是因为有些时候通过官方的这个代码安装GPU版本,但是实际安装的是CPU版本,因此我便在官网选择了pip的方式进行安装。假如CUDA版本比较低的话,也可以到官网查找到对应的下载代码。

#创建并激活环境
conda create --name mmpretrain python=3.8 -y
conda activate mmpretrain
#安装Pytorch#在GPU平台
conda install pytorch torchvision -c pytorch#在CPU平台
conda install pytorch torchvision cpuonly -c pytorch#我所使用的安装GPU版本的方式
#pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

然后我们需要在终端的git下载源码并进行安装。

git clone https://github.com/open-mmlab/mmpretrain.git
cd mmpretrain
pip install -U openmim && mim install -e .

假如我们的网络并不支持的话,可以考虑通过登录上MMPreTrain的GitHub官网来直接下载压缩包文件,然后将内容安装到指定位置即可。接下来还是和上面一样进入该文件目录然后在终端输入pip install -U openmim && mim install -e .即可。

我们可以通过下面的代码验证是否已经安装。

python demo/image_demo.py demo/demo.JPEG resnet18_8xb32_in1k --device cpu

当我们看到命令行中输出了结果字典,包括 pred_labelpred_scorepred_class 三个字段时就代表我们已经成功配置好MMPreTrain的环境了。

数据采集

图像分类任务中,数据集的获取相对容易。我们既可以通过本地采集数据,也可以利用网络上众多的开源数据集。因为分类任务只需要将图片放入对应类别的文件夹中,所以通常我们能获得的数据集都十分庞大且种类繁多。即便是像VOC或YOLO这样的数据集,它们可能不会直接按类别提供图片,但我们仍然可以通过脚本提取。比如,在一个标注有车辆和行人的数据集中,如果我们只需要车辆图片,我们可以编写脚本筛选出仅标注有车辆的图片,并将它们统一转移到一个文件夹里。这样一来,我们就可以轻松创建出一个按类别组织的图像数据集。

在下面的介绍当中,我将主要采用的是开源的数据集来进行测试并训练。一般而言,我们能够在几个渠道获取开源的数据集,包括国外的GitHub、HuggingFace、Kaggle以及国内的的飞浆AI Studio。我常用的平台就是Kaggle和AI studio,因为上面的数据集格式都是能够直接下载并使用的。下面我将下载一个Kaggle上的汽车和单车的图像分类数据集进行测试。具体页面链接为:https://www.kaggle.com/datasets/utkarshsaxenadn/car-vs-bike-classification-dataset

打开该链接后,我们能够查看到该数据集的一些基本信息,包括文件大小,文件内容,以及数据集等信息。我们点击下载按钮并放到MMPreTrain的文件夹里解压即可(我这里就选择把文件下载到MMPreTrain下的data文件夹里,没有的话可以新建一个)。

这样我们的数据集就准备好了。

数据处理

数据集格式

一般来讲,对于分类数据集而言,最重要的处理方式就是删除不相关的图片或者是特征比较不明显的图片来提升准确度。除此之外,还有很重要的一点就是将图片的格式改成适合于模型训练的格式。我们可以在mmpretrain/datasets文件夹里看到几类常见的数据集格式:

  • imagenet.py

    • in1k

  • in21k

  • voc.py

  • calthech101.py

  • food101.py

我们可以打开配置文件看到该模型所需要的文件格式:

除此之外也有很多的类型,我们都可以根据config文件来选择适合的数据集格式去制作。

之所以我们要按照dataset里要求的格式去制作的主要原因是为了方便后期调整。当我们按照数据集的要求修改了名称,我们就能够直接进行训练而不需要再修改配置文件来实现了。这样就能够大大加快我们的上手速度以及简化了整体的流程。

修改数据集格式

下面我们可以将解压好的数据集做成最常见的imagenet格式。

首先我们把文件解压后可以达到要给名为archive的文件夹,然后我们可以把里面的Car-Bike-Dataset文件夹复制到data文件夹的最外面,然后删掉archive的相关文件。这样处理完成后就应该显示的是下面的状态。

我们现在得到的是两个包含了所有图片文件的文件夹。那我们现在要模仿imagenet(in1k)的图片格式来进行转换。我们可以不通过手动修改的方式实现,而是设计一套提示词然后输入到大语言模型(比如说ChatGPT)中让其为我们生成脚本。由于我们不需要进行test,所以我们只需要制作val和train文件即可。

提示词如下:

请你作为一名python的脚本专家,辅助我完成接下来的任务:首先我在data/Car-Bike-Dataset该文件夹下有Bike和Car两个子文件夹,里面分别存放了大量的相关照片。现在我希望你能够在data这个文件夹里创建一个名为imagenet的文件夹,然后在里面创建两个个子文件夹train和val,然后在这些子文件夹里再分别创建两个子文件夹Bike和Car。然后按照80%,20%的比例把data/Car-Bike-Dataset/Bike里面的图片和data/Car-Bike-Dataset/Car这里的图片分别放到train和val这两个个文件夹下对应名称的子文件夹内。请一步步的进行思考并给出我完整的最终脚本代码。

下面是ChatGPT所给出的答复:

要完成您的任务,我们将使用Python的标准库来创建文件夹、移动文件,并使用随机分割来按照80%和20%的比例划分数据集。以下是完成这一任务的步骤和相应的Python脚本代码。

首先,我们需要导入必要的模块,并且设置好源文件夹和目标文件夹的路径。

import os
import shutil
from random import shuffle# 源文件夹路径
source_dataset_dir = 'data/Car-Bike-Dataset'# 目标文件夹路径
target_dataset_dir = 'data/imagenet'# 创建目标文件夹及其子文件夹
os.makedirs(os.path.join(target_dataset_dir, 'train', 'Bike'), exist_ok=True)
os.makedirs(os.path.join(target_dataset_dir, 'train', 'Car'), exist_ok=True)
os.makedirs(os.path.join(target_dataset_dir, 'val', 'Bike'), exist_ok=True)
os.makedirs(os.path.join(target_dataset_dir, 'val', 'Car'), exist_ok=True)

接下来,我们将定义一个函数来处理文件的分割和移动。函数将遍历源文件夹中的图片,随机打乱,然后按照80%和20%的比例分配到训练和验证文件夹中。

def split_data(source_folder, target_train_folder, target_val_folder, split_size=0.8):# 获取所有文件的路径files = [os.path.join(source_folder, f) for f in os.listdir(source_folder) if os.path.isfile(os.path.join(source_folder, f))]shuffle(files)  # 随机打乱文件顺序# 分割点计算split_point = int(len(files) * split_size)# 分配文件到训练集和验证集train_files = files[:split_point]val_files = files[split_point:]# 复制文件到目标文件夹for f in train_files:shutil.copy(f, target_train_folder)for f in val_files:shutil.copy(f, target_val_folder)

最后,我们调用split_data函数,并为BikeCar两个分类分别进行操作。

# 对Bike和Car文件夹执行数据集分割
split_data(os.path.join(source_dataset_dir, 'Bike'), os.path.join(target_dataset_dir, 'train', 'Bike'), os.path.join(target_dataset_dir, 'val', 'Bike'))
split_data(os.path.join(source_dataset_dir, 'Car'), os.path.join(target_dataset_dir, 'train', 'Car'), os.path.join(target_dataset_dir, 'val', 'Car'))

这个脚本将完成以下任务:

  1. data文件夹下创建imagenet文件夹以及其子文件夹trainval

  2. trainval文件夹下各创建BikeCar子文件夹。

  3. data/Car-Bike-Dataset/Bikedata/Car-Bike-Dataset/Car中随机选择80%的图片放入train对应子文件夹,剩下的20%放入val对应子文件夹。

我们可以在MMPretrian文件夹下新建一个test.py文件,并把代码都复制进去并下载对应的库,然后在终端运行python test.py这样我们就能够创建出以下的内容:

这样我们就把imagenet(in1k)的格式创建完成了。其他格式的创建方式也可以参考我的提示词进行修改使用。

模型配置及训练

在准备好了imagenet的数据集后,我们就可以去config文件夹里寻找我们想要用来分类的模型。我们可以在GitHub的官网以及中文文档上看到详细的模型库信息

这里我们选择比较常见的res2net模型进行训练。我们可以看到该模型有三个配置文件,其主要区别在于w和s的值,我们可以进入README.md文件中查看模型更加详细的信息。包括Top-1和Top-5的准确率以及参数量等。我们可以根据自己的硬件或者部署环境进行选择。

由于数据量比较小,在这里我们选择一个最小的模型进行测试并训练(即configs/res2net/res2net50-w14-s8_8xb32_in1k.py),假如大家有更大的数据集想要训练效果更好的模型,也可以考虑采用参数量更大且更深的模型。

当我们点击进入该文件后,可以看到以下内容:

_base_ = [                                             # 此配置文件将继承所有 `_base_` 中的配置'../_base_/models/res2net50-w14-s8.py',            # 模型配置'../_base_/datasets/imagenet_bs32_pil_resize.py',  # 数据配置'../_base_/schedules/imagenet_bs256.py',           # 训练策略配置'../_base_/default_runtime.py'                     # 默认运行设置
]

由于我们可能要修改模型,为不影响其他模型的使用,我们可以在MMPreTrain的project文件夹下创建一个新的文件夹Car_Bike_Classification,根据文件地址找到对应文件后,按照以下的格式将文件内容进行保存。

并对以下两个文件里的num_classes进行修改(由于我现在只是Car和Bike二分类,因此修改成2即可)。

当然我们也可以对学习率、损失函数之类超参数进行修改以提升效果。但是由于我们只是测试,现在我们就按照默认的情况来进行运行。

在完成了配置文件的设置后,我们可以到config文件里将文件地址进行修改以确保不会出错。

最后在这一切都修改妥当后,我们可以在终端输入python tools/train.py projects/Car_Bike_Classification/config/res2net50-w14-s8_8xb32_in1k.py即可进行训练。

但是我们一旦运行程序就会发现程序报错了,具体报错内容为:“ValueError: Top-5 accuracy is unavailable since the number of categories is 2. Please check the val_evaluator and test_evaluator fields in your config file.”。这个报错意味着我们二分类问题而言不能用Top-5来计算,只有用Top-1来计算。并且在val_evaluator和test_evaluator里删掉Top-5的内容。那我们就需要到下图的位置把topk=(1,5)改为topk=(1,):

这样我们再次运行python tools/train.py projects/Car_Bike_Classification/config/res2net50-w14-s8_8xb32_in1k.py

当我们看到下面的内容就代表模型正式开始训练了。并且模型的权重文件将保存在work_dirs/res2net50-w14-s8_8xb32_in1k,假如我们要修改保存的地址,就可以在上面的代码中假如“--work-dir xxx”。这里面。这里面还展示了其他的信息,包括eta(预计完成时间)、loss(当前模型的损失值)以及accuracy/top1(模型预测的准确率)。

模型测试

查看运行情况

在模型训练完后,我们可以点开work_dirs/res2net50-w14-s8_8xb32_in1k进入查看内部的文件。在vis_data里的json文件将存放着模型训练过程中的各种信息,而config.py文件里存放的是模型结构文件,.log文件里存放的是完整的训练信息(从开始到结束在终端里显示的信息)。再下面就是所有的训练出来的权重文件(这个模型有100个)。

我们可以通过MMPreTrain里自带的可视化文件来讲模型的准确度以及损失值可视化出来查看模型整体训练的效果。

  • 损失值可视化

python tools/analysis_tools/analyze_logs.py plot_curve work_dirs/res2net50-w14-s8_8xb32_in1k/20231107_155535/vis_data/20231107_155535.json --keys loss  
  1. python - 这是启动Python解释器的命令。

  2. tools/analysis_tools/analyze_logs.py - 这是用来分析日志文件的Python脚本的路径。

  3. plot_curve - 这是analyze_logs.py脚本的一个子命令,用于生成损失或者其他度量的曲线图。

  4. work_dirs/res2net50-w14-s8_8xb32_in1k/20231107_155535/vis_data/20231107_155535.json - 这是包含训练日志数据的JSON文件的路径。该文件记录了模型在训练过程中的性能指标,如损失和准确率等。

  5. --keys loss - 这是一个命令行参数,指定了要在曲线图中显示的关键字,这里是loss。意味着脚本将会提取日志文件中记录的损失值,并将其绘制成曲线图。但是我们同样可以添加其他比如说准确度的信息。

可以看到损失值在40批次的时候损失值已经在一个比较低的位置了。

  • 准确度

python tools/analysis_tools/analyze_logs.py plot_curve work_dirs/res2net50-w14-s8_8xb32_in1k/20231107_155535/vis_data/20231107_155535.json --keys accuracy/top1  

可以看到模型准确度在接近30批次的时候发生了一次剧烈的震荡,但是在30批次后就开始稳定在97.5%的准确度上。

总结上面两个数据我们可以看出,模型在40批次的时候已经训练好了,后面继续训练的内容就是过拟合后的内容。过拟合会使得模型专注于训练的数据集而丢失了泛化的能力,因此我们应该要选择的是40批次的权重来作为最终的权重来进行测试。

查看模型效果

我们可以在网上找几张车和单车的照片进行测试(不能使用训练集里的数据测试,因为模型训练学习过这些图片的内容,假如拿这些图片计算得到的结果是不准确的)。下面是找的几张测试的照片,我将其放到了MMPreTrain下的demo文件夹里(例如demo/bike.jfif):

我们可以通过调用demo/image_demo.py这个文件进行测试,具体的代码如下:

#python <脚本位置> image.jpg model_config.py --checkpoint checkpoint.pth --show --device cpu
#单车图片
python demo/image_demo.py demo/bike.jfif work_dirs/res2net50-w14-s8_8xb32_in1k/20231107_155535/vis_data/config.py --checkpoint work_dirs/res2net50-w14-s8_8xb32_in1k/epoch_40.pth --show --device cpu
#汽车图片
python demo/image_demo.py demo/car.jfif work_dirs/res2net50-w14-s8_8xb32_in1k/20231107_155535/vis_data/config.py --checkpoint work_dirs/res2net50-w14-s8_8xb32_in1k/epoch_40.pth --show --device cpu
  1. python - 这是用来启动Python解释器的命令。

  2. demo/image_demo.py - 这是你要运行的Python脚本的路径。这个脚本预计是MMPreTrain库的一部分,用于演示如何使用该库进行图像分类的推断。

  3. demo/bike.jfif - 这是输入图像文件的路径,你想要对它进行分类预测。

  4. work_dirs/res2net50-w14-s8_8xb32_in1k/20231107_155535/vis_data/config.py - 这是用于初始化模型的配置文件的路径。配置文件包含了模型的结构和其他参数设置。

  5. --checkpoint - 这是一个命令行参数,告诉脚本使用特定的权重文件来加载训练好的模型。

  6. work_dirs/res2net50-w14-s8_8xb32_in1k/epoch_40.pth - 这是模型权重文件的路径,包含了模型训练过程中学习到的参数。

  7. --show - 这个选项告诉脚本在推断完成后显示图像和预测结果。

  8. --device cpu - 这个参数指定了推断运行的设备。在这个例子中,它指定了使用CPU来进行推断,如果你有GPU且配置了相应的CUDA环境,通常可以用--device cuda来加速推断过程。

得到的结果为:

由于我们这里没有设置标签,所以显示的是Positive和Negative。但是可以看出的是Positive代表的是单车,Negative代表的是汽车。并且输入的照片分类都是准确的,所以可以看出MMPreTrain里提供的模型的准确度还是非常高的。

模型转换部署

在确定模型效果符合预期后,我们可以将模型进行部署到本地环境里。这里我们将使用OpenMMLab官方的MMDeploy实现。具体的环境安装以及模型的转换可以查看这篇文章。下面我就直接进入MMDeploy环境开始进行部署的指导。

首先在MMDeploy里创建一个名为project的文件夹,然后新建一个名为Car_Bike_Classification的文件夹,然后把训练好的config文件和checkpoint文件以及一张图片文件放入。

然后我们需要在configs/mmpretrain这个文件夹里找到我们要转换的模型以及对应需要的尺寸。这里我就选择configs/mmpretrain/classification_onnxruntime_dynamic.py转为ONNXRuntime模型并且尺寸并不固定的。接下来我们就需要调用tools/deploy.py里的部署文件在终端进行部署,具体代码如下:

python tools/deploy.py configs/mmpretrain/classification_onnxruntime_dynamic.py project/Car_Bike_Classification/config.py project/Car_Bike_Classification/epoch_40.pth project/Car_Bike_Classification/bike.jfif --work-dir output/Car_Bike_Classification --device cpu --dump-info
  • python tools/deploy.py:运行deploy.py脚本,这通常是用于部署工作流的主脚本。

  • configs/mmpretrain/classification_onnxruntime_dynamic.py:指定了部署配置文件的路径,这个配置文件定义了如何将模型转换为ONNXRuntime的动态版本。

  • project/Car_Bike_Classification/config.py:指定了模型的配置文件路径,这个文件包含了模型结构和训练过程中使用的各种参数。

  • project/Car_Bike_Classification/epoch_40.pth:指定了模型权重文件的路径,这是一个训练好的模型检查点文件。

  • project/Car_Bike_Classification/bike.jfif:指定了用于模型转换的图片文件路径,这张图片将用于转换过程中的测试或者量化校准。

  • --work-dir output/Car_Bike_Classification:设置工作目录为output/Car_Bike_Classification,转换的模型和日志将保存在这个目录下。

  • --device cpu:指定转换和测试过程中使用的设备是CPU。建议都安装CPU版本,时间虽然长一点的但是会方便很多。

  • --dump-info:这个参数表示需要导出SDK(软件开发工具包)相关的信息,便于部署到特定的设备或平台上。

完成后我们可以到output里查看结果。

可以看到模型成功被转换了,现在我们就能够直接调用这个SDK包进行预测了(这一整个文件夹,调用的话可以output/Car_Bike_Classification这样进行调用)。

我们可以用官方给的demo模板进行测试(demo/python/image_classification.py):

# Copyright (c) OpenMMLab. All rights reserved.
import argparseimport cv2
from mmdeploy_runtime import Classifierdef parse_args():parser = argparse.ArgumentParser(description='show how to use sdk python api')parser.add_argument('device_name', help='name of device, cuda or cpu')parser.add_argument('model_path',help='path of mmdeploy SDK model dumped by model converter')parser.add_argument('image_path', help='path of an image')args = parser.parse_args()return argsdef main():args = parse_args()img = cv2.imread(args.image_path)classifier = Classifier(model_path=args.model_path, device_name=args.device_name, device_id=0)result = classifier(img)for label_id, score in result:print(label_id, score)if __name__ == '__main__':main()

在终端调用的代码为:

python demo/python/image_classification.py cpu output/Car_Bike_Classification project/Car_Bike_Classification/bike.jfif

可以看到,结果就是分为第一类且有高达99%的准确率。

这样我们就成功完成了模型的部署了,下面我们可以用这个模型任何地方进行本地化运行了。

模型可视化

本地部署Gradio

我们甚至可以用这里面的end2end.onnx文件利用ONNXRuntime和Gradio部署在HuggingFace平台上。之所以没有用MMDeploy的SDK包进行部署的主要原因是在HuggingFace上配置MMDeploy的环境比较困难,需要对Linux非常熟悉,所以我们可以采取利用ONNXRuntime的方式运行。当然在本地部署我们也可以采用MMDeploy的SDK包来实现,但是考虑到要在HuggingFace上部署,还是用ONNXRuntime比较合适。

那么首先我们需要先将代码写下。这部分我们可以靠着大语言模型来帮我们完成,假如遇到Bug让其进行修改即可。我的提示词如下:

你可以作为Gradio的专家,帮我写一个gradio界面吗。现在我有一个分类模型的.onnx文件在本地(文件名为end2end.onnx),该模型分为两类,第一类是单车bike,第二类是汽车car,然后我希望这个gardio界面能够左边是上传图片的,右边展示两类的可能性,然后用一个矩形图展示出来,并且根据判断的结果下面加一个文本框告诉大家说“该图片里是汽车或者单车”。 你写好这个代码,只需要给我留一个传入onnx文件地址的入口即可。清一步步的进行思考,记得详细的考虑Gradio的注意事项,不要添加太多没有意义的东西。

但是一般来说第一次生成的代码都会有一些问题,我们只需要把问题反映给ChatGPT后面让其进行修改后得到下面的最终代码:

import gradio as gr
import onnxruntime as ort
import numpy as np
from PIL import Image# 替换成你的 ONNX 模型文件路径
ONNX_MODEL_PATH = 'end2end.onnx'# 加载模型
ort_session = ort.InferenceSession(ONNX_MODEL_PATH)# 定义预测函数
def classify_image(image):# 确保image是一个PIL图像对象if not isinstance(image, Image.Image):image = Image.fromarray(image)# 预处理输入图片image = image.resize((224, 224))image = np.array(image).astype('float32')image = np.transpose(image, (2, 0, 1))  # Change data layout from HWC to CHWimage = np.expand_dims(image, axis=0)# 使用 ONNX 运行推理inputs = {ort_session.get_inputs()[0].name: image}outputs = ort_session.run(None, inputs)# 获取预测结果predictions = outputs[0]# 创建一个矩形图展示可能性pred_probs = predictions[0].tolist()  # 假设模型输出是一个概率列表pred_probs = [float(i)/sum(pred_probs) for i in pred_probs]  # 归一化概率值class_names = ['Bike', 'Car']result = {class_name: prob for class_name, prob in zip(class_names, pred_probs)}# 生成结果文本pred_text = f"该图片里是{'汽车' if np.argmax(predictions) else '单车'}。"return result, pred_text# 根据Gradio新的API更新了导入和组件
from gradio import Interface, components# 创建 Gradio 界面
iface = Interface(fn=classify_image,inputs=components.Image(shape=(224, 224)),outputs=[components.Label(num_top_classes=2),components.Textbox(label="分类结果")],title="单车与汽车图像分类",description="上传一张图片,模型将预测图片是单车还是汽车。"
)# 启动界面
iface.launch(share=True)

这个代码只需要我们在本地安装以下几个库便可使用:

pip install gradio onnxruntime numpy Pillow

运行后可以显示这样的效果,我们可以上传图片以获得结果。

HuggingFace上部署Gradio

那假如我们不想单单在本地部署,而是希望能够一直分享给别人(本地分享的话只有72h的保留时间),那我们就需要把模型部署在HuggingFace上然后分享出去。

首先我们需要登录到HuggingFace上,并且在右上角找到+ new spaces。

进入后创建自己Space的名字,然后再选择下面的Gradio平台。硬件的话就按默认的就可以,我们都可以免费使用CPU来进行推理,假如要高级一点的硬件的话就需要花费了。最后我们选择公开(Public)或者私有(Private)模型后,就可以点击创建Space(Create Space)了。

然后我们需要点击右上角的Files并把end2end.onnx文件上传到HuggingFace平台上。

然后我们要新建一个文件并把命名为app.py后,将代码复制进去。

然后再新建一个名为requirements.txt的文件,并把需要安装的库放入。

最后我们点击一下右上角的APP,等待一段时间配置环境,我们就能够把模型部署在HuggingFace上了。

我们上传之前的图片看看效果如何。

可以看到模型真的被运行在了云端上了,并且能够基于免费的硬件资源进行长期的部署!大家也可以通过这个链接来进行尝试。

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

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

相关文章

易保全网络赋强公证系统,“公证赋强+科技赋能”双重增信

网络赋强公证系统是一种创新的法律服务模式&#xff0c;旨在通过线上方式赋予债权文书强制执行效力。具体来说&#xff0c;该系统结合了互联网技术与公证业务&#xff0c;允许公证机构根据当事人的申请&#xff0c;利用互联网公证技术手段对互联网上的债权文书进行公证&#xf…

移动端浏览器的扫描二维码实现(vue-qrcode-reader与jsQR方式)

1. 实现功能 类似扫一扫的功能&#xff0c;自动识别到画面中的二维码并进行识别&#xff0c;也可以选择从相册中上传。 2. 涉及到的一些插件介绍 vue-qrcode-reader 一组用于检测和解码二维码的Vue.js组件 jsQR 一个纯粹的javascript二维码阅读库&#xff0c;该库接收原始…

Activity->Activity中动态添加Fragment->add和replace方式添加的区别

XML文件 Activity布局文件R.layout.activity_main <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/root_ll"android:orientation"v…

操作系统期末复习(大题)

1. 进程调度 周转时间作业完成时刻-作业到达时刻 带权周转时间周转时间/服务时间 平均周转时间各个作业周转时间之和/作业个数 操作系统&#xff1a;周转时间和其他时间_系统为作业提供的时间-CSDN博客 2. 进程调度 3. 调度算法 4. 临界区互斥访问问题 即证明是否满足互斥&a…

mac环境基于llama3和metaGPT自动开发2048游戏

1.准备虚拟环境 conda create -n metagpt python3.9 && conda activate metagpt 2.安装metagpt pip install --upgrade metagpt 3.初始化配置文件 metagpt --init-config 4. 安装llama3 5. 修改配置文件 6.让metegpt自动开发2048游戏 7.经过多轮迭代&#xff0c;最终…

抖音 根据sec uid获取个人详细信息(性别、年龄、属地、关注数、粉丝数、简介等)

本文带来用户的secuid获取用户信息以及其他基本信息&#xff1a; 话不多说看效果&#xff1a; 第一步输入用户sec_uid 根据secuid获取到用户基本信息&#xff1a; 可以支持接口批量转换&#xff0c;欢迎咨询

国内著名的四个“大模型”

关于您提到的国内四大模型&#xff0c;这里为您详细介绍&#xff1a; 文心大模型&#xff1a;文心大模型是百度自主研发的产业级知识增强大模型。它以创新性的知识增强技术为核心&#xff0c;从单模态大模型发展到跨模态&#xff0c;从通用基础大模型到跨领域、跨行业&#xff…

05 Linux 内核启动流程

1、阅读 Linux 内核源码 学习 Linux 有两种路线&#xff1a; 1&#xff09;按照 Linux 启动流程&#xff0c;梳理每个子系统。 2&#xff09;把 Linux 所有用到的子系统学会&#xff0c;再组合起来。 博主选择第一种方式&#xff0c;可以快速上手&#xff0c;知道自己在学什…

5.mongodb 备份与恢复

mongodb备份工具介绍&#xff1a; 1.mongoexport(备份)/mongoimport(恢复) mongoexport是MongoDB提供的一个工具&#xff0c;用于将数据从MongoDB实例导出到JSON或CSV格式的文件中&#xff0c;这个工具对于数据迁移、数据备份或者在不同的数据库之间同步数据非常有用 2.mongodu…

鱼泡-伙伴匹配系统

第一次直播 项目介绍 帮助找到志同道合的伙伴 需求分析 标签分类 主动搜索 组队 创建队伍加入队伍根据标签查询队伍 前端项目初始化 项目初始化文件夹中一定不要带空格&#xff01; 使用npm&#xff08;node包管理器&#xff09;来安装 Vite 脚手架&#xff1a; vue cl…

USB (5)

USB是一个poll的总线。并且数据传输是对齐到time-line的。 对于比如鼠标这样的设备&#xff0c;主机会最快125us poll一次&#xff0c;看是否有输入。这也就是interrupt transfer类型。 对于isochronous transfer类型&#xff0c;数据是在固定的时隙传输的&#xff0c;但不保证…

Python魔法之旅-魔法方法(22)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

怎么改图片分辨率的dpi数值?简单调整图片dpi的方法

图片分辨率的dpi是目前使用图片时比较常见的要求之一&#xff0c;在网上上传图片时比如证件照类型&#xff0c;都经常会对图片dpi数值有要求。在使用图片的时候&#xff0c;如果dpi的数值不满足用户使用&#xff0c;那么就会无法正常上传使用&#xff0c;那么修改图片api具体该…

42.vue-element-admin界面上的search字段配置

vue-element-admin界面上的search字段&#xff08;下图红色部分&#xff09;是可配置&#xff0c;使用*.vue里的search关键字进行配置。 一、配置方法 1.如果这个字段要放到search区域&#xff0c;则&#xff1a; search: {hidden: false}, 2.如果这个字段不要放到search区域…

实验七、创建小型实验拓扑《计算机网络》

早检到底是谁发明出来的。 一、实验目的 完成本实验后&#xff0c;您将能够&#xff1a; • 设计逻辑网络。 • 配置物理实验拓扑。 • 配置 LAN 逻辑拓扑。 • 验证 LAN 连通性。 二、实验任务 在本实验中&#xff0c;将要求您连接网络设备并配置主机实现基本的网络…

贪心算法-数组跳跃游戏(mid)

目录 一、问题描述 二、解题思路 1.回溯法 2.贪心算法 三、代码实现 1.回溯法实现 2.贪心算法实现 四、刷题链接 一、问题描述 二、解题思路 1.回溯法 使用递归的方式&#xff0c;找到所有可能的走步方式&#xff0c;并记录递归深度&#xff08;也就是走步次数&#x…

【AI法官】人工智能判官在线判案?

概述 AI法官是一款为用户提供专业法律分析和判决建议的智能体应用。用户只需简要描述案情&#xff0c;AI法官便会利用其强大的法律知识和逻辑推理能力&#xff0c;快速且准确地梳理出判决结果。该应用的目标是为用户提供高效、准确、合法的判决建议。 角色任务 任务描述 作为…

小程序 UI 风格魅力非凡

小程序 UI 风格魅力非凡

Oracle的优化器

sql优化第一步&#xff1a;搞懂Oracle中的SQL的执行过程 从图中我们可以看出SQL语句在Oracle中经历了以下的几个步骤&#xff1a; 语法检查&#xff1a;检查SQL拼写是否正确&#xff0c;如果不正确&#xff0c;Oracle会报语法错误。 语义检查&#xff1a;检查SQL中的访问对象…

海南聚广众达电子商务咨询有限公司打造一站式电商服务

在数字经济的浪潮中&#xff0c;电商行业蓬勃发展&#xff0c;各种平台和服务商如雨后春笋般涌现。其中&#xff0c;海南聚广众达电子商务咨询有限公司凭借其专业的团队和丰富的经验&#xff0c;在抖音电商服务领域独树一帜&#xff0c;成为业界的佼佼者。 海南聚广众达电子商…