YOLOv9 实战指南:打造个性化视觉识别利器,从零开始训练你的专属测试集

news2024/9/24 11:22:37

论文地址:YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information

GitHub:WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information (github.com)


一、摘要

今天的深度学习方法侧重于如何设计最合适的目标函数,从而使模型的预测结果能够最接近真实标签。同时,设计一个合适的体系结构,可以获取足够的信息进行预测。现有的方法忽略了输入数据在进行分层特征提取和空间转换时,会丢失大量信息。

本文研究数据通过深度网络传输时数据丢失的重要问题,即信息瓶颈和可逆函数。并且提出了可编程梯度信息(PGI)的概念,以应对深度网络实现多个目标所需的各种变化。PGI可以为目标任务提供完整的输入信息来计算目标函数,从而获得可靠的梯度信息来更新网络权值。

此外,还设计了一种基于梯度路径规划的新型轻量级网络体系结构——广义高效层聚合网络(GELAN)。GELAN的架构证实了PGI在轻量级模型上获得了更好的结果。并且基于MS COCO数据集的目标检测上验证了所提出的GELAN和PGI。结果表明,GELAN只使用传统的卷积算子来比基于深度卷积的先进方法获得更好的参数利用。

PGI可用于从轻量级到大型的各种模型。可以用来获得完整的信息,因此,从头开始训练的模型可以比使用大数据集预先训练的最先进的模型获得更好的结果。

在MS COCO数据集中,基于GELAN和PGI的目标检测方法在目标检测性能方面超过了以往所有的从头训练方法,在精度方面,新方法优于大数据集预训练的RT DETR,在参数利用方面也优于基于深度卷积的设计YOLO MS。

二、配置YOLOv9

2.1、下载yolov9

git clone https://github.com/WongKinYiu/yolov9.git

2.2、创建conda环境

conda create -n yolov9 python==3.8

然后切换到yolov9目录下,找到requirements.txt文件(yolov9需要的库)

# 1、激活yolov9
conda activate yolov9

# 2、切换地址
cd yolov9

# 3、安装相关库
pip install -r requirements.txt

注意:本文忽略了anaconda的安装和cuda、cudnn的安装过程

三、数据划分

环境都配置完成之后,开始对测试集进行划分,本文选择了一个insect测试集(包含7个类别['Leconte','Boerner','linnaeus','armandi','coleoptera','acuminatus','Linnaeus'])如下图所示

images:训练集和验证集

labels:训练集和验证集的标签

train.txt和val.txt:需要生成的列表(对于每个图片的地址)

test:测试集

train.cache和val.cache:训练过程中生成的

3.1、数据可视化

看下标签

<annotation>
	<folder>xxx</folder>
	<filename>1.jpeg</filename>
	<path>/home/fion/桌面/xxx/1.jpeg</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>1344</width>
		<height>1344</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>Leconte</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>473</xmin>
			<ymin>578</ymin>
			<xmax>612</xmax>
			<ymax>727</ymax>
		</bndbox>
	</object>
	<object>
		<name>Boerner</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>822</xmin>
			<ymin>505</ymin>
			<xmax>948</xmax>
			<ymax>639</ymax>
		</bndbox>
	</object>
	<object>
		<name>linnaeus</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>607</xmin>
			<ymin>781</ymin>
			<xmax>690</xmax>
			<ymax>842</ymax>
		</bndbox>
	</object>
	<object>
		<name>armandi</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>756</xmin>
			<ymin>786</ymin>
			<xmax>841</xmax>
			<ymax>856</ymax>
		</bndbox>
	</object>
	<object>
		<name>coleoptera</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>624</xmin>
			<ymin>488</ymin>
			<xmax>711</xmax>
			<ymax>554</ymax>
		</bndbox>
	</object>
</annotation>

xml文件解析:

xml.etree.ElementTree库在Python中提供了多种处理XML数据的方法。以下是一些常见的用法:

1. 解析XML字符串:
   使用ET.fromstring(xml_string)可以从一个XML格式的字符串创建一个元素对象,并作为树的根节点。

2. 解析XML文件:
   使用ET.parse(file_path)可以加载并解析一个XML文件,返回一个树的根节点。

3. 获取元素标签和属性:
   使用element.tag获取元素的标签名称;使用`element.attrib`获取元素的属性字典。

4. 查找子元素:
   使用element.find(tag)查找第一个匹配的子元素;使用`element.findall(tag)`查找所有匹配的子元素。

5. 遍历元素:
   使用`element.iter()`或`element.iter(tag)`可以迭代遍历元素的所有后代元素。

等等......

这些是`xml.etree.ElementTree`库的一些基本用法,涵盖了解析、查询、修改和创建XML数据的常见操作。

import numpy as np
import os,cv2,sys

try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

def plot_image():
    # 数据的类别
    INSECT_NAMES = ['Leconte','Boerner','linnaeus','armandi','coleoptera','acuminatus','Linnaeus']
    # 不同类别给不同颜色
    COLOR_NAMES = {'Leconte':(255,0,0),'Boerner':(0,255,0),'linnaeus':(0,0,255),'armandi':(0,0,0),
                   'coleoptera':(255,255,0),'acuminatus':(148,0,211),'Linnaeus':(255,255,255)}
    img_dir = r"E:\YOLO_insects\insects\train\images"
    xml_dir = r"E:\YOLO_insects\insects\train\annotations\xmls"
    save_dir = r"E:\YOLO_insects\insects\imshow"
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    for i in os.listdir(img_dir):
        img_path = os.path.join(img_dir, i)
        xml_path = os.path.join(xml_dir, i.split(".")[0]+".xml")
        img = cv2.imread(img_path)
        root = ET.parse(xml_path).getroot()
        for obj in root.findall('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            size = root.find('size')
            w = int(size.find('width').text)
            h = int(size.find('height').text)
            if cls not in INSECT_NAMES or int(difficult) == 1:
                continue
            cls_id = INSECT_NAMES.index(cls)
            xml_box = obj.find('bndbox')
            b = (float(xml_box.find('xmin').text), float(xml_box.find('xmax').text),
                 float(xml_box.find('ymin').text), float(xml_box.find('ymax').text))
            print(f"{cls}")
            cv2.rectangle(img, (int(b[0]),int(b[2])),(int(b[1]),int(b[3])), COLOR_NAMES[str(cls)],3)
            cv2.putText(img, cls,(int(b[0]),int(b[2])-5),cv2.FONT_HERSHEY_SIMPLEX,0.5,COLOR_NAMES[str(cls)],2,cv2.LINE_AA)
        cv2.imwrite(os.path.join(save_dir,i), img)

3.2、测试集标签转换

因为本文测试集已划分好了train、val和test,因此下面跳过了数据集划分部分,下面看下如何生成yolo所需的标签格式

代码部分:

import numpy as np
import os,cv2,sys

try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET


def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return x, y, w, h


def generate_labels():
    train_dir = r'E:\YOLO_insects\insects\val\annotations\xmls'
    train_xml = './insects/labels/val'
    if not os.path.exists(train_xml):
        os.makedirs(train_xml,exist_ok=True)

    num = 0
    classes = ['Leconte','Boerner','linnaeus','armandi','coleoptera','acuminatus','Linnaeus']
    for file in os.listdir(train_dir):
        xml_path = os.path.join(train_dir,file)
        outfile = open(os.path.join(train_xml,file.split(".xml")[0]+".txt"),'w',encoding="utf8")
        num +=1
        print(xml_path)
        content = ET.parse(xml_path)
        root = content.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)
        channel = int(size.find('depth').text)
        print(f"size: {w}x{h}, channel: {channel}")
        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            # classes.append(cls) # 可以查看有哪些类
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xml_box = obj.find('bndbox')
            b = (float(xml_box.find('xmin').text), float(xml_box.find('xmax').text),
                 float(xml_box.find('ymin').text),float(xml_box.find('ymax').text))
            b1, b2, b3, b4 = b
            # 标注越界修正
            if b2 > w:
                b2 = w
            if b4 > h:
                b4 = h
            b = (b1, b2, b3, b4)
            bbox = convert((w,h),b)
            print(bbox)
            outfile.write(str(cls_id) + " " + " ".join([str(i) for i in bbox]) + "\n")

    print(f"total_num:{num}")

标签生成之后,生成测试列表

def produce_txt(input_dir=r'E:\yolov9\data\insects\images\val', output_file=r"E:\yolov9\data\insects\val.txt"):
    with open(output_file, 'w') as f:
        for root, dirs, files in os.walk(input_dir):
            for file in files:
                file_path = os.path.join(root, file)
                f.write(file_path + '\n')

四、开始训练

4.1、在github里下载yolov9-c.pt文件

存放位置随意

4.2、创建对应的yaml配置文件

yolov9/data/insect.yaml
path: E:\yolov9\data\insects  # dataset root dir
train: train.txt  # train images (relative to 'path')
val: val.txt  # val images (relative to 'path')

# Classes
names: ['Leconte','Boerner','linnaeus','armandi','coleoptera','acuminatus','Linnaeus']

4.3、修改yolov9-c.yaml文件中的类别数目

# YOLOv9

# parameters
nc: 7  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()

# anchors
anchors: 3

4.4、配置train_dual.py参数

--weights:设置下载好的yolov9-c.pt文件地址
--cfg:选择yolov9-c.yaml
--data:自己创建的配置文件
--imgsz:图像的尺寸:我这里图设置320,也可以设置640
--batch-size:批次大小,太大可能跑不了
--epoch:训练epoch次数
其他参数都是选择默认值
def parse_opt(known=False):
    parser = argparse.ArgumentParser()
    # parser.add_argument('--weights', type=str, default=ROOT / 'yolo.pt', help='initial weights path')
    # parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
    parser.add_argument('--weights', type=str, default='weights/yolov9-c.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='models/detect/yolov9-c.yaml', help='model.yaml path')
    parser.add_argument('--data', type=str, default='data/insect.yaml', help='dataset.yaml path')
    parser.add_argument('--hyp', type=str, default='data/hyps/hyp.scratch-high.yaml', help='hyperparameters path')
    parser.add_argument('--epochs', type=int, default=20, help='total training epochs')
    parser.add_argument('--batch-size', type=int, default=8, help='total batch size for all GPUs, -1 for autobatch')
    parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=320, help='train, val image size (pixels)')
    parser.add_argument('--rect', action='store_true', help='rectangular training')
    parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
    parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
    parser.add_argument('--noval', action='store_true', help='only validate final epoch')
    parser.add_argument('--noautoanchor', action='store_true', help='disable AutoAnchor')
    parser.add_argument('--noplots', action='store_true', help='save no plot files')
    parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations')
    parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
    parser.add_argument('--cache', type=str, nargs='?', const='ram', help='image --cache ram/disk')
    parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
    parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
    parser.add_argument('--optimizer', type=str, choices=['SGD', 'Adam', 'AdamW', 'LION'], default='SGD', help='optimizer')
    parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
    parser.add_argument('--workers', type=int, default=0, help='max dataloader workers (per RANK in DDP mode)')
    parser.add_argument('--project', default=ROOT / 'runs/train', help='save to project/name')
    parser.add_argument('--name', default='exp', help='save to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--quad', action='store_true', help='quad dataloader')
    parser.add_argument('--cos-lr', action='store_true', help='cosine LR scheduler')
    parser.add_argument('--flat-cos-lr', action='store_true', help='flat cosine LR scheduler')
    parser.add_argument('--fixed-lr', action='store_true', help='fixed LR scheduler')
    parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
    parser.add_argument('--patience', type=int, default=10, help='EarlyStopping patience (epochs without improvement)')
    parser.add_argument('--freeze', nargs='+', type=int, default=[0], help='Freeze layers: backbone=10, first3=0 1 2')
    parser.add_argument('--save-period', type=int, default=-1, help='Save checkpoint every x epochs (disabled if < 1)')
    parser.add_argument('--seed', type=int, default=0, help='Global training seed')
    parser.add_argument('--local_rank', type=int, default=-1, help='Automatic DDP Multi-GPU argument, do not modify')
    parser.add_argument('--min-items', type=int, default=0, help='Experimental')
    parser.add_argument('--close-mosaic', type=int, default=0, help='Experimental')

    # Logger arguments
    parser.add_argument('--entity', default=None, help='Entity')
    parser.add_argument('--upload_dataset', nargs='?', const=True, default=False, help='Upload data, "val" option')
    parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval')
    parser.add_argument('--artifact_alias', type=str, default='latest', help='Version of dataset artifact to use')

    return parser.parse_known_args()[0] if known else parser.parse_args()

4.5、开始训练

直接运行:train_dual.py

16 epochs completed in 6.767 hours.
Optimizer stripped from runs\train\exp3\weights\last.pt, 102.8MB
Optimizer stripped from runs\train\exp3\weights\best.pt, 102.8MB

Validating runs\train\exp3\weights\best.pt...
Fusing layers...
yolov9-c summary: 604 layers, 50712138 parameters, 0 gradients, 236.7 GFLOPs
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 16/16 01:11
                   all        245       1856      0.743      0.782      0.836      0.588
               Leconte        245        594       0.92      0.871      0.964      0.714
               Boerner        245        318       0.85      0.893      0.928      0.722
               armandi        245        231      0.611      0.754      0.712      0.497
            coleoptera        245        186      0.437      0.909      0.757      0.456
            acuminatus        245        235      0.763        0.8       0.86      0.555
              Linnaeus        245        292      0.877      0.464      0.796      0.584

训练过程中在runs/train目录下生成中间文件,如下图

五、模型测试

5.1、修改detect_dual.py文件

--weights:训练好的模型,选择best.pt
--source:设置测试图片地址,或者采用电脑摄像头,设置为0时
--data:自己创建的insect.yaml配置文件
--imgsz:这里选择320,和训练时保持一致
其他参数选择默认配置
def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'runs/train/exp3/weights/best.pt', help='model path or triton URL')
    # parser.add_argument('--source', type=str, default=ROOT / 'E:\yolov9\data\insects\\test', help='file/dir/URL/glob/screen/0(webcam)')
    parser.add_argument('--source', type=str, default=ROOT / 'E:\YOLO_insects\insects\\test\images',help='file/dir/URL/glob/screen/0(webcam)')
    parser.add_argument('--data', type=str, default=ROOT / 'data/insect.yaml', help='(optional) dataset.yaml path')
    parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[320], help='inference size h,w')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
    parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='show results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--visualize', action='store_true', help='visualize features')
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default=ROOT / 'runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
    parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')
    parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
    parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
    parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')
    parser.add_argument('--vid-stride', type=int, default=1, help='video frame-rate stride')
    opt = parser.parse_args()
    opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1  # expand
    print_args(vars(opt))
    return opt

在runs\detect\exp目录下生成对应的测试效果图

六、遇到的问题

AttributeError: 'FreeTypeFont' object has no attribute 'getsize'

这个问题 主要是:

'FreeTypeFont' object has no attribute 'getsize', is caused by a compatibility problem with the new version of Pillow.

# 1、查看pillow的版本
conda list

# 2、卸载高版本安装9.5版本
pip uninstall pillow

pip install pillow==9.5

参考博客:

1、YOLOv9目标识别——详细记录训练环境配置与训练自己的数据集_yolov9训练自己的数据集-CSDN博客

2、YOLOv9如何训练自己的数据集(NEU-DET为案列)_yolov9训练自己的数据集-CSDN博客

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

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

相关文章

Unity 背包系统中拖拽物体到指定位置或互换位置效果的实现

在Unity中&#xff0c;背包系统是一种常见的游戏系统&#xff0c;可以用于管理和展示玩家所持有的物品、道具或装备。 其中的拖拽功能非常有意思&#xff0c;具体功能就是玩家可以通过拖拽物品图标来移动物品在背包中的位置&#xff0c;或者将物品拖拽到其他位置或界面中&…

Q-Day提前?IBM警告:「量子+AI」将触发巨大风险!

Q-Day&#xff0c;即量子计算机强大到足以破解当前加密方案的时刻&#xff0c;原本被视为一个从近期到长期可能面临的挑战&#xff0c;而非刻不容缓的现实问题。然而&#xff0c;最新的研究发现似乎加速了这一天的到来。 IBM的研究团队在一篇论文中提出&#xff0c;混合量子经典…

linux 区别:mount 一个目录到另外一个目录,目录软链接 (*)

Linux命令200例&#xff1a;mount将文件系统挂载到指定目录下&#xff08;常用&#xff09; https://blog.csdn.net/qq_21891743/article/details/132220283 Linux磁盘卸载 https://blog.csdn.net/Mcy7ycM/article/details/124347504 能否通俗易懂&#xff0c;深入浅出地解释…

【数据结构】顺序表的实现——静态分配

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

ZNB20罗德与施瓦茨ZNB20网络分析仪

181/2461/8938产品概述&#xff1a; 罗德与施瓦茨 ZNB20 矢量网络分析仪具有高达 140 dB 的宽动态范围&#xff08;在 10 Hz IF 带宽时&#xff09;、低于 0.004 dB RMS 的低迹线噪声&#xff08;在 10 kHz IF 带宽时&#xff09;以及高达 的高输出功率13 dBm&#xff0c;可在…

Zabbix-告警

基本概念 一、介绍 自定义的监控项默认不会自动报警 首页也不会提示错误 需要配置触发器与报警动作才可以自动报警 二、触发器 表达式&#xff0c;如内存不足300M&#xff0c;用户超过30个等 当触发条件发生后&#xff0c;会导致一个触发事件 触发事件会执行某个动作 …

网络编程综合项目-多用户通信系统

文章目录 1.项目所用技术栈本项目使用了java基础&#xff0c;面向对象&#xff0c;集合&#xff0c;泛型&#xff0c;IO流&#xff0c;多线程&#xff0c;Tcp字节流编程的技术 2.通信系统整体分析主要思路&#xff08;自己理解&#xff09;1.如果不用多线程2.使用多线程3.对多线…

ssh 公私钥(github)

一、生成ssh公私钥 生成自定义名称的SSH公钥和私钥对&#xff0c;需要使用ssh-keygen命令&#xff0c;这是大多数Linux和Unix系统自带的标准工具。下面&#xff0c;简单展示如何使用ssh-keygen命令来生成具有自定义名称的SSH密钥对。 步骤 1: 打开终端 首先&#xff0c;打开我…

vue前端工程化

前言 本文介绍的是有关于vue方面的前端工程化实践&#xff0c;主要通过实践操作让开发人员更好的理解整个前端工程化的流程。 本文通过开发准备阶段、开发阶段和开发完成三个阶段开介绍vue前端工程化的整体过程。 准备阶段 准备阶段我将其分为&#xff1a;框架选择、规范制…

AI智能分析网关智慧食安监管系统方案

3.15晚会刚过不久&#xff0c;淀粉肠的“屈辱”终于得以洗清&#xff0c;但某些品牌奶茶、梅菜扣肉、预制菜等等&#xff0c;生产过程仍是触目惊心。如何提升食品安全管理水平&#xff0c;保障食品从生产到消费环节的质量和安全&#xff1f;TSINGSEE青犀智利用智能分析网关V4Ea…

mysql--事务四大特性与隔离级别

事务四大特性与隔离级别 mysql事务的概念事务的属性事务控制语句转账示例 并发事务引发的问题脏读脏读场景 不可重复读幻读幻读场景 事务的隔离级别读未提交读已提交可重复读&#xff08;MySQL默认&#xff09; 总结 mysql事务的概念 事务就是一组操作的集合&#xff0c;他是一…

x86的内存分段机制

8086 是 Intel 公司第一款 16 位处理器&#xff0c;诞生于 1978 年&#xff0c;所以说它很古老。 一.8086 的通用寄存器 8086 处理器内部共有 8 个 16 位的通用处理器&#xff0c;分别被命名为 AX、 BX、 CX、 DX、 SI、 DI、 BP、 SP。如下图所示。 “通用”的意思是…

幻兽帕鲁服务器多少钱?可真便宜呀

2024年全网最全的幻兽帕鲁服务器租用价格表&#xff0c;阿里云幻兽帕鲁游戏服务器26元1个月、腾讯云32元一个月、京东云26元一个月、华为云24元1个月&#xff0c;阿腾云atengyun.com整理最新幻兽帕鲁专用4核16G、8核16G、8核32G游戏服务器租用价格表大全&#xff1a; 阿里云幻…

8、鸿蒙学习-HAR

HAR&#xff08;Harmony Archive&#xff09;是静态共享包&#xff0c;可以包含代码、C库、资源和配置文件。通过HAR可以实现多个模块或多个工程共享ArkUI组件、资源等相关代码。HAR不同于HAP&#xff0c;不能独立安装运行在设备上。只能作为应用模块的依赖项被引用。 一、创建…

【案例·增】获取当前时间、日期(含,SQL中DATE数据类型)

问题描述&#xff1a; 需要使用当前时间、日期&#xff0c;可以使用 SQL 中的 CURDATE() 、NOW()、CURTIME()运算符 案例&#xff1a; INSERT INTO table_name(current_time, column_name2,...) VALUES (NOW(),, ...)规则(Date 相关函数)&#xff1a; 规则(Date数据类型)

初识C++之命名空间(namespace)

初识C之入门 命名空间(namespace) 文章目录 初识C之入门 命名空间(namespace)1.为什么要有命名空间2. 命名空间 namespace使用方法3. 作用域限定符(::&#xff09;和 命名空间(namespace)4. 命名空间的定义5. 命名空间的嵌套6. 命名空间的使用7. 总结 1.为什么要有命名空间 在C…

通过Caliper进行压力测试程序,且汇总压力测试问题解决

环境要求 第一步. 配置基本环境 部署Caliper的计算机需要有外网权限;操作系统版本需要满足以下要求:Ubuntu >= 16.04、CentOS >= 7或MacOS >= 10.14;部署Caliper的计算机需要安装有以下软件:python 2.7、make、g++(gcc-c++)、gcc及git。第二步. 安装NodeJS # …

Tensorflow2.0笔记 - 自定义Layer和Model

本笔记主要记录如何在tensorflow中实现自定的Layer和Model。详细内容请参考代码中的链接。 import time import tensorflow as tf from tensorflow import keras from tensorflow.keras import datasets, layers, optimizers, Sequential, metricstf.__version__ #关于自定义l…

软考 - 系统架构设计师 - 关系模型的完整性规则

前言 关系模型的完整性规则是一组用于确保关系数据库中数据的完整性和一致性的规则。这些规则定义了在关系数据库中如何存储、更新和查询数据&#xff0c;以保证数据的准确性和一致性。 详情 关系模型的完整性规则主要包括以下三类&#xff1a; 实体完整性规则 这是确保每个…

【Java程序设计】【C00373】基于(JavaWeb)Springboot的社区疫情返乡管控系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…