Author: Labyrinthine Leo
Init_time: 2020.10.26
GitHub: https://github.com/ultralytics/yolov5
Index Words: Object Detection
、YOLO v5
、YOLO Series
由于博主当前的研究问题涉及到图片的局部图像提取,于是决定使用目前比较流行且高效的目标检测网络框架YOLOv5
(虽然其沿用了社区的版本号v5,但只是ultralytics
团队的开源实现,并未获得官方的认可,此处暂且按下不表)来完成实验任务。博主之前并无目标检测方向的相关基础知识,因此在将其化为己用之前也趟了不少坑,这里特此记录为博客以备后用,同时将其微薄经验分享给大家,希望读者能够有所收获并对错误之处批评指正。
YOLOv5
根据模型的规模不同设有4个模型:v5s
、v5m
、v5l
、v5x
,如上图所示是这些不同规模的模型与EfficientDet
模型的性能对比图。而这些模型涉及的预训练权重数据该项目也已提供:checkpoints,只不过是存在谷歌云盘上,为了方便读者下载,笔者已将v5s
和v5x
的权重下载好放在了百度网盘上,以供大家使用:链接:https://pan.baidu.com/s/1_Abpe46JFevdBzOyBwGo-A 提取码:fuoe
。由于博主硬件设备有限使用cpu
运行项目,因此本文主要使用v5s
的较小模型进行实验,实验数据包括官网提供的coco128
的数据集,同时包含如何使用公开数据集(该部分实验使用roboflow
上的Mask Wearing Dataset
),最后博主还会讲解如何自制数据集进行训练。
引言 1.1 写作动机 1.2 背景介绍 1.3 文章结构
配置环境 2.1 下载源码 2.2 软硬件要求和安装依赖
相关数据下载 3.1 权重数据下载 3.2 coco128
数据集的下载
训练coco128
数据集 4.1 设置coco128.yaml
文件 4.2 文件目录组织 4.3 选择模型 4.4 训练 4.5 训练数据可视化 4.6 推断/预测
训练公开数据集Mask Wearing Dataset
5.1 数据集的选择 5.2 标签格式说明 5.3 数据集的放置和配置文件的修改
训练自制数据集 6.1 标注工具的使用 6.1.1 LabelImg
的安装 6.1.2 LabelImg
的使用 6.2 自制数据集文件的设置
FAQ和总结 7.1 FAQ 7.2 总结
Reference
在开始之前,我们可以看一下官网的训练定制数据的标准教程:Train Custom Data,先简单了解一下整体流程:1) 创建yaml
文件(简单理解为项目读取训练数据路径的配置文件),2) 创建数据的labels
信息,3)将项目和数据文件结构组织好,4) 选择上述中想要使用的模型并修改指定参数,5) 训练和检测。如果是新手可能还是一头雾水,无碍,Let's Go!
项目的源码可以直接使用Git Bash
在指定文件夹目录下输入下面命令行来获取:
git clone https://github.com/ultralytics/yolov5
或者在github
官网使用点击下载zip
源码进行解压即可使用,如下图所示。
下载完成以后,下图即整个项目的文件结构,这里先简单的做个说明:data
主要放置相关训练数据的配置文件(读取、解析等);models
放置各模型的参数配置文件;weights
则放置预训练模型的权重文件;inference
放置预测/推理阶段的测试图片;runs
则放置训练过程中保留下来的一些数据;当前目录下的文件重点关注train.py
、test.py
、detect.py
,这些是网络模型的关键源码(待精读深读)。
首先说明一下笔者的硬件配置:无GPU
、16G内存,事实证明v5s
模型可以跑,只不过耗时较长(建议夜间);依照下图所示当前Release
的软件要求,所以软件的配置:window 10
、IDE: pycharm 2020
、Python: 3.8
、PyTorch: 1.6.0 cpu版
、torchvision: 0.7.0
,笔者的软件环境均在anaconda
中进行安装,这部分前置环境配置在此不赘述(插句题外话,使用anaconda
将各个虚拟环境分隔开用于不同要求环境的项目中真的很nice!笔者之前是所有环境大杂烩在python
终端中,会很乱,强推anaconda
)。
接下来看看该项目运行起来需要哪些依赖库,如下图所示,在刚才了解过的文件结构中有一个requirements.txt
文件。
文件打开以后其实就是我们需要pip insatll
的第三方库列表(如下图所示),我们可以在终端中使用下列命令行进行一次性安装(终端下要进入该项目路径),当然也可以在终端中一个一个包的insatll
或者在pycharm
中进行导入安装(笔者是在anaconda
虚拟环境中进行insatll
然后在pycharm
中导入整个虚拟环境,较为方便)。
pip install -U -r requirements.txt
我们首先需要下载的就是预训练模型的权重数据,这里主要放出笔者下载的v5s
和v5x
模型权重:链接:https://pan.baidu.com/s/1_Abpe46JFevdBzOyBwGo-A 提取码:fuoe
,将下载好的yolov5s.pt
文件放置在当前文件夹下,如图所示:
在进行下一步之前,我们就可以验证前面进行的操作包括环境的配置、权重数据的下载是否没有问题(如果按照笔者的顺序应该是没有问题的,嘿嘿),我们在pycharm
的terminal
中输入以下命令:
python detect.py --source inference/images/ --weights ./yolov5s.pt
这行命令其实就是进行模型的测试/推断了,测试的图片就是前面讲的inference
目录下的图片,使用的权重数据就是刚才下载的yolov5s.pt
,而推断后的输出图片存放在inference/output/
中。
测试图片bus.jpg
&zidane.jpg
如下所示:
推断后的效果图片如下所示:
如果输出的效果图没有问题,那就证明环境以及代码都已准备无误,接下来就可以进行进一步的深入;不排除会有问题,那就将前面的步骤进行检查排错。
coco128
数据集的下载coco128
数据集是COCO
数据集的前128张图片,通常用作小型的教程数据集,这里面的128张图片即用作训练也用作验证。下载链接:https://github.com/ultralytics/yolov5/releases/download/v1.0/coco128.zip
,当然笔者也将其放在了网盘链接里。下载解压以后我们将文件夹放置在与/yolov5
同级目录下,如下所示:
打开coco128
文件夹可以看到其中有两个子文件夹,images
和labels
同级并列,分别放置训练的图片和对应的标签,同理后面制作自己的数据集时文件也是这么放置。文件结构如下图:
coco128
数据集coco128.yaml
文件在路径yolov5/data/
下含有后缀.yaml
的配置文件,可以简单理解为程序训练相应数据集所需要的对应配置文件,比如coco.yaml
就是对应COCO train2017
数据集,coco128.yaml
对应我们需要使用的coco128
数据集,打开coco128.yaml
文件,代码如下:
# COCO 2017 dataset http://cocodataset.org - first 128 training images
# Train command: python train.py --data ./data/coco128.yaml
# Dataset should be placed next to yolov5 folder:
# /parent_folder
# /coco128
# /yolov5
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ../coco128/images/train2017/ # 128 images 训练集
val: ../coco128/images/train2017/ # 128 images 验证集
# number of classes 类别数
nc: 80
# class names 类别列表
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
'hair drier', 'toothbrush']
配置文件主要包含以下内容:1) 提示将数据集文件夹放置yolov5
项目文件夹同级路径下,2) 设置训练集和验证集的图片位置(这里是相对路径,为何是../coco128
而不是../../coco128
,笔者也尚未搞清,待解惑),程序会自动搜索图片路径对应的标签文件,3) 设置图片中包含的类别数nc
,4) 设置所有类别的str列表names
。可以看到coco128
数据集中包含80类目标,其中目标名称的索引是从0开始,在这部分数据训练过程无需修改参数。
这里使用官网提供的目录截图,结构清晰明了。必须保证/coco128
和/yolov5
同级,coco128/train2017/labels/
和coco128/train2017/images/
同级。
yaml
配置文件设置好并且文件数据组织完毕,接下来就要选择一个模型进行训练。上文已经讲过有4个不同规模的模型,由于配置有限笔者使用的是规模最小训练速度最快的v5s
模型(当然性能会差一些,但是够用)。在./models/
下有4个对应模型的yaml
模型参数设置文件,我们打开其中的yolov5s.yaml
文件,内容如下:
# parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
# anchors
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Focus, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, BottleneckCSP, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 9, BottleneckCSP, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, BottleneckCSP, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 1, SPP, [1024, [5, 9, 13]]],
[-1, 3, BottleneckCSP, [1024, False]], # 9
]
# YOLOv5 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, BottleneckCSP, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, BottleneckCSP, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, BottleneckCSP, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, BottleneckCSP, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
可以看到里面有很多与模型相关的专业参数,定义了:1) parameters,2) anchor,3) YOLOv5 backbone,4) YOLOv5 head。如果不了解我们不需要知道也不用修改(正是笔者本人了,哈哈),需要了解的读者可以自行深究,这里笔者爱莫能助。但是有一个参数nc
需要注意,其为类别数,后期训练自制数据时需要修改的参数有且仅有它,在这里coco128
就是80类,不用修改。
上述准备就绪,接下来就要开始最耗时的训练阶段了。训练方式包含两种,一种是from scratch
,一种是使用我们下载好的预训练模型权重。对应的参数命令:
--cfg ./models/yolov5s.yaml --weights ''
--cfg ./models/yolov5s.yaml --weights ./yolov5s.pt
接下来我们在pycharm
中终端下输入以下命令进行训练模型:python train.py --img 640 --batch 16 --epochs 5 --data ./data/coco128.yaml --cfg ./models/yolov5s.yaml --weights ./yolov5s.pt
这是使用yolov5.pt
预训练模型训练了5个epochs
(这里只是测试,效果不佳可以增大),其中设置的图片大小为640*640,batch(size)
设为16(如果内存不足则将其设小),更多参数在train.py
文件中有解释,如下所示,如有需要可以设置。
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path')
parser.add_argument('--hyp', type=str, default='data/hyp.scratch.yaml', help='hyperparameters path')
parser.add_argument('--epochs', type=int, default=300)
parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes')
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('--notest', action='store_true', help='only test final epoch')
parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
parser.add_argument('--name', default='', help='renames experiment folder exp{N} to exp{N}_{name} if supplied')
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 as single-class dataset')
parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
parser.add_argument('--logdir', type=str, default='runs/', help='logging directory')
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
opt = parser.parse_args()
如何知道我们训练的数据标注十分正确呢,值得注意的是yolov5
设置了训练过程的数据保存和训练图片的可视化。训练的结果依次保存在./runs/exp0
、./runs/exp1
等路径下,你后续进行的实验结果也会依序存储。我们可以查看./runs/exp0/train_batch*.jpg
,就可以看到一个batch
中的训练图片,如下所示:
同时在第1个epoch
完成之后,可以打开./runs/exp0/test_batch0_gt.jpg
图片查看batch0
的ground truth
标签(即真实标签)和打开./runs/exp0/test_batch0_pred.jpg
图片查看batch0
的预测效果,如下所示:
训练过程中的losses
和评价指标均被保存在了Tensorboard
和./runs/exp0/results.txt
日志文件中,其中results.txt
会在训练结束可视化为results.png
。当然我们也可以使用Tensorboard
进行查看,在pycharm
的终端中输入:
tensorboard --logdir=runs
然后点击其中出现的URL
:http://localhost:6006/
,注意不能关闭命令行,即出现下图的数据可视化。
可见左边可以选择需要显示的exp
参数,右边包括metric
和train
的数据折线图,其中最多的实验训练了300个epoch
。
训练完毕后,整个过程的最好权重best.pt
和最后权重last.pt
程序会保存在./runs/exp*/weigths/
下,我们就可以使用其中的最好权重进行单张或者批量的图像目标识别预测(同时可以进行视频的预测,这里暂且不表)。推断命令如下:
python3 detect.py --source file.jpg # image
file.mp4 # video
./dir # directory
rtsp://170.93.143.139/rtplive/470011e600ef003a004ee33696235daa # rtsp stream
http://112.50.243.8/PLTV/88888888/224/3221225900/1.m3u8 # http stream
这里的--source
参数用来选择识别的图片、视频、图片文件夹的目录路径。
python detect.py --source ./inference/images/ --weights ./runs/exp4/weights/best.pt
预测后的输出图片或数据均会自动存放在./inference/output/
中,效果如下:
到这里为止,coco128
数据集的训练和预测的使用就算完满完成了,雄关漫道,步步为营。
Mask Wearing Dataset
训练完coco128
数据集,我们需要尝试使用公开数据集进行训练,这里博主推荐一个公开数据集网站roboflow
,里面有很多已经标注好的数据可以直接拿来训练练手,非常的方便。
博主这里使用其中的Mask Wearing Dataset
,其中包含149张图片,我们选择其中已标注好的416x416-black-padding
数据,点击下载时,选择的格式是TXT
下的yolov5 pytorch
。
在这里需要特别说明一下关于yolov5
图片数据和标签的格式,上文中提到的官网Train Custom Data教程中包含一个步骤Create Labels
,就是关于yolov5
中标签数据的格式要求。在目标检测中,我们对原始的图片中的目标要进行人工的手动标框,即bounding box
,同时设置该目标的类别(类别索引从0开始),如下图所示:
这样这些标框位置、类别等信息都会存为对应的label
标签文件,即我们上面所见的/coco128/labels/train2017/*.txt
文件,在yolov5
中标签信息文件是TXT
文件,其中包含了哪些信息,我们来看一下:
如上图所示,每个目标对应的bounding box
包含信息:1) bounding box
中心x坐标x_center
,2) bounding box
中心y坐标y_center
,3) bounding box
的宽width
,4) bounding box
的高height
。需要注意几点:1) 这4个信息均要被归一化为0-1之间的值,2) 这4个信息前加上目标类别class
总共5列信息即TXT
文件中的标签信息(如下图所示),则构成class x_center y_center width height
,3) 类别的索引从0开始。
对于下载好解压后的Mask Wearing Dataset
文件目录如下图所示,其中三个子文件夹train
、valid
、test
表示训练验证和测试的数据集,分别都包含原始图片和图片对应的标签信息txt
文件,注意:该数据集文件夹要与coco128
一样放置在/yolov5
同级目录下,并且图片和标签文件夹并列(上文已强调)。
同上,准备好数据后需要创建配置文件,并修改参数:**1、**在./data/
下创建mask.yaml
(name随意,与coco128.yaml
同级目录),配置文件内容如下:
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ../mask_datesets/train/images/ # 149 images 训练集
val: ../mask_datesets/valid/images/ # 149 images 验证集
# number of classes 类别数
nc: 2
# class names 类别列表
names: ['mask','no-mask']
**2、**因为选择的模型仍然是yolov5s
,则在./models/yolov5s.yaml
中将类别数nc
改为2即可。训练和预测的过程同上,指令只需将--data
参数设为--data ./data/mask.yaml
,其他均与上无异,预测效果图如下:
如果顺利完成上述内容,那么这部分的内容对你来说会是轻车熟路,因此这部分笔者尽量简而言之。上文中已提到,训练数据可以使用官方提供的或者公开开源的,但是难免会涉及我们自身研究问题相关的数据集,所以自制数据集并进行训练是必要的。
当我们拥有自己的的原始图片时,最关键的是对数据进行标框(bounding box
),可以使用Labelme
、LabelImg
、Labelbox
、CVAT
等bounding box
的标注工具,常用的两款是Labelme
和LabelImg
。其中Labelme
主要用于图像分割(语义分割、实例分割等)的标签任务,其在目标检测的标签任务中会生成json
文件,对于不同的模型的标签文件格式不同(如coco json
、xml
、txt
),因此需要使用者编写脚本将Labelme
生成的json
文件转换成需要的格式标签文件,会比较麻烦;相对来说,在目标检测的标签任务上,LabelImg
更加方便,可以直接选择需要的格式标签进行保存文件,因此本文使用LabelImg
工具。
LabelImg
的安装LabelImg
是一款用python
编写以Qt
开发GUI
的非常优秀的开源的图形图像标注工具,标注的结果可以保存为PASCAL VOC
格式的XML
文件(该格式通常用于ImageNet
)、可以保存为YOLO
系列的TXT
格式,因此非常的方便。github地址:``https://github.com/tzutalin/labelImg
。首先在其官网(即上面的github
地址)下载源码项目解压,然后在anaconda
中进入到该项目文件目录(不得不说,使用anaconda
真的很方便),如下:
cd e:\LabelImg-master
然后在终端输入以下命令:
conda install pyqt=5 # 安装pyqt
pyrcc5 -o resources.py resources.qrc
python labelImg.py
就会出现LabelImg
的GUI
界面(每次使用时进入源码目录,运行python labelImg.py
即可),如图所示:
LabelImg
的使用其实LabelImg
的使用很简单,按钮的使用以及图像的标注如下图所示
这里博主自制的图像数据是医疗图像相关的,读者可以以此为鉴自行标注自己的数据。
仍然同理,自制的数据集(包括初始图片../my_datasets/images/train/*.jpg
和标注后的标签信息文件../my_datasets/labels/train/*.txt
)和上文一样需要并列在同级目录下,并且总数据集文件夹要放置在/yolov5
同级目录下。结构如下:
my_datasets
|-- images
|-- train
|-- 1.jpg
...
|-- valid
|-- 1.jpg
...
|-- labels
|-- train
|-- 1.txt
...
|-- valid
|-- 1.txt
...
同时需要在./data/
下新建my_datasets.yaml
配置文件,将其中的文件读取路径、类别数、类别列表设置为自己的数据集要求即可;并将./models/yolov5s.yaml
中的nc
修改。
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ../my_datesets/images/train/ # 训练集
val: ../my_datesets/images/valid/ # 验证集# number of classes 类别数
nc: 4 # # class names 类别列表
names: ['L1','L2','L3','L4'] #
这样设置完毕后,训练时命令同样将--data
参数设为--data ./data/my_datasets.yaml
即可,自己的训练代数尽量设置大一些才会出现效果(博主训练了300个epochs
)。接下来的预测、可视化过程同上,此处不赘述。预测效果如下:
OK,到这里整个流程走下来,将yolov5
简单用起来就没有问题了(当然,其中模型的源码特别是数据读取和v1-v4论文的细节有待笔者深究,此处暂且挖坑后续填补)。
在整个过程中,无论是数据的下载配置还是程序的运行使用,不同人不同软件不同环境不同时间下都有可能出现不知所谓的bug
,这里将笔者遇到的几个问题简单填坑。
Labelme
软件安装的过程中,可能会出现如下问题。这是笔者在anaconda
环境下使用非base
虚拟环境安装Labelme
时出现的问题,显示其无法正常安装qt
依赖包,然后在github
的anaconda-issues
下有有效的解决方法(设置环境变量,github链接
:https://github.com/ContinuumIO/anaconda-issues/issues/10949
)。但是对博主来说无用,最后无奈,只能在base
环境下安装,可以成功安装(这并非博主的初衷)。这个问题读者可能会遇到,也有可能一次性成功安装,笔者的方法仅提供参考。Downloading and Extracting Packages
sip-4.19.13 | 265 KB | ############################################################################ | 100%
qt-5.9.7 | 72.5 MB | ############################################################################ | 100%
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
ERROR conda.core.link:_execute(700): An error occurred while installing package 'defaults::qt-5.9.7-vc14h73c81de_0'.
Rolling back transaction: done
LinkError: post-link script failed for package defaults::qt-5.9.7-vc14h73c81de_0
location of failed script: C:\Anaconda3\envs\tensorflow\Scripts.qt-post-link.bat
==> script messages <==
...
pycharm
中运行程序时可能会报如下关于Qt
的错误:This application failed to start because it could not find or load the Qt platform plugin "windows" in "".
Reinstalling the application may fix this problem.
解决方法:
/anaconda/Library/plugins
,将其绝对路径复制,在系统变量中作为新增QT_QPA_PLATFORM_PLUGIN_PATH
变量的变量值。pycharm
运行,即可解决。**解决方法:**在./train.py
文件中添加如下代码,表示允许副本的存在,笔者猜测是该dll
文件已经被其他项目加载导致无法在新项目中使用。图2的问题会随着图1问题的解决而消失。
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="True"
人生到处知何似,应似飞鸿踏雪泥,整个过程还算充实,特别在写这篇博文时也算是花费不少心思,希望能对每一位似笔者初入门的读者有微薄之用。科研长路,雄关漫道,与君共勉!
临渊羡鱼不如退而结网 创作不易,如果您觉得这篇文章对你有用,可以点个赞,算是对笔者的支持和激励!这里是Leo的博客城堡,以Python为核,ML&DL为主,泛之形形色色,输寥寥拙见,摄浮光掠影,讲三两故事。临渊羡鱼,不如退而结网,持续干货输出,有趣的灵魂值得你的关注!原文可以去笔者的github
主页:https://github.com/LabyrinthineLeo/Yxs_Git_Learning_repos
查看(如果可以,点个star
也无妨呀,嘿嘿)。