DataWhale AI夏令营 2024大运河杯-数据开发应用创新赛-task3

news2024/9/20 18:40:52

DataWhale AI夏令营 2024大运河杯-数据开发应用创新赛

  • 数据增强
  • 数据收集
  • 打标签

多的不说少的不唠,之前说过初赛基本就是比谁的数据好了,因为原始数据的质量太低了想跑到0.25都很难所以需要使用一些数据增强策略以及收集一些新的数据集。

数据增强

计算机视觉中有一个应用比较广泛的包,来进行数据增强transforms,其中包含了一些图像增强的常见策略比如调整大小、裁剪、归一化、随机反转等等。如果大家想从事计算机视觉方面的工作可以去了解一下,这里我不过多赘述。
这里提供一份使用transforms进行数据增强的代码。

# -*- coding: utf-8 -*-
"""
Created on 2023-04-01 9:08
@author: Fan yi ming
Func: 对于目标检测的数据增强[YOLO](特点是数据增强后标签也要更改)
review:常用的数据增强方式;
        1.翻转:左右和上下翻转,随机翻转
        2.随机裁剪,图像缩放
        3.改变色调
        4.添加噪声
注意: boxes的标签和坐标一个是int,一个是float,存放的时候要注意处理方式。
参考:https://github.com/REN-HT/Data-Augmentation/blob/main/data_augmentation.py
"""
import torch
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFile

ImageFile.LOAD_TRUNCATED_IMAGES = True
from torchvision import transforms
import numpy as np
import matplotlib.pyplot as plt
import os
import random

random.seed(0)


class DataAugmentationOnDetection:
    def __init__(self):
        super(DataAugmentationOnDetection, self).__init__()

    # 以下的几个参数类型中,image的类型全部如下类型
    # 参数类型: image:Image.open(path)
    def resize_keep_ratio(self, image, boxes, target_size):
        """
            参数类型: image:Image.open(path), boxes:Tensor, target_size:int
            功能:将图像缩放到size尺寸,调整相应的boxes,同时保持长宽比(最长的边是target size
        """
        old_size = image.size[0:2]  # 原始图像大小
        # 取最小的缩放比例
        ratio = min(float(target_size) / (old_size[i]) for i in range(len(old_size)))  # 计算原始图像宽高与目标图像大小的比例,并取其中的较小值
        new_size = tuple([int(i * ratio) for i in old_size])  # 根据上边求得的比例计算在保持比例前提下得到的图像大小
        # boxes 不用变化,因为是等比例变化
        return image.resize(new_size, Image.BILINEAR), boxes

    def resizeDown_keep_ratio(self, image, boxes, target_size):
        """ 与上面的函数功能类似,但它只降低图片的尺寸,不会扩大图片尺寸"""
        old_size = image.size[0:2]  # 原始图像大小
        # 取最小的缩放比例
        ratio = min(float(target_size) / (old_size[i]) for i in range(len(old_size)))  # 计算原始图像宽高与目标图像大小的比例,并取其中的较小值
        ratio = min(ratio, 1)
        new_size = tuple([int(i * ratio) for i in old_size])  # 根据上边求得的比例计算在保持比例前提下得到的图像大小

        # boxes 不用变化,因为是等比例变化
        return image.resize(new_size, Image.BILINEAR), boxes

    def resize(self, img, boxes, size):
        # ---------------------------------------------------------
        # 类型为 img=Image.open(path),boxes:Tensor,size:int
        # 功能为:将图像长和宽缩放到指定值size,并且相应调整boxes
        # ---------------------------------------------------------
        return img.resize((size, size), Image.BILINEAR), boxes

    def random_flip_horizon(self, img, boxes, h_rate=1):
        # -------------------------------------
        # 随机水平翻转
        # -------------------------------------
        if np.random.random() < h_rate:
            transform = transforms.RandomHorizontalFlip(p=1)
            img = transform(img)
            if len(boxes) > 0:
                x = 1 - boxes[:, 1]
                boxes[:, 1] = x
        return img, boxes

    def random_flip_vertical(self, img, boxes, v_rate=1):
        # 随机垂直翻转
        if np.random.random() < v_rate:
            transform = transforms.RandomVerticalFlip(p=1)
            img = transform(img)
            if len(boxes) > 0:
                y = 1 - boxes[:, 2]
                boxes[:, 2] = y
        return img, boxes

    def center_crop(self, img, boxes, target_size=None):
        # -------------------------------------
        # 中心裁剪 ,裁剪成 (size, size) 的正方形, 仅限图形,w,h
        # 这里用比例是很难算的,转成x1,y1, x2, y2格式来计算
        # -------------------------------------
        w, h = img.size
        size = min(w, h)
        if len(boxes) > 0:
            # 转换到xyxy格式
            label = boxes[:, 0].reshape([-1, 1])
            x_, y_, w_, h_ = boxes[:, 1], boxes[:, 2], boxes[:, 3], boxes[:, 4]
            x1 = (w * x_ - 0.5 * w * w_).reshape([-1, 1])
            y1 = (h * y_ - 0.5 * h * h_).reshape([-1, 1])
            x2 = (w * x_ + 0.5 * w * w_).reshape([-1, 1])
            y2 = (h * y_ + 0.5 * h * h_).reshape([-1, 1])
            boxes_xyxy = torch.cat([x1, y1, x2, y2], dim=1)
            # 边框转换
            if w > h:
                boxes_xyxy[:, [0, 2]] = boxes_xyxy[:, [0, 2]] - (w - h) / 2
            else:
                boxes_xyxy[:, [1, 3]] = boxes_xyxy[:, [1, 3]] - (h - w) / 2
            in_boundary = [i for i in range(boxes_xyxy.shape[0])]
            for i in range(boxes_xyxy.shape[0]):
                # 判断x是否超出界限
                if (boxes_xyxy[i, 0] < 0 and boxes_xyxy[i, 2] < 0) or (
                        boxes_xyxy[i, 0] > size and boxes_xyxy[i, 2] > size):
                    in_boundary.remove(i)
                # 判断y是否超出界限
                elif (boxes_xyxy[i, 1] < 0 and boxes_xyxy[i, 3] < 0) or (
                        boxes_xyxy[i, 1] > size and boxes_xyxy[i, 3] > size):
                    in_boundary.append(i)
            boxes_xyxy = boxes_xyxy[in_boundary]
            boxes = boxes_xyxy.clamp(min=0, max=size).reshape([-1, 4])  # 压缩到固定范围
            label = label[in_boundary]
            # 转换到YOLO格式
            x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
            xc = ((x1 + x2) / (2 * size)).reshape([-1, 1])
            yc = ((y1 + y2) / (2 * size)).reshape([-1, 1])
            wc = ((x2 - x1) / size).reshape([-1, 1])
            hc = ((y2 - y1) / size).reshape([-1, 1])
            boxes = torch.cat([xc, yc, wc, hc], dim=1)
        # 图像转换
        transform = transforms.CenterCrop(size)
        img = transform(img)
        if target_size:
            img = img.resize((target_size, target_size), Image.BILINEAR)
        if len(boxes) > 0:
            return img, torch.cat([label.reshape([-1, 1]), boxes], dim=1)
        else:
            return img, boxes

    # ------------------------------------------------------
    # 以下img皆为Tensor类型
    # ------------------------------------------------------

    def random_bright(self, img, u=120, p=1):
        # -------------------------------------
        # 随机亮度变换
        # -------------------------------------
        if np.random.random() < p:
            alpha = np.random.uniform(-u, u) / 255
            img += alpha
            img = img.clamp(min=0.0, max=1.0)
        return img

    def random_contrast(self, img, lower=0.5, upper=1.5, p=1):
        # -------------------------------------
        # 随机增强对比度
        # -------------------------------------
        if np.random.random() < p:
            alpha = np.random.uniform(lower, upper)
            img *= alpha
            img = img.clamp(min=0, max=1.0)
        return img

    def random_saturation(self, img, lower=0.5, upper=1.5, p=1):
        # 随机饱和度变换,针对彩色三通道图像,中间通道乘以一个值
        if np.random.random() < p:
            alpha = np.random.uniform(lower, upper)
            img[1] = img[1] * alpha
            img[1] = img[1].clamp(min=0, max=1.0)
        return img

    def add_gasuss_noise(self, img, mean=0, std=0.1):
        noise = torch.normal(mean, std, img.shape)
        img += noise
        img = img.clamp(min=0, max=1.0)
        return img

    def add_salt_noise(self, img):
        noise = torch.rand(img.shape)
        alpha = np.random.random() / 5 + 0.7
        img[noise[:, :, :] > alpha] = 1.0
        return img

    def add_pepper_noise(self, img):
        noise = torch.rand(img.shape)
        alpha = np.random.random() / 5 + 0.7
        img[noise[:, :, :] > alpha] = 0
        return img


def plot_pics(img, boxes):
    # 显示图像和候选框,img是Image.Open()类型, boxes是Tensor类型
    plt.imshow(img)
    label_colors = [(213, 110, 89)]
    w, h = img.size
    for i in range(boxes.shape[0]):
        box = boxes[i, 1:]
        xc, yc, wc, hc = box
        x = w * xc - 0.5 * w * wc
        y = h * yc - 0.5 * h * hc
        box_w, box_h = w * wc, h * hc
        plt.gca().add_patch(plt.Rectangle(xy=(x, y), width=box_w, height=box_h,
                                          edgecolor=[c / 255 for c in label_colors[0]],
                                          fill=False, linewidth=2))
    plt.show()


def get_image_list(image_path):
    # 根据图片文件,查找所有图片并返回列表
    files_list = []
    for root, sub_dirs, files in os.walk(image_path):
        for special_file in files:
            special_file = special_file[0: len(special_file)]
            files_list.append(special_file)
    return files_list


def get_label_file(label_path, image_name):
    # 根据图片信息,查找对应的label
    fname = os.path.join(label_path, image_name[0: len(image_name) - 4] + ".txt")
    data2 = []
    if not os.path.exists(fname):
        return data2
    if os.path.getsize(fname) == 0:
        return data2
    else:
        with open(fname, 'r', encoding='utf-8') as infile:
            # 读取并转换标签
            for line in infile:
                data_line = line.strip("\n").split()
                data2.append([float(i) for i in data_line])
    return data2


def save_Yolo(img, boxes, save_path, prefix, image_name):
    # img: 需要时Image类型的数据, prefix 前缀
    # 将结果保存到save path指示的路径中
    if not os.path.exists(save_path) or \
            not os.path.exists(os.path.join(save_path, "images")):
        os.makedirs(os.path.join(save_path, "images"))
        os.makedirs(os.path.join(save_path, "labels"))
    try:
        img.save(os.path.join(save_path, "images", prefix + image_name))
        with open(os.path.join(save_path, "labels", prefix + image_name[0:len(image_name) - 4] + ".txt"), 'w',
                  encoding="utf-8") as f:
            if len(boxes) > 0:  # 判断是否为空
                # 写入新的label到文件中
                for data in boxes:
                    str_in = ""
                    for i, a in enumerate(data):
                        if i == 0:
                            str_in += str(int(a))
                        else:
                            str_in += " " + str(float(a))
                    f.write(str_in + '\n')
    except:
        print("ERROR: ", image_name, " is bad.")


def runAugumentation(image_path, label_path, save_path):
    image_list = get_image_list(image_path)
    for image_name in image_list:
        print("dealing: " + image_name)
        img = Image.open(os.path.join(image_path, image_name))
        boxes = get_label_file(label_path, image_name)
        boxes = torch.tensor(boxes)
        # 下面是执行的数据增强功能,可自行选择
        # Image类型的参数
        DAD = DataAugmentationOnDetection()

        """ 尺寸变换   """
        # 缩小尺寸
        # t_img, t_boxes = DAD.resizeDown_keep_ratio(img, boxes, 1024)
        # save_Yolo(t_img, boxes, save_path, prefix="rs_", image_name=image_name)
        # 水平旋转
        t_img, t_boxes = DAD.random_flip_horizon(img, boxes.clone())
        save_Yolo(t_img, t_boxes, save_path, prefix="fh_", image_name=image_name)
        # 竖直旋转
        t_img, t_boxes = DAD.random_flip_vertical(img, boxes.clone())
        save_Yolo(t_img, t_boxes, save_path, prefix="fv_", image_name=image_name)
        # center_crop
        t_img, t_boxes = DAD.center_crop(img, boxes.clone(), 1024)
        save_Yolo(t_img, t_boxes, save_path, prefix="cc_", image_name=image_name)

        """ 图像变换,用tensor类型"""
        to_tensor = transforms.ToTensor()
        to_image = transforms.ToPILImage()
        img = to_tensor(img)

        # random_bright
        t_img, t_boxes = DAD.random_bright(img.clone()), boxes
        save_Yolo(to_image(t_img), boxes, save_path, prefix="rb_", image_name=image_name)
        # random_contrast 对比度变化
        t_img, t_boxes = DAD.random_contrast(img.clone()), boxes
        save_Yolo(to_image(t_img), boxes, save_path, prefix="rc_", image_name=image_name)
        # random_saturation 饱和度变化
        t_img, t_boxes = DAD.random_saturation(img.clone()), boxes
        save_Yolo(to_image(t_img), boxes, save_path, prefix="rs_", image_name=image_name)
        # 高斯噪声
        t_img, t_boxes = DAD.add_gasuss_noise(img.clone()), boxes
        save_Yolo(to_image(t_img), boxes, save_path, prefix="gn_", image_name=image_name)
        # add_salt_noise
        t_img, t_boxes = DAD.add_salt_noise(img.clone()), boxes
        save_Yolo(to_image(t_img), boxes, save_path, prefix="sn_", image_name=image_name)
        # add_pepper_noise
        t_img, t_boxes = DAD.add_pepper_noise(img.clone()), boxes
        save_Yolo(to_image(t_img), boxes, save_path, prefix="pn_", image_name=image_name)

        print("end:     " + image_name)


if __name__ == '__main__':
    # 图像和标签文件夹
    image_path = "./yolo-dataset-lwb/val"
    label_path = "./yolo-dataset-lwb/val_txt"
    save_path = "./yolo-dataset-lwb/save_val"  # 结果保存位置路径,可以是一个不存在的文件夹
    # 运行
    runAugumentation(image_path, label_path, save_path)

因为YOLOV8为我们集成好了很多的数据增强策略了已经。
以下是YOLOV8在训练中已经使用的一些策略,大家也可以调参使用。

参数范围功能
hsv_h默认0.015,可调范围是0.0~1.0调整图像的色调,引入颜色可变性。
hsv_s默认0.7,可调范围是0.0~1.0调整图像的饱和度。
translate默认0.1,可调范围是0.0~1.0平移一小部分图像。
scale默认0.5,可调范围是大于等于0.0都可以缩放图像。
fliplr默认为0.5,可调范围是0.0~1.0以指定的概率将图像从左向右翻转,左右镜像。
mosaic默认为1.0,可调范围是0.0~1.0将四个训练图像组合为一个。
auto_augment默认为randaugment,可调范围是(randaugment、autoaugment和augmix)面向分类任务,自动应用预定义的增强策略。
erasing默认为0.4,可调范围是0.0~0.9在分类训练过程中随机擦除图像的一部分。
crop_fraction默认为1.0,可调范围是0.1~1.0将分类图像裁剪到其大小的一小部分。

以下是YOLOV8未使用的一些增强策略

参数范围功能
degrees范围是-180~+180在指定的度数范围内随机旋转图像。
shear范围是-180~+180以指定的角度剪切图像。
perspective范围是0.0~0.001将随机透视变换应用于图像。
flipud范围是0.0~1.0以指定的概率将图像倒置。
bgr范围是0.0~1.0以指定的概率将图像通道从RGB翻转到BGR。
mixup范围是0.0~1.0混合两个图像及其标签,创建合成图像。
copy_paste范围是0.0~1.0将对象从一个图像中复制并粘贴到另一个图像上。

这里是一篇关于YOLOV8各个参数功能详细介绍的大佬原文添加链接描述建议像详细了解参数功能的可以去看一下。
参数的使用方法如下(直接在train中使用即可):

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

import warnings
warnings.filterwarnings('ignore')


from ultralytics import YOLO
model = YOLO("yolov8n.pt")
results = model.train(data="yolo-dataset/yolo.yaml", epochs=2, imgsz=1080, batch=16, copy_paste=0.2, mixup=0.5)

数据收集

然后大家可以观察一下官方大大给出的数据集,其实大多视频都是同一个场景或者标签有错误,所以如果想卷的话还是要自己动手收集数据打标签,这里我也给大家推荐几个数据集。
这里是一个飞桨提供的一个垃圾桶的数据集大家可以去找一些适合本次大赛的图片添加到训练集中垃圾桶溢满数据集。
这个是极市在2022年的一个比赛的数据集,里面的图片看例图和本次本赛还是很贴近的,但是这个目前极市官方是不公开数据的,不过这个比赛当视很火,应该可以在网上找到资源机动车违停识别。

打标签

感觉写到上面有点水笔记,再加个打标签吧,虽然能参加比赛的佬基本都会。
首先先创建一个打标签的环境

conda create -n label python=3.8

激活环境

conda activate label

安装labelme

pip install labelme

等待安装完成使用在终端输入labelme启动labelme

labelme

启动后界面如下
在这里插入图片描述
点击打开目录选择你数据集所在的文件夹即可,接着选择‘文件-更改输出路径’,这里建议图片和标签不要放在一起,因为labelme标注后的数据不是yolo的格式需要进一步的转化才能使用。
这里提供一个转标签的python文件

# # trans_labelme_to_yolo.py
import cv2
import os
import json
import shutil
import numpy as np
from pathlib import Path
from glob import glob

# id2cls = {0: 'clothing'}
# cls2id = {'clothing': 0}
id2cls = {0: '非机动车违停', 1: '机动车违停', 2: '垃圾桶满溢', 3:'违法经营'}
cls2id = {'非机动车违停': 0, '机动车违停': 1, '垃圾桶满溢': 2, '违法经营': 3}

# 支持中文路径
def cv_imread(filePath):
    cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), flags=cv2.IMREAD_COLOR)
    return cv_img

def labelme2yolo_single(img_path, label_file):
    anno = json.load(open(label_file, "r", encoding="utf-8"))
    shapes = anno['shapes']
    w0, h0 = anno['imageWidth'], anno['imageHeight']
    image_path = os.path.basename(img_path + anno['imagePath'])
    labels = []
    for s in shapes:
        pts = s['points']
        x1, y1 = pts[0]
        x2, y2 = pts[1]
        x = (x1 + x2) / 2 / w0
        y = (y1 + y2) / 2 / h0
        w = abs(x2 - x1) / w0
        h = abs(y2 - y1) / h0
        cid = cls2id[s['label']]
        labels.append([cid, x, y, w, h])
    return np.array(labels), image_path


def labelme2yolo(img_path, labelme_label_dir, save_dir='res/'):
    labelme_label_dir = str(Path(labelme_label_dir)) + '/'
    save_dir = str(Path(save_dir))
    yolo_label_dir = save_dir + '/'
    if not os.path.exists(yolo_label_dir):
        os.makedirs(yolo_label_dir)

    json_files = glob(labelme_label_dir + '*.json')
    for ijf, jf in enumerate(json_files):
        print(ijf + 1, '/', len(json_files), jf)
        filename = os.path.basename(jf).rsplit('.', 1)[0]
        labels, image_path = labelme2yolo_single(img_path, jf)
        if len(labels) > 0:
            # 在这里我们对np.savetxt的调用做了修改
            np.savetxt(yolo_label_dir + filename + '.txt', labels, fmt='%d %0.16f %0.16f %0.16f %0.16f')
            # shutil.copy(labelme_label_dir + image_path, yolo_image_dir + image_path)
    print('Completed!')


if __name__ == '__main__':
    img_path = './yolo-dataset-lwb/val'  # 数据集图片的路径
    json_dir = './yolo-dataset-lwb/val_json'  # json标签的路径
    save_dir = './yolo-dataset-lwb/val_txt'  # 保存的txt标签的路径
    labelme2yolo(img_path, json_dir, save_dir)

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

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

相关文章

LVGL 控件之按钮(lv_button)

目录 一、按钮1、概述2、样式2.1 设置背景2.1.1 颜色2.1.2 透明度2.1.3 渐变色2.1.4 渐变色起始位置设置 2.2 修改边界2.2.1 宽度2.2.2 颜色2.2.3 透明度2.2.4 指定边 2.3 修改边框2.4 修改阴影2.4.1 宽度2.4.2 透明度2.4.3 偏移坐标2.4.4 颜色2.4.5 延伸 2.5 设置圆角弧度2.6 …

C++STL~~list

文章目录 一、list的概念二、list的使用三、list的练习四、与vector的对比五、总结 一、list的概念 list 是一种容器&#xff0c;实现了双向链表结构 它具有以下特点&#xff1a; 动态大小&#xff0c;可按需增减元素数量。高效的插入和删除操作&#xff0c;在任意位置插入和…

(四)进入MySQL 【事务】

一、MySQL事务的概念 MySQL 事务主要用于处理操作量大&#xff0c;复杂度高的数据。比如说&#xff0c;在人员管理系统中&#xff0c; 要删除一个人员&#xff0c;即需要删除人员的基本资料&#xff0c;又需要删除和该人员相关的信息&#xff0c;如信箱&#xff0c; 文章等等。…

unity中的InstanceID详解 即Object.GetInstanceID

GetInstanceID 是 Unity 中 Object 类的一个方法,它用于获取一个对象的唯一实例标识符。每个 Unity 对象(如游戏对象、组件、资源等)都有一个唯一的实例 ID,这个 ID 在对象的生命周期内是唯一的。 对于它的生命周期是不确定的。网上说在切换场景或者编辑器关闭重启后会变。…

红黑树刨析(删除部分)

文章目录 红黑树删除节点情景分析情景1&#xff1a;删除节点左右子树都为空情景1.1&#xff1a;删除节点为红色情景1.2&#xff1a;删除节点为黑色情况1.2.1&#xff1a;删除节点的兄弟节点是红色情景1.2.2&#xff1a;删除节点的兄弟节点是黑色情景1.2.2.1&#xff1a;删除节点…

计算机毕业设计选题推荐-大学生竞赛管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

初识Arduino

什么是Arduino Arduino是一款便捷灵活、方便上手的开源电子原型平台。它包含硬件部分&#xff08;即各种型号的Arduino板&#xff09;、软件部分&#xff08;即Arduino IDE&#xff09;&#xff0c;以及其Arduino社区平台。 Arduino由一个欧洲开发团队于2005年冬季开发&#…

56基于SpringBoot+Vue+uniapp的教学资源库的详细设计和实现(源码+lw+部署文档+讲解等)

文章目录 前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus 系统测试系统测试目的系统功能测试系统测试结论 为什么选择我代码参考数据库参考源码获取源码获取 前言 &#x1f31e;博主介绍 &#xff1a;✌全网粉丝15W,CSDN特邀作者、21…

信息学奥赛初赛天天练-80-NOIP2015普及组-基础题5-错位排列、二叉树、完全二叉树、叶子节点、完全二叉树叶子节点

NOIP 2015 普及组 基础题5 21 重新排列 1234使得每一个数字都不在原来的位置上&#xff0c;一共有( )种排法 22 一棵结点数为 2015的二叉树最多有( )个叶子结点 2 相关知识点 1) 错位排列 考虑一个有n个元素的排列&#xff0c;若一个排列中所有的元素都不在自己原来的位置…

建模杂谈系列250 Hello2Pymc

说明 pymc算是多年的老朋友了&#xff0c;中间失联了好几年。 内容 1 安装 安装更加麻烦了&#xff0c;不能很好的和其他的环境兼容。在官网上&#xff0c;也是建议用conda的方式安装。 conda create -c conda-forge -n pymc_env "pymc>5" conda activate p…

SQL基础——MySQL的优化

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 概述 在应用的的开发过程中&#xff0c;由于初期数据量小&#xff0c;开发人员写 SQL 语句时更重视功能上的实现&#xff0c;但是当应用系统正式上线后&#xff0c;随着生产数据量的急剧增长&…

安卓15发布日期确定,安卓15 谷歌GMS认证截止日期有重大变化!安卓版本GMS认证截止时间更新,谷歌GMS认证之MADA/EDLA设备认证截止时间介绍

谷歌正式公布安卓15发布日期&#xff0c;即9月3号&#xff0c;到时&#xff0c;安卓版本的认证时间将会有改变&#xff01;以下是深光标准整理的最新安卓版本的到期时间 详细讲解如何看懂这个图 第一列&#xff1a;OS version (API level) 指安卓版本 第二列&#xff1a;AOS…

软件测试工程师必备的技术能力

今年是我从事软件测试工作的第十年&#xff0c;从功能测试进阶到自动化测试&#xff0c;然后负责稳定性测试团队&#xff0c;进而兼任整个质量团队的技术专项治理&#xff0c;再到基础架构团队的测试专家角色&#xff0c;负责多个技术项目的产品/运营和质量保障工作。可以说绝大…

GNU 汇编语法基础

目录 一、引言 二、GNU 汇编基本结构 1.指令格式 2.注释 3. 段 三、寄存器和寻址方式 1.寄存器命名 2.寻址方式 四、指令集 1.数据传送指令 2.算术运算指令 3.逻辑运算指令 4.控制流指令 五、宏和函数 1.宏定义 2. 函数定义 六、总结 一、引言 在嵌入式系统…

南京观海微电子----VCC、 VDD、VSS、VEE 电压符号解释

一般在数据手册或者是说原理图中你会看到VCC、 VDD、VEE、VSS等不同的符号&#xff0c;那它们有什么区别&#xff0c;并且该怎么记住它们呢。 解释一&#xff1a; VCC&#xff1a;电源电压&#xff08;双极器件&#xff09;&#xff1b;电源电压&#xff08;74系列数字电路&a…

机会约束转化为确定性约束-- 样本均值法

当涉及到新能源消纳的机会约束规划时&#xff0c;我们需要深入理解其背后的原理和采用的方法。以下是对上文内容的更详细且更贴切的展开解释&#xff1a; 机会约束转化为确定性约束-- 样本均值法代码获取戳此处代码获取戳此处代码获取戳此处 新能源消纳的机会约束 新能源&…

计量校准中溯源方法会有哪些不足之处?

随着新型计量器具的不断涌现&#xff0c;现有的计量检定规程或计量校准规范已不能满足计量溯源的需要。特别是一体化大型设备所配备的传感器&#xff0c;如产业生产线之上的压力传感器、流量计、在线电导率仪、在线酸度计为代表的对传感器的检测目前多依据国家检定规程或计量校…

自制深度学习推理框架之表达式层的设计与实现

文章目录 一、表达式Expression二、词法解析2.1 词法定义2.2 词法解析 三、语法解析3.1 语法树的定义3.2 语法树构建3.3 语法树的转换(逆波兰式) 四、表达式层4.1 ExpressionLayer和ExpressionParser类4.2 表达式层的注册4.3 表达式层的输入处理4.4 表达式层的计算过程 五、计算…

分布式计算架构详解以及任务调度方式

信息技术领域重要分支—分布式计算。分布式计算通过将任务分配到多个物理的计算资源上进行处理&#xff0c;以来提高计算效率和资源利用率。今天主讲分布式计算架构的关键组成以及在云服务器背景下任务调度的不同方式&#xff0c;然后再综合来看这些调度策略是怎样适应云环境的…

使用 nuxi build-module 命令构建 Nuxt 模块

title: 使用 nuxi build-module 命令构建 Nuxt 模块 date: 2024/8/31 updated: 2024/8/31 author: cmdragon excerpt: nuxi build-module 命令是构建 Nuxt 模块的核心工具,它将你的模块打包成适合生产环境的格式。通过使用 --stub 选项,你可以在开发过程中加快模块构建速度…