前言

本人从一个小白,一路走来,已能够熟练使用YOLOv5算法来帮助自己解决一些问题,早就想分析一下自己的学习心得,一直没有时间,最近工作暂时告一段落,今天抽空写点东西,一是为自己积累一些学习笔记,二是可以为一些刚接触YOLOv5算法的小白们提供一些参考,希望大家看之前能够动动你的小手,给我点个关注,给文章点个赞,如果此文确实给你提供了帮助,希望你能在留言区打两个字个“此文有用!”,以此来让这篇文章获得更多的流量,让更多小白能够看到。

YOLOv5

那么多深度学习算法,为什么要用YOLOv5?我觉得很简单,因为YOLOv5快、YOLOv5火、YOLOv5流行啊,为什么不用YOLOv7、YOLOv8,因为不成熟、不稳定,噱头大于改进。所以你要做深度学习,用YOLOv5算法是最稳妥的,就像做人一样,不会很优秀,也不会犯错。中庸之道才是王道。

数据集是什么?就是一堆包含你最终要检测的目标的照片,例如猫、狗、猪。

训练是什么?就是不停的告诉电脑这是猫,这是狗,这是猪的一个不断重复的过程。

检测是什么?就是你教了电脑300遍后,你再拿张有着猫、狗、猪的照片问电脑,哪是猫、哪是狗、哪是猪。

我这样讲,大家应该对这是个怎么回事有个初步的了解了吧,那我们继续往下走。

1.目标检测整体流程

获取算法源码 --------》 配置运行环境 --------》 建立数据集 --------》 标注数据集 --------》 数据集分组 --------》 文件、代码修改 --------》 开始训练、得到模型 --------》 用得到的模型、检测目标 --------》 OVER

2.获取算法源码

YOLOv5代码是开源的,可以免费下载不同的版本,我使用的是YOLOv5 6.1版本,如果你想参考我的步骤做,就下载这个版本的,别的版本我也不熟悉,操作步骤有可能不同。
yolov5-6.1版本代码下载地址

点开网址后,点击左上角的master,下拉框里选择v6.1版本,如下图:
然后点击右边的克隆,下载源代码里选择zip,这样就把源代码下载下来了。如下图:

3.配置运行环境

有了代码,怎样让代码运行通,这需要配置环境,新手小白在这一步搞个三五天很正常,各种错误,各种bug,我也是这么过来的,但是你配置好环境,运行代码没有bug后,你会感觉非常有成就感。记住,不要放弃,就一点一点的解决bug,不要中途放弃。
这一块有其他博主写的很好很详细,大家可以点进去跟着做。
点击配置YOLOv5运行环境
我的环境贴出来给大家看看:
我用的是笔记本:联想拯救者Y9000P2022
操作系统:windows11
显卡:RTX 3060
编译软件:Pycharm
python版本:3.9.1
pytorch版本:1.9.1
cuda版本:11.1
怎样判断环境是否配置好了呢?那就是运行检测程序——detcet.py文件,然后会在runs文件夹里的detcet文件夹下生成一个exp文件夹,里面是一张框出几个人或者车的图片,具体什么我也忘了。反正就是能够运行detect.py文件。

4.建立数据集

在data目录下新建Annotations, images, ImageSets, labels 四个文件夹。
目录结构如下图所示:


其中images存放的是原始的图片数据集,Annotations存放的是标记后生成的xml文件,labels存放的是保存标记内容的txt文件,ImageSets存放的是训练数据集和测试数据集的分类情况。

巧妇难为无米之炊。做好准备工作之后,下一步要干什么?
那就是数据,数据从哪里来?一个就是下载网上公开的数据集,一个就是自己收集数据集。
基本上现在研究YOLOv5算法的主要有两个方向:一是在源代码上做文章,以此能够达到提高精度或者提高速度的目标,然后发论文。二是在数据集上做文章,用自己的数据集去解决某一实际问题,然后发论文。往往第一种方向会用公开的数据集,第二个方向会用自己的数据集。由于第一个方向需要对编程和数学有深厚的学识造诣,所以自然而然我就奔向了第二个方向。我使用的是自己的数据集。

5.标注数据集

Yolov5 使用精灵标注助手制作数据集详细教程

6.数据集分组

在yolov5-6.1根目录下新建一个文件makeTxt.py,(根目录大家都知道啥意思吧?我还真担心有人不知道)
代码如下:

import os
import randomtrainval_percent = 0.9
train_percent = 0.9
xmlfilepath = 'data/Annotations'
txtsavepath = 'data/ImageSets'
total_xml = os.listdir(xmlfilepath)num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)ftrainval = open('data/ImageSets/trainval.txt', 'w')
ftest = open('data/ImageSets/test.txt', 'w')
ftrain = open('data/ImageSets/train.txt', 'w')
fval = open('data/ImageSets/val.txt', 'w')for i in list:name = total_xml[i][:-4] + '\n'if i in trainval:ftrainval.write(name)if i in train:ftrain.write(name)else:fval.write(name)else:ftest.write(name)ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

接着再新建另一个文件voc_label.py,切记,代码中classes=[……] 中填入的一定要是自己在数据集中所标注的类别名称,标记了几个类别就填写几个类别名,填写错误的话会造成读取不出xml文件里的标注信息。代码如下:

# -*- coding: utf-8 -*-
# xml解析包
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import joinsets = ['train', 'test', 'val']
classes = ['cat', 'dog', 'pig']# 进行归一化操作
def convert(size, box): # size:(原图w,原图h) , box:(xmin,xmax,ymin,ymax)dw = 1./size[0]     # 1/wdh = 1./size[1]     # 1/hx = (box[0] + box[1])/2.0   # 物体在图中的中心点x坐标y = (box[2] + box[3])/2.0   # 物体在图中的中心点y坐标w = box[1] - box[0]         # 物体实际像素宽度h = box[3] - box[2]         # 物体实际像素高度x = x*dw    # 物体中心点x的坐标比(相当于 x/原图w)w = w*dw    # 物体宽度的宽度比(相当于 w/原图w)y = y*dh    # 物体中心点y的坐标比(相当于 y/原图h)h = h*dh    # 物体宽度的宽度比(相当于 h/原图h)return (x, y, w, h)    # 返回 相对于原图的物体中心点的x坐标比,y坐标比,宽度比,高度比,取值范围[0-1]# year ='2012', 对应图片的id(文件名)
def convert_annotation(image_id):'''将对应文件名的xml文件转化为label文件,xml文件包含了对应的bunding框以及图片长款大小等信息,通过对其解析,然后进行归一化最终读到label文件中去,也就是说一张图片文件对应一个xml文件,然后通过解析和归一化,能够将对应的信息保存到唯一一个label文件中去labal文件中的格式:calss x y w h  同时,一张图片对应的类别有多个,所以对应的bunding的信息也有多个'''# 对应的通过year 找到相应的文件夹,并且打开相应image_id的xml文件,其对应bund文件in_file = open('data/Annotations/%s.xml' % (image_id), encoding='utf-8')# 准备在对应的image_id 中写入对应的label,分别为# <object-class> <x> <y> <width> <height>out_file = open('data/labels/%s.txt' % (image_id), 'w', encoding='utf-8')# 解析xml文件tree = ET.parse(in_file)# 获得对应的键值对root = tree.getroot()# 获得图片的尺寸大小size = root.find('size')# 如果xml内的标记为空,增加判断条件if size != None:# 获得宽w = int(size.find('width').text)# 获得高h = int(size.find('height').text)# 遍历目标objfor obj in root.iter('object'):# 获得difficult ??difficult = obj.find('difficult').text# 获得类别 =string 类型cls = obj.find('name').text# 如果类别不是对应在我们预定好的class文件中,或difficult==1则跳过if cls not in classes or int(difficult) == 1:continue# 通过类别名称找到idcls_id = classes.index(cls)# 找到bndbox 对象xmlbox = obj.find('bndbox')# 获取对应的bndbox的数组 = ['xmin','xmax','ymin','ymax']b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))print(image_id, cls, b)# 带入进行归一化操作# w = 宽, h = 高, b= bndbox的数组 = ['xmin','xmax','ymin','ymax']bb = convert((w, h), b)# bb 对应的是归一化后的(x,y,w,h)# 生成 calss x y w h 在label文件中out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# 返回当前工作目录
wd = getcwd()
print(wd)for image_set in sets:'''对所有的文件数据集进行遍历做了两个工作:1.将所有图片文件都遍历一遍,并且将其所有的全路径都写在对应的txt文件中去,方便定位2.同时对所有的图片文件进行解析和转化,将其对应的bundingbox 以及类别的信息全部解析写到label 文件中去最后再通过直接读取文件,就能找到对应的label 信息'''# 先找labels文件夹如果不存在则创建if not os.path.exists('data/labels/'):os.makedirs('data/labels/')# 读取在ImageSets/Main 中的train、test..等文件的内容# 包含对应的文件名称image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()# 打开对应的2012_train.txt 文件对其进行写入准备list_file = open('data/%s.txt' % (image_set), 'w')# 将对应的文件_id以及全路径写进去并换行for image_id in image_ids:list_file.write('data/images/%s.jpg\n' % (image_id))# 调用  year = 年份  image_id = 对应的文件名_idconvert_annotation(image_id)# 关闭文件list_file.close()# os.system(‘comand’) 会执行括号中的命令,如果命令成功执行,这条语句返回0,否则返回1
# os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
# os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")

先运行makeTxt.py,makeTxt.py主要是将数据集分类成训练数据集和测试数据集,默认train,val,test按照8:1:1的比例进行随机分类,运行后ImagesSets文件夹中会出现四个文件,主要是生成的训练数据集和测试数据集的图片名称,如下图:

这几个txt你要点开看看,如果时空白的,说明你出错了,如果里面是下图这样的内容,说明没问题。

再运行voc_label.py文件,主要是将图片数据集标注后的xml文件中的标注信息读取出来并写入txt文件,运行后在labels文件夹中出现所有图片数据集的标注信息,如下图:

到这一步,已经把米准备好了,下一步就是修改几个参数就可以训练了。是不是感觉很麻烦,其实不是,你以后这些步骤都不用再做了,主要做的就是train和detect,也就是训练和检测。

7.文件、代码修改

7.1 文件修改

首先在data目录下,找到存在的coco.yaml,然后复制一份重命名为animal.yaml,这个animal是我的名字,你的名字自己取就行,打开animal.yaml,其中path,train,val,test分别为数据集的路径, nc为数据集的类别数,我这里只分了3类,names为类别的名称。这几个参数均按照自己的实际需求来修改。总之,这一步只用修改nc后面的数字,别的不要动。
animal.yaml的代码如下:

# Train command: python train.py --data data/cat.yaml
# Dataset should be placed next to yolov5 folder:
# parent
# ├── yolov5
#     └── data# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: data  # dataset root dir
train: train.txt  # train images (relative to 'path')
val: val.txt  # val images (relative to 'path')
test: test.txt  # test images (optional)# number of classes
nc: 3# class names
names: ['cat', 'dog', 'pig']

7.2 代码修改
yolov5提供了好几个训练模型,让你作为“基模型”进行训练,我用的是yolov5s模型,所以我找到models目录下提供了yolov5s.yaml文件进行修改,只用修改类的个数,我的类是3,所以nc:3.你根据你的实际情况决定n是多少,其余的不用修改。代码如下:

# Parameters
nc: 3  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple

最后要对train.py中的一些参数进行修改,train.py顾名思义就是用来训练的,
我们平时训练的话,主要用到的只有这几个参数而已:–weights,–cfg,–data,–epochs,–batch-size,–img-size,–project。

parser = argparse.ArgumentParser()
# 加载预训练的模型权重文件,如果文件夹下没有该文件,则在训练前会自动下载
parser.add_argument('--weights', type=str, default=ROOT / 'yolov5s.pt', help='initial weights path')
# 模型配置文件,网络结构,使用修改好的yolov5l.yaml文件
parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='model.yaml path')
# 数据集配置文件,数据集路径,类名等,使用配置好的animal.yaml文件
parser.add_argument('--data', type=str, default=ROOT / 'data/animal.yaml', help='dataset.yaml path')
# 超参数文件
parser.add_argument('--hyp', type=str, default=ROOT / 'data/hyps/hyp.scratch.yaml', help='hyperparameters path')
# 训练总轮次,1个epoch等于使用训练集中的全部样本训练一次,值越大模型越精确,训练时间也越长,默认为300
parser.add_argument('--epochs', type=int, default=300)
# 批次大小,一次训练所选取的样本数,显卡不太行的话,就调小点,反正3060是带不动batch-size=16的,传-1的话就是autobatch
parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
# 输入图片分辨率大小,默认为640
parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='train, val image size (pixels)')
# 是否采用矩形训练,默认False,开启后可显著的减少推理时间
parser.add_argument('--rect', action='store_true', help='rectangular training')
# 继续训练,默认从打断后的最后一次训练继续,需开启default=True
parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
# 仅保存最终一次epoch所产生的模型
parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
# 仅在最终一次epoch后进行测试
parser.add_argument('--noval', action='store_true', help='only validate final epoch')
# 禁用自动锚点检查
parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
# 超参数演变
parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations')
# 谷歌云盘bucket,一般不会用到
parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
# 是否提前缓存图片到内存,以加快训练速度,默认False
parser.add_argument('--cache', type=str, nargs='?', const='ram', help='--cache images in "ram" (default) or "disk"')
# 选用加权图像进行训练
parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
# 训练的设备,cpu;0(表示一个gpu设备cuda:0);0,1,2,3(多个gpu设备)。值为空时,训练时默认使用计算机自带的显卡或CPU
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
# 是否进行多尺度训练,默认False
parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
# 数据集是否只有一个类别,默认False
parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
# 是否使用adam优化器,默认False
parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
# 是否使用跨卡同步BN,在DDP模式使用
parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
# dataloader的最大worker数量,大于0时使用子进程读取数据,训练程序有可能会卡住
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
# 训练结果所存放的路径,默认为runs/train
parser.add_argument('--project', default=ROOT / 'runs/train', help='save to project/name')
# 训练结果所在文件夹的名称,默认为exp
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')
# 使用四合一dataloader
parser.add_argument('--quad', action='store_true', help='quad dataloader')
# 线性学习率
parser.add_argument('--linear-lr', action='store_true', help='linear LR')
# 标签平滑处理,默认0.0
parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
# 已训练多少次epoch后结果仍没有提升就终止训练,默认100
parser.add_argument('--patience', type=int, default=100, help='EarlyStopping patience (epochs without improvement)')
# 冻结模型层数,默认0不冻结,冻结主干网就传10,冻结所有就传24
parser.add_argument('--freeze', type=int, default=0, help='Number of layers to freeze. backbone=10, all=24')
# 设置多少次epoch保存一次模型
parser.add_argument('--save-period', type=int, default=-1, help='Save checkpoint every x epochs (disabled if < 1)')
# 分布式训练参数,请勿修改
parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')# Weights & Biases arguments(一般上用不着)
parser.add_argument('--entity', default=None, help='W&B: Entity')
parser.add_argument('--upload_dataset', action='store_true', help='W&B: Upload dataset as artifact table')
parser.add_argument('--bbox_interval', type=int, default=-1, help='W&B: Set bounding-box image logging interval')
parser.add_argument('--artifact_alias', type=str, default='latest', help='W&B: Version of dataset artifact to use')opt = parser.parse_known_args()[0] if known else parser.parse_args()

6.开始训练、得到模型

完成以上步骤后,把电脑所以运行的程序都关掉,就留一个P有Charm,运行train.py文件开始训练,这是就是检验你电脑性能的时候了,主要是看你的显卡性能,时间长短由你的显卡性能决定,也由你的数据集的数量决定。

当程序出现如下界面时,说明程序开始训练,没有错误。

为了截图,我的训练轮次epochs设置的时2次,默认是300次。

当训练结束后,会在runs文件夹下train文件里生成一个exp文件夹,里面有一堆文件,其中的weights里的best.pt就是训练得到的检测模型,用于下一步的检测之中。如下图所示:

6.用得到的模型、检测目标

有了训练得到的模型后,下一步我们就要干嘛了?检测试验,看训练得到的检测模型好不好用?那就要在detect.py文件里做文章了,这里面也有一些参数需要设置一下,主要用到的有这几个参数:–weights,–source,–img-size,–conf-thres,–project。详细如下图所示:

parser = argparse.ArgumentParser()
# 选用训练的权重,不指定的话会使用yolov5l.pt预训练权重
parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'runs/train/exp/weights/best.pt', help='model path(s)')
# 检测数据,可以是图片/视频路径,也可以是'0'(电脑自带摄像头),也可以是rtsp等视频流
parser.add_argument('--source', type=str, default=ROOT / 'inference/videos/动物识别.mp4', help='file/dir/URL/glob, 0 for webcam')
# 指定推理图片分辨率,默认640
parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')
# 置信度阈值,检测到的对象属于特定类(狗,猫,香蕉,汽车等)的概率,默认为0.25
parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
# 指定NMS(非极大值抑制)的IOU阈值,默认为0.45
parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
# 每张图最多检测多少目标,默认为1000个
parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
# 检测的设备,cpu;0(表示一个gpu设备cuda:0);0,1,2,3(多个gpu设备)。值为空时,训练时默认使用计算机自带的显卡或CPU
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
# 是否展示检测之后的图片/视频,默认False
parser.add_argument('--view-img', action='store_true', help='show results')
# 是否将检测的框坐标以txt文件形式保存(yolo格式),默认False
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
# 在输出标签结果txt中同样写入每个目标的置信度,默认False
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
# 从图片\视频上把检测到的目标抠出来保存,默认False
parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
# 不保存图片/视频,默认False
parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
# 设置只检测特定的类,如--classes 0 2 4 6 8,默认False
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3')
# 使用agnostic NMS(前背景),默认False
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
# 推理的时候进行多尺度,翻转等操作(TTA)推理,属于增强识别,速度会慢不少,默认False
parser.add_argument('--augment', action='store_true', help='augmented inference')
# 特征可视化,默认False
parser.add_argument('--visualize', action='store_true', help='visualize features')
# 更新所有模型,默认False
parser.add_argument('--update', action='store_true', help='update all models')
# 检测结果所存放的路径,默认为runs/detect
parser.add_argument('--project', default=ROOT / 'runs/detect', help='save results to project/name')
# 检测结果所在文件夹的名称,默认为exp
parser.add_argument('--name', default='exp', help='save results to project/name')
# 若现有的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')
# 半精度检测(FP16)
parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
# 在onnx推理中使用OpenCV DNN
parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')
opt = parser.parse_args()

修改好参数后,直接执行detect.py文件,如果不更改检测结果所产生的路径的话,检测完成后会在runs/detect/exp文件夹得到检测后的图片。如下图所示:

至此,整个从0到最后能检测你想要的目标就结束了,到这里是不感觉一点都不难了。万事开头难真的是句真理,等你掌握了这一整套流程后,你会发现你有很多好想法,利用YOLOv5算法来解决生活中很多的现实问题。

大家过程中有什么问题,可以在文章下面留言,我看到会及时回复的,别的朋友看到也会回复的!
再次提醒,别忘了点赞、关注、留言!

我告诉大家一个很残酷的现实,那就是你在学习过程中,出现bug了,你想让哪位博主给你解决,或者你想加别人联系方式,然后想有问题就问,在无偿情况下是不可能的,因为大家都很忙,所以我告诉大家一个方法,那就是遇到问题,就在CSDN上查,没有什么解决不了的,反正我一路走来,遇到的所以问题都是在CSDN上自己查的解决方法,相信我,你也可以的。

手把手教你用YOLOv5算法训练数据和检测目标(不会你捶我)相关推荐

  1. 【2023-Pytorch-检测教程】手把手教你使用YOLOV5做麦穗计数

    小麦是世界上种植地域最广.面积最大及产量最多的粮食作物,2021年世界小麦使用量达到7.54亿吨.小麦产量的及时预估对作物生产.粮食价格及粮食安全产生重大影响,单位面积穗数是小麦产量预估研究中的难点及 ...

  2. 手把手教你用YOLOv5训练自己的数据集(从Windows环境配置到模型部署)

    [小白CV]手把手教你用YOLOv5训练自己的数据集(从环境配置到模型部署) 本文禁止转载 前言: 1. 安装Anaconda: 2. 创建虚拟环境: 3. 安装pytorch: 4. 下载源码和安装 ...

  3. 手把手教你使用 YOLOV5 训练目标检测模型

    作者 | 肆十二 来源 | CSDN博客 这次要使用YOLOV5来训练一个口罩检测模型,比较契合当下的疫情,并且目标检测涉及到的知识点也比较多. 先来看看我们要实现的效果,我们将会通过数据来训练一个口 ...

  4. B站教学 手把手教你使用YOLOV5之口罩检测项目 最全记录详解 ( 深度学习 / 目标检测 / pytorch )

    目录 一.环境搭建 pytorch的下载 测试(cmd窗口中) pycharm下测试(要配置pycharm中的虚拟环境) 二.数据标注 下载labor image 使用labelimg进行图片标注 划 ...

  5. python爬取资料怎么样_手把手教你Python爬取新房数据

    原标题:手把手教你Python爬取新房数据 项目背景 新房数据,对于房地产置业者来说是买房的重要参考依据,对于房地产开发商来说,也是分析竞争对手项目的绝佳途径,对于房地产代理来说,是踩盘前的重要准备. ...

  6. 手把手教你使用YOLOV5训练自己的数据集并用TensorRT加速

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 前言 本文主要介绍目标检测YOLOV5算法来训练自己的数据集,并且使用TensorRT来对训练好的模型 ...

  7. 手把手教你在百度aistuio训练人工智能模型

    我在上文中介绍了百度的在线AI模型创建平台aistudio(博客地址:https://blog.csdn.net/BEYONDMA/article/details/101762116),我们知道深度学 ...

  8. 以『公众号』为例,手把手教你爬取PC端数据

    之前教过大家如何爬取手机APP数据[以某乎为实战案例,教你用Python爬取手机App数据] 思路:主要是通过手机设置代理,然后在pc端开启抓包工具获取数据包,然后在编写python代码(get方式) ...

  9. 手把手教你打造一个企业级实时数据中台【万字图文】

    引言--首先来聊聊现代企业数据架构及痛点: 数据孤岛:低效率和利用困难的根源 应用瓶颈:传统方案数据仓库.数据湖的不足   单讲这两个问题你可能会疑惑--为什么会出现这样的问题?   所以下面来讲讲两 ...

最新文章

  1. Java序列化技术与Protobuff
  2. oppo如何更新计算机,OPPO R17Pro手机怎么升级和降级系统?
  3. SpringBoot(笔记)
  4. java将一个对象赋值给另一个对象_java一个对象赋值给另一个对象,支持平铺类和层级类间的互转...
  5. centos python_【建议收藏】Python虚拟环境最全教程,看这篇就够了!
  6. java GoF 的 23 种设计模式的分类和功能
  7. Pascal调用与C调用
  8. teststand调用python模块_TestStand 界面重置【小技巧】
  9. 21个深度学习开源数据集分类汇总
  10. PS-fiveday-快速选择和魔棒工具(快速抠图)
  11. 马云正式辞职,那么天才郭盛华到底在追求什么呢?
  12. 青龙自动薅羊毛—【万年历】秒到
  13. Java学习lesson 10
  14. 计算机应用月什么,计算机应用月考试卷
  15. 与其自怨自艾,不如夯实勤奋
  16. cmd中启动MySQL输入net start mysql 显示‘net‘不是内部或外部命令,也不是可运行的程序或批处理的文件。
  17. 题解 P5265 【模板】多项式反三角函数
  18. GitBook学习入门教程
  19. SUNTANS模型学习(3)——学习cylinder算例
  20. Junit 入门使用教程

热门文章

  1. I'm Groot!
  2. ORA-04044:此处不允许过程、函数、程序包或类型,系统分析与解决
  3. Python-练习 40. 模块、类和对象
  4. a标签新窗口打开页面跳转sessionStorage丢失
  5. 金蝶云星空实施相关问题
  6. 基于springboot的婚纱摄影网站
  7. 原码、反码、补码、移码——小解
  8. CSS样式图片放在DIV里面,自动填充充满,且不变形
  9. 16款网站后台管理系统html模板代码下载
  10. overflow属性