yolov3

yolov1

传统的算法  最主要的是先猜很多候选框,然后使用特征工程来提取特征(特征向量),最后使用传统的机器学习工具进行训练。然而复杂的过程可能会导致引入大量的噪声,丢失很多信息。

从传统的可以总结出目标检测可以分为两个阶段:候选框生成、回归分类。

yolov1是单阶段的目标检测算法。

yolov1的算法流程:

  1. 每一张图片分为s*s的网格大小,物体中心点落在哪一个格子上,则那个格子就负责预测那个物体。  也就是说yolov1就一幅图像经过卷积之后变成了特征图大小为7*7,特征图上的每一个点对应与原始图像的某一个区域,每一个点都是一个向量,每个向量包含了这片区域是否包含物体的信息。  这里最后的特征图太小,会出现多个物体落在一个格子上的现象。
  2. 卷积之后特征图大小为s*s,最终输出的张量是s*s*(5*B+C).  每个bounding box的置信度其实是两个信息的耦合,包含了这个边界框是否含有信息且含有信息的可靠性。
  3. 损失函数:边界框的回归。宽高带根号。

yolov1特征总结:

1 优势:

one-stage,非常快

2 缺点:

对拥挤情况不好,7*7网格太小(一个网格检测一个物体),对于稠密物体效果不好

对小物体检测不好

对形状变化大的物体不好

没有用BN

yolov2

yovov2算法改进:

1、引入BN

2、更高精度的classifier ,yolov1分为7*7网格(对稠密物体不友好),yolov2则分为13*13的网格

3、多尺度训练

        - 移除了FC层可以接收任意尺度

        - 从320*320,352*352 训练至680*680

4、细粒度(fine-grained)特征

        - 浅层特征直连深层  (浅层特征主要学物体的边缘特征,深层特征主要学习物体的语义信息)

        - 引入新层“reorg”(即“slice”层)  (后续被抛弃,在yolov7中又被重新引入)

5、YOLO系列首次使用了Anchor(非常重要)

        - Anchor 是什么

        - 为什么要用Anchor

anchor机制

Anchor的含义:

        - 预设好的虚拟边框

        - 生成框由Anchor回归而来

yolov3

1 新的网络模块

2 多尺度结构

3 Multi-class loss

softmax loss (one hot )  -> logistic regression loss

yolo-head部分会含有anchor,也就是说yolo-head 输出的其实就是真实框和anchor的偏移量

yolo的众多改良

1 数据改良(各种数据增广方案)

2 网络框架改良

激活函数

正则化改良

现代框架:解耦与第三分支

3 损失函数改良

Focal Loss

IOU/GIOU/

4 yolo后续

voctoyolo

生成train.txt文件 文件名+边界框坐标+类别

import os
import xml.etree.ElementTree as ETdef convert(size, box):dw = 1. / size[0]dh = 1. / size[1]x = (box[0] + box[1]) / 2.0y = (box[2] + box[3]) / 2.0w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def xml2txt(xml_file, f, classes):"""xml_file:xml 文件f: 读取的信息以追加的方式追加到txt_file文件中classes:所有的类别"""# 解析 xml 文件tree = ET.parse(xml_file)root = tree.getroot()# 读取高宽等信息size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)# 遍历 xml 中的目标for obj in root.iter('object'):difficult = obj.find('difficult').text  # 跳过困难样本cls = obj.find('name').text  # 获取目标类别# 跳过无需转换的类别if cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)  # 转换为对应索引 从 0 开始xmlbox = obj.find('bndbox')  # 读取标注信息 [xmin, ymin, xmax, ymax]b = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)), int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text))) # 字符型转换为float# b = convert((w, h), b)  # 转换为yolo格式 [xcenter, ycenter, box_w, box_h]f.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))f.write('\n')if __name__ == '__main__':classes = ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair','cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train','tvmonitor']def create_txt(img_dir,xml_dir,txt_file,classes):img_total = os.listdir(img_dir)with open(txt_file, mode='w', encoding='utf-8') as f:for img in img_total:if not img.endswith(('jpg')):continueimg_path = os.path.join(img_dir, img)xml_path = os.path.join(xml_dir, img.split('.')[0] + '.xml')f.write(img_path)xml2txt(xml_path, f, classes)create_txt(img_dir='./VOCdevkit/VOC2007/JPEGImages',xml_dir='./VOCdevkit/VOC2007/Annotations',txt_file='./train.txt',classes=classes)
import os
import shutillabel_total=os.listdir('./Anonations')for label in label_total:print(label)label_name=label.split('.')[0]shutil.move(os.path.join('./1/',label_name+'.bmp'),os.path.join('./2/',label_name+'.bmp'))

读取标注并且画出方框

import os
import shutil
import cv2
import xml.etree.ElementTree as ETannoation=os.listdir('./Anonations')for label in annoation:name=label.split('.')[0]# print(name)# shutil.move(os.path.join('./image',name+'.bmp'),os.path.join('img1',name+'.bmp'))image_name=os.path.join('image',name+'.bmp')image=cv2.imread(image_name)annoation_path=os.path.join('./Anonations',label)# print(annoation_path)#画候选框#提取候选框tree=ET.parse(annoation_path)root=tree.getroot()for obj in root.iter('object'):cls=obj.find('name').textprint('类别',cls)xmlbox=obj.find('bndbox')  #读取标注信息 [xmin,ymin,xmax,yamx]b = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)),int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text)))cv2.rectangle(image,(b[0],b[1]),(b[2],b[3]),(255,255,2552),thickness=1)cv2.putText(image,text=cls,org=(b[0],b[1]),fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=0.5,color=(255,0,0))cv2.imshow('image',image)cv2.waitKey(0)

create_list.py 用于创建train.txt 和 val.txt文件

import random
import os
#生成train.txt和val.txt
random.seed(8888)
#---------------------修改为自己的路径----------------------------------------------------
xml_dir  = './annotations'#标签文件地址
img_dir = './images'#图像文件地址
#---------------------修改为自己的路径----------------------------------------------------path_list = list()
for img in os.listdir(img_dir):img_path = os.path.join(img_dir,img)xml_path = os.path.join(xml_dir,img.replace('jpg', 'xml'))  ##这里将图片后缀替换为xmlpath_list.append((img_path, xml_path))
random.shuffle(path_list)
#这里用于测试,因为数据量比较大,cpu带不动
test_data_lenth=50
path_list=path_list[:test_data_lenth]ratio = 0.9
#---------------------train/val之前修改为自己的路径----------------------------------------------------
train_f = open('./train.txt','w') #生成训练文件
val_f = open('./val.txt' ,'w')#生成验证文件
#---------------------修改为自己的路径----------------------------------------------------for i ,content in enumerate(path_list):img, xml = contenttext = img + ' ' + xml + '\n'if i < len(path_list) * ratio:train_f.write(text)else:val_f.write(text)
train_f.close()
val_f.close()#生成标签文档
label = ['speedlimit','crosswalk','trafficlight'] #设置你想检测的类别#---------------------label_list之前修改为自己的路径----------------------------------------------------
with open('./label_list.txt', 'w',encoding='utf-8') as f:
# ---------------------label_list之前修改为自己的路径----------------------------------------------------for text in label:f.write(text+'\n')

【目标检测】将xml标注文件转换为txt格式,voc标注格式转为yolo的txt格式_voc转txt_悠悠青青的博客-CSDN博客

yolodataset

对图像进行变换时也需要对真实框进行变换

import cv2
import numpy as np
import torch
from PIL import Image
from torch.utils.data.dataset import Dataset# ---------------------------------------------------------#
#   将图像转换成RGB图像,防止灰度图在预测时报错。
#   代码仅仅支持RGB图像的预测,所有其它类型的图像都会转化成RGB
# ---------------------------------------------------------#
def cvtColor(image):if len(np.shape(image)) == 3 and np.shape(image)[2] == 3:return imageelse:image = image.convert('RGB')return imagedef preprocess_input(image):image /= 255.0return imageclass YoloDataset(Dataset):def __init__(self, annotation_lines, input_shape=[416, 416], num_classes=20, train=False):super(YoloDataset, self).__init__()self.annotation_lines = annotation_linesself.input_shape = input_shapeself.num_classes = num_classesself.length = len(self.annotation_lines)self.train = traindef __len__(self):return self.lengthdef __getitem__(self, index):index = index % self.length# ---------------------------------------------------##   训练时进行数据的随机增强#   验证时不进行数据的随机增强# ---------------------------------------------------#image, box = self.get_random_data(self.annotation_lines[index], self.input_shape[0:2], random=self.train)image = np.transpose(preprocess_input(np.array(image, dtype=np.float32)), (2, 0, 1))box = np.array(box, dtype=np.float32)if len(box) != 0:box[:, [0, 2]] = box[:, [0, 2]] / self.input_shape[1]box[:, [1, 3]] = box[:, [1, 3]] / self.input_shape[0]box[:, 2:4] = box[:, 2:4] - box[:, 0:2]box[:, 0:2] = box[:, 0:2] + box[:, 2:4] / 2return image, boxdef rand(self, a=0, b=1):return np.random.rand() * (b - a) + adef get_random_data(self, annotation_line, input_shape, jitter=.3, hue=.1, sat=0.7, val=0.4, random=True):line = annotation_line.split()# ------------------------------##   读取图像并转换成RGB图像# ------------------------------#image = Image.open(line[0])image = cvtColor(image)# ------------------------------##   获得图像的高宽与目标高宽# ------------------------------#iw, ih = image.size  #iw表示原始图片的宽,ih表示原始图片的高h, w = input_shape   #模型输入的高和宽# ------------------------------##   获得预测框# ------------------------------#box = np.array([np.array(list(map(int, box.split(',')))) for box in line[1:]])if not random:##random=False  时,即验证时,不需要进行数据增强scale = min(w / iw, h / ih)  ##输入图片大小跟算法处理的大小不一致,需要进行变换nw = int(iw * scale)  #这是因为图片必须同一比例进行缩放nh = int(ih * scale)dx = (w - nw) // 2 #这里因为使用同一比例进行缩放时 可能会导致有些图片变小,所以这时需要进行填充,//2,两边填充dy = (h - nh) // 2# ---------------------------------##   将图像多余的部分加上灰条# ---------------------------------#image = image.resize((nw, nh), Image.BICUBIC)new_image = Image.new('RGB', (w, h), (128, 128, 128))new_image.paste(image, (dx, dy))image_data = np.array(new_image, np.float32)# ---------------------------------##   对真实框进行调整# ---------------------------------#if len(box) > 0:np.random.shuffle(box)box[:, [0, 2]] = box[:, [0, 2]] * nw / iw + dxbox[:, [1, 3]] = box[:, [1, 3]] * nh / ih + dybox[:, 0:2][box[:, 0:2] < 0] = 0box[:, 2][box[:, 2] > w] = wbox[:, 3][box[:, 3] > h] = hbox_w = box[:, 2] - box[:, 0]box_h = box[:, 3] - box[:, 1]box = box[np.logical_and(box_w > 1, box_h > 1)]  # discard invalid boxreturn image_data, box# ------------------------------------------##   对图像进行缩放并且进行长和宽的扭曲# ------------------------------------------#new_ar = iw / ih * self.rand(1 - jitter, 1 + jitter) / self.rand(1 - jitter, 1 + jitter)scale = self.rand(.25, 2)if new_ar < 1:nh = int(scale * h)nw = int(nh * new_ar)else:nw = int(scale * w)nh = int(nw / new_ar)image = image.resize((nw, nh), Image.BICUBIC)# ------------------------------------------##   将图像多余的部分加上灰条# ------------------------------------------#dx = int(self.rand(0, w - nw))dy = int(self.rand(0, h - nh))new_image = Image.new('RGB', (w, h), (128, 128, 128))new_image.paste(image, (dx, dy))image = new_image# ------------------------------------------##   翻转图像# ------------------------------------------#flip = self.rand() < .5if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT)image_data = np.array(image, np.uint8)# ---------------------------------##   对图像进行色域变换#   计算色域变换的参数# ---------------------------------#r = np.random.uniform(-1, 1, 3) * [hue, sat, val] + 1# ---------------------------------##   将图像转到HSV上# ---------------------------------#hue, sat, val = cv2.split(cv2.cvtColor(image_data, cv2.COLOR_RGB2HSV))dtype = image_data.dtype# ---------------------------------##   应用变换# ---------------------------------#x = np.arange(0, 256, dtype=r.dtype)lut_hue = ((x * r[0]) % 180).astype(dtype)lut_sat = np.clip(x * r[1], 0, 255).astype(dtype)lut_val = np.clip(x * r[2], 0, 255).astype(dtype)image_data = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))image_data = cv2.cvtColor(image_data, cv2.COLOR_HSV2RGB)# ---------------------------------##   对真实框进行调整# ---------------------------------#if len(box) > 0:np.random.shuffle(box)box[:, [0, 2]] = box[:, [0, 2]] * nw / iw + dxbox[:, [1, 3]] = box[:, [1, 3]] * nh / ih + dyif flip: box[:, [0, 2]] = w - box[:, [2, 0]]box[:, 0:2][box[:, 0:2] < 0] = 0box[:, 2][box[:, 2] > w] = wbox[:, 3][box[:, 3] > h] = hbox_w = box[:, 2] - box[:, 0]box_h = box[:, 3] - box[:, 1]box = box[np.logical_and(box_w > 1, box_h > 1)]return image_data, boxif __name__=='__main__':with open('train.txt',mode='r',encoding='utf-8') as f:annotation_lines=f.readlines()print(annotation_lines)dataset=YoloDataset(annotation_lines=annotation_lines)image_data,box=dataset[0]print(image_data.shape,box)

kmeans  anchors聚类

# -------------------------------------------------------------------------------------------------------#
#   kmeans虽然会对数据集中的框进行聚类,但是很多数据集由于框的大小相近,聚类出来的9个框相差不大,
#   这样的框反而不利于模型的训练。因为不同的特征层适合不同大小的先验框,shape越小的特征层适合越大的先验框
#   原始网络的先验框已经按大中小比例分配好了,不进行聚类也会有非常好的效果。
# -------------------------------------------------------------------------------------------------------#
import glob
import xml.etree.ElementTree as ETimport matplotlib.pyplot as plt
import numpy as np
from tqdm import tqdmdef cas_iou(box, cluster):x = np.minimum(cluster[:, 0], box[0])y = np.minimum(cluster[:, 1], box[1])intersection = x * yarea1 = box[0] * box[1]area2 = cluster[:, 0] * cluster[:, 1]iou = intersection / (area1 + area2 - intersection)return ioudef avg_iou(box, cluster):return np.mean([np.max(cas_iou(box[i], cluster)) for i in range(box.shape[0])])def kmeans(box, k):# -------------------------------------------------------------##   取出一共有多少框# -------------------------------------------------------------#row = box.shape[0]# -------------------------------------------------------------##   每个框各个点的位置# -------------------------------------------------------------#distance = np.empty((row, k))# -------------------------------------------------------------##   最后的聚类位置# -------------------------------------------------------------#last_clu = np.zeros((row,))np.random.seed()# -------------------------------------------------------------##   随机选k个当聚类中心# -------------------------------------------------------------#cluster = box[np.random.choice(row, k, replace=False)]iter = 0while True:# -------------------------------------------------------------##   计算当前框和先验框的宽高比例# -------------------------------------------------------------#for i in range(row):distance[i] = 1 - cas_iou(box[i], cluster)# -------------------------------------------------------------##   取出最小点# -------------------------------------------------------------#near = np.argmin(distance, axis=1)  #求每一个框距离哪一个中心点的位置最近if (last_clu == near).all():break# -------------------------------------------------------------##   求每一个类的中位点# -------------------------------------------------------------#for j in range(k):cluster[j] = np.median(box[near == j], axis=0)   #near==j  说明这些框是一个类别的last_clu = nearif iter % 5 == 0:print('iter: {:d}. avg_iou:{:.2f}'.format(iter, avg_iou(box, cluster)))iter += 1return cluster, near   #cluster是最后的聚类中心,near是每一个框属于哪一个聚类中心def load_data(path):data = []# -------------------------------------------------------------##   对于每一个xml都寻找box# -------------------------------------------------------------#for xml_file in tqdm(glob.glob('{}/*xml'.format(path))):tree = ET.parse(xml_file)height = int(tree.findtext('./size/height'))width = int(tree.findtext('./size/width'))if height <= 0 or width <= 0:continue# -------------------------------------------------------------##   对于每一个目标都获得它的宽高# -------------------------------------------------------------#for obj in tree.iter('object'):xmin = int(float(obj.findtext('bndbox/xmin'))) / widthymin = int(float(obj.findtext('bndbox/ymin'))) / heightxmax = int(float(obj.findtext('bndbox/xmax'))) / widthymax = int(float(obj.findtext('bndbox/ymax'))) / heightxmin = np.float64(xmin)ymin = np.float64(ymin)xmax = np.float64(xmax)ymax = np.float64(ymax)# 得到宽高data.append([xmax - xmin, ymax - ymin])return np.array(data)if __name__ == '__main__':np.random.seed(0)input_shape = [200, 200]   #图片的大小anchors_num = 9# -------------------------------------------------------------##   载入数据集,可以使用VOC的xml# -------------------------------------------------------------#path = './anonations'# -------------------------------------------------------------##   载入所有的xml#   存储格式为转化为比例后的width,height# -------------------------------------------------------------#print('Load xmls.')data = load_data(path)print('Load xmls done.')# -------------------------------------------------------------##   使用k聚类算法# -------------------------------------------------------------#print('K-means boxes.')cluster, near = kmeans(data, anchors_num)print('K-means boxes done.')data = data * np.array([input_shape[1], input_shape[0]])cluster = cluster * np.array([input_shape[1], input_shape[0]])# -------------------------------------------------------------##   绘图# -------------------------------------------------------------#for j in range(anchors_num):plt.scatter(data[near == j][:, 0], data[near == j][:, 1])  #画出所有框的散点图plt.scatter(cluster[j][0], cluster[j][1], marker='x', c='black')  #cluster 表示聚类中心plt.savefig("kmeans_for_anchors.jpg")plt.show()print('Save kmeans_for_anchors.jpg in root dir.')hh=np.argsort(cluster[:, 0] * cluster[:, 1])cluster = cluster[np.argsort(cluster[:, 0] * cluster[:, 1])]print('avg_ratio:{:.2f}'.format(avg_iou(data, cluster)))print('聚类中心',cluster)f = open("yolo_anchors.txt", 'w')row = np.shape(cluster)[0]for i in range(row):if i == 0:x_y = "%d,%d" % (cluster[i][0], cluster[i][1])else:x_y = ", %d,%d" % (cluster[i][0], cluster[i][1])f.write(x_y)f.close()

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

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

相关文章

Java 读取TIFF JPEG GIF PNG PDF

Java 读取TIFF JPEG GIF PNG PDF 本文解决方法基于开源 tesseract 下载适合自己系统版本的tesseract &#xff0c;官网链接&#xff1a;https://digi.bib.uni-mannheim.de/tesseract/ 2. 下载之后安装&#xff0c;安装的时候选择选择语言包&#xff0c;我选择了中文和英文 3.…

提高Python并发性能 - asyncio/aiohttp介绍

在进行大规模数据采集时&#xff0c;如何提高Python爬虫的并发性能是一个关键问题。本文将向您介绍使用asyncio和aiohttp库实现异步网络请求的方法&#xff0c;并通过具体结果和结论展示它们对于优化爬虫效率所带来的效果。 1. 什么是异步编程&#xff1f; 异步编程是一种非阻…

vue使用打印组件print-js

项目场景&#xff1a; 由于甲方要求&#xff0c;项目需要打印二维码标签&#xff0c;故开发此功能 开发流程 安装包&#xff1a;npm install print-js --saveprint-js的使用 <template><div id"print" ref"print" ><p>打印内容<p&…

树的介绍(C语言版)

前言 在数据结构中树是一种很重要的数据结构&#xff0c;很多其他的数据结构和算法都是通过树衍生出来的&#xff0c;比如&#xff1a;堆&#xff0c;AVL树&#xff0c;红黑色等本质上都是一棵树&#xff0c;他们只是树的一种特殊结构&#xff0c;还有其他比如linux系统的文件系…

CocosCreator3.8研究笔记(二)windows环境 VS Code 编辑器的配置

一、设置文件显示和搜索过滤步骤 为了提高搜索效率以及文件列表中隐藏不需要显示的文件&#xff0c; VS Code 需要设置排除目录用于过滤。 比如 cocoscreator 中&#xff0c;编辑器运行时会自动生成一些目录&#xff1a;build、temp、library&#xff0c; 所以应该在搜索中排除…

代码随想录算法训练营第五十一天 | 309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费

代码随想录算法训练营第五十一天 | 309.最佳买卖股票时机含冷冻期&#xff0c;714.买卖股票的最佳时机含手续费 309.最佳买卖股票时机含冷冻期714.买卖股票的最佳时机含手续费 309.最佳买卖股票时机含冷冻期 题目链接 视频讲解 给定一个整数数组prices&#xff0c;其中第 pric…

Mysql-索引查询相关

一、单表查询 1.1 二级索引为null 不论是普通的二级索引&#xff0c;还是唯一二级索引&#xff0c;它们的索引列对包含 NULL 值的数量并不限制&#xff0c;所以我们采用key IS NULL 这种形式的搜索条件最多只能使用 ref 的访问方法&#xff0c;而不是 const 的访问方法 1.2 c…

深入探索PHP编程:连接数据库的完整指南

深入探索PHP编程&#xff1a;连接数据库的完整指南 在现代Web开发中&#xff0c;与数据库进行交互是不可或缺的一部分。PHP作为一种强大的服务器端编程语言&#xff0c;提供了丰富的工具来连接和操作各种数据库系统。本篇教程将带您了解如何在PHP中连接数据库&#xff0c;执行…

并发编程的故事——并发之共享模型

并发之共享模型 文章目录 并发之共享模型一、多线程带来的共享问题二、解决方案三、方法中的synchronize四、变量的线程安全分析五、习题六、Monitor七、synchronize优化八、wait和notify九、sleep和wait十、park和unpark十一、重新理解线程状态十二、多把锁十三、ReentrantLoc…

Window11-Ubuntu双系统安装

一、制作Ubuntu系统盘 1.下载Ubuntu镜像源 阿里云开源镜像站&#xff1a;https://mirrors.aliyun.com/ubuntu-releases/ 清华大学开源软件镜像网站&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/ 选择想要的版本下载&#xff0c;我用的是20.04版本。 2…

关于类和接口

类和接口的区别&#xff0c;去除语法层面&#xff0c;谈谈编程层面的意义。 设计原则SOLID&#xff1a; S&#xff1a;单一职责(SRP)&#xff0c;Single Responsibility Principle O&#xff1a;开-闭原则(OCP)&#xff0c;Open-Closed Principle L&#xff1a;里氏替换(LSP)&…

Facebook登录SDK

一、Facebook SDK接入 官方文档&#xff1a;https://developers.facebook.com/docs/facebook-login/android 按照流程填写完成 1、选择新建应用 如果已经创建了应用就点【搜索你的应用】&#xff0c;忽略2、3步骤 2、选择【允许用户用自己的Facebook账户登录】 3、填写应用…

Qt应用开发(基础篇)——消息对话框 QMessageBox

一、前言 QMessageBox类继承于QDialog&#xff0c;是一个模式对话框&#xff0c;常用于通知用户或向用户提出问题并接收答案。 对话框QDialog QMessageBox消息框主要由四部分组成&#xff0c;一个主要文本text&#xff0c;用于提醒用户注意某种情况;一个信息文本informativeTex…

Redis数据结构应用场景及原理分析

目录 一、Redis介绍 二、应用场景 2.1 String应用场景 2.2 Hash应用场景 2.3 List应用场景 2.4 Set应用场景 2.5 Zset应用场景 一、Redis介绍 单线程多路复用底层数据结构&#xff1a;全局哈希表&#xff08;key-value&#xff09; 二、应用场景 2.1 String应用…

VBA技术资料MF50:VBA_在Excel中突出显示前3个值

【分享成果&#xff0c;随喜正能量】人受到尊重&#xff0c;不是因为权钱&#xff0c;而是他骨子里透出的&#xff0c;正直与善良。。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高…

ChatGPT 总结数据分析的所有知识点

ChatGPT功能非常多,特别是对某个行业,某个方向,某个技术进行总结那是相当专业的。 如下图。 直接用一个指令便总结出来数据分析当中的所有知识点内容。 AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle, Office, Python ,ETL Ex…

day01-ES6新特性以及ReactJS入门

课程介绍 ES6新特性ReactJS入门学习 1、ES6 新特性 1.2、let 和 const 命令 var 之前&#xff0c;我们写js定义变量的时候&#xff0c;只有一个关键字&#xff1a; var var 有一个问题&#xff0c;变量作用域的问题&#xff0c;作用域不可控&#xff0c;就是定义的变量有时会…

嵌入式开发之syslog和rsyslog构建日志记录

1.syslogd作客户端 BusyBox v1.20.2 (2022-04-06 16:19:14 CST) multi-call binary.Usage: syslogd [OPTIONS]System logging utility-n Run in foreground-O FILE Log to FILE (default:/var/log/messages)-l N Log only messages more urge…

深度学习中有哪些超参数,都有什么作用

深度学习中有许多超参数需要设置&#xff0c;它们会对模型的性能和训练过程产生重要影响。以下是一些常见的超参数及其作用&#xff1a; 学习率&#xff08;Learning Rate&#xff09;&#xff1a;控制参数更新的步长。较小的学习率可以使模型收敛更稳定&#xff0c;但可能需要…

自动化备份方案

背景说明 网上有很多教程&#xff0c;写的都是从零搭建一个什么什么&#xff0c;基本上都是从无到有的教程&#xff0c;但是&#xff0c;很少有文章提及搭建好之后如何备份&#xff0c;我觉得备份才是一个系统生命周期内永恒的主题&#xff0c;是一个值得花时间严肃对待的问题…