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

news2024/11/18 19:29:07

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

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 argparse

import cv2
from mmdeploy_runtime import Classifier

def 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 args

def 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 CHW
    image = 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.coloradmin.cn/o/1811878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

正则表达式(Linux 下搭配 grep 使用)

目录 1.基本正则表达式 2.扩展正则表达式 3.实操之grep筛选 3.1基本正则表达式 3.2扩展正则表达式 1.基本正则表达式 ^ 用于最左端,如^"abc",匹配以abc开头的行 $ 用于最右端,如"abc$",匹配以abc结尾的行 ^$ …

使用Oracle VM VirtualBox安装Centos7

下载软件 VirtualBox下载&#xff1a; https://www.virtualbox.org/ CentOS7下载&#xff1a;http://mirrors.aliyun.com/centos/7/isos/x86_64/(阿里云镜像下载快) VirtualBox下载好之后&#xff0c;双击运行后&#xff0c;根据提示直接下一步到底就行了。 下面开始安装cent…

接连获得2项认可!细探美创信创数据安全方案与实践

信创浪潮奔涌向前&#xff0c;筑信创防线&#xff0c;守数据安全&#xff0c;近年来&#xff0c;美创科技率先布局&#xff0c;持续在信创产品类型、产品更新迭代、国产信创改造服务、解决方案、生态建设等方面创新与实践&#xff0c;以满足各行业用户数据安全建设需求&#xf…

Redis为何如此快与其线程模型

Redis是单线程的为什么如此快 ①redis是基于内存的 首先,Redis 是基于内存的数据库&#xff0c;不论读写操作都是在内存上完成的&#xff0c;完全吊打磁盘数据库的速度。 ②Redis是单线程模型&#xff0c;从而避开了多线程中上下文频繁切换的操作 Redis 的单线程指的是 Red…

(2024,选择性遗忘,积极遗忘,消极遗忘)机器学习及其他领域的“遗忘”:综述

"Forgetting" in Machine Learning and Beyond: A Survey 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0 摘要 1 引言 2 不同知识领域中的遗忘背景 2.1 心理学中的遗忘&…

responses-validator接口断言之状态码

概述 responses-validator 专用于对 reqeuests 的响应对象进行断言&#xff0c; 同时&#xff0c;为了更适用 yaml 的场景&#xff0c;支持了多种灵活、可扩展的写法&#xff0c;可用于搭建yaml接口自动化测试框架。 根据 reqeuests 响应对象的特点&#xff0c;responses-val…

电流监测利器!FP137宽共模范围高侧轨电流测量IC助您解决电流问题!

随着大量包含高精度放大器和精密匹配电阻的IC的推出&#xff0c;在高侧电流测量中使用差分放大器变得非常方便。高侧检测带动了电流检测IC的发展&#xff0c;降低了由分立器件带来的参数变化、器件数目太多等问题&#xff0c;集成电路方便了我们使用。本文将对FP137高端电流检测…

用Vue3构建一个交互式3D图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 代码相关的技术博客 应用场景介绍 本代码段用于创建可用于展示服务或产品计划的卡片式组件。此类组件常见于网站或应用程序中&#xff0c;用于以清晰简洁的方式呈现不同级别的功能和定价信息。 代码基本功能…

Pycharm将python程序打包为exe文件

前提&#xff1a;我的文件只有一个&#xff0c;多个的还没有试过 打开项目终端 s1&#xff1a;在项目终端输入&#xff08;注意要在自己的项目下&#xff09; pip install pyinstaller s2&#xff1a;在项目终端输入&#xff08;注意要在自己的项目下&#xff09; pyinstaller …

香港国际ESG联盟:绿色能源时代的先锋力量

在香港国际ESG联盟引领绿色能源革命浪潮的今天&#xff0c;ESG联盟正以矢志不渝的精神推动大陆储能市场的繁荣与进步&#xff0c;同时立足于香港这一国际金融之都&#xff0c;ESG联盟的视野早已超越地域界限&#xff0c;向中国内地乃至全球市场延伸开来。联盟始终秉承着创新开放…

大模型生成短视频

最近看到一个开源项目可以通过AI生成短视频&#xff0c;然后尝试了下&#xff0c;感觉还不错&#xff0c;下面是具体步骤。 项目名叫moneyprinterTurbo&#xff0c;它本意是对接到Youtube&#xff0c;自动生成视频并上传到Youtube获取流量赚钱&#xff0c;所以项目名叫moneypri…

图形和插图软件Canvas X Pro 20 Build 914

Canvas X Pro是一款功能强大、用途广泛的Windows软件,旨在处理技术图形和可视化,该程序结合了创建矢量和光栅图形的工具,这使其成为需要创建高质量技术插图和演示文稿的工程师、设计师、科学家和其他专业人士的理想选择。 Canvas X Pro的主要功能之一是支持处理大型和复杂的…

ssm职工健康素养数据管理系统设计与实现-计算机毕业设计源码45392

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对职工健康素养数据管理系统等问题&#xff0…

SpringBoot基础配置文件

在SpringBoot当中, 所有的配置文件都将会被配置在application.preperties当中 一: 配置服务器端口 只需要在相应的properties当中输入, 修改我们的端口号即可 server.port80 二: 修改banner #设置 将我们的Banner不再进行显示, 或者是也可以让其在控制台当中显示, 或者是日…

Python 全栈体系【四阶】(五十九)

第五章 深度学习 十三、自然语言处理&#xff08;NLP&#xff09; 4. 语言模型 4.1 什么是语言模型 语言模型在文本处理、信息检索、机器翻译、语音识别中承担这重要的任务。从通俗角度来说&#xff0c;语言模型就是通过给定的一个词语序列&#xff0c;预测下一个最可能的词…

外包SEO如何进行?

当你的业务需要外包seo时&#xff0c;首先选择一个信誉良好且经验丰富的SEO服务提供商至关重要&#xff0c;深入研究其过往案例和客户评价可以帮助你评估他们的专业性和可靠性。 在选择了合适的服务商后&#xff0c;你需要与他们进行深入的沟通&#xff0c;讨论你的业务特点、市…

信贷背后的大秘密:贷后管理的作用与智慧

很多朋友可能都听过“贷后管理”这个词&#xff0c;尤其是在征信报告的查询记录里&#xff0c;它经常是出现频率最高的。很多人可能觉得贷后管理就是走过场&#xff0c;没啥大用&#xff0c;其实&#xff0c;这背后可是大有门道的。 贷后管理到底是个啥&#xff1f; 贷后管理&a…

SpringBoot+layui实现商品打标

标题 下拉框组件效果图代码实现前端界面产品打标页面代码 后端代码controllerservice ,serviceImplmappermapper.xmlentity 数据库表 下拉框组件 xm-select 效果图 代码实现 前端界面 <script type"text/html" id"stockTags"><div><div&…

Redis实战篇4:发布博客与点赞

一、博客 关于发布博客这个功能&#xff0c;他就是mysql相关的数据库&#xff0c;不涉及到redis&#xff0c;但是我们可以来看一下其相关的表的功能来了解一下&#xff1a; 博客表&#xff1a; 与其对应的评论表&#xff1a; 关于其数据库的设计也应该好好的学习一下。 二…

盲盒小程序开发:传统与当代的创新融合

谈起盲盒&#xff0c;许多人并不陌生。近几年&#xff0c;盲盒一直是年轻人首选的娱乐消费方式&#xff0c;小小的盲盒为消费者带来了极大的欢乐。 盲盒小程序是将传统的盲盒玩法与线上购物方式相融合&#xff0c;对拆盲盒进行创新&#xff0c;为盲盒消费者带来全新的盲盒体验…