提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
作为一名准研究生,已经在暑假参与了一丢丢学校的工程项目(打杂ing),这次的任务是帮学长在服务器上建立一个能够跑通yolov5的镜像,并且用yolov5训练船舰数据集(也可以是自己的数据集)。所以本篇文章就来记录自己用yolov5训练船舰集的过程,方便日后复习,也希望与大家互相学习交流。
首先要登上学校的服务器,由于本人没有一卡通账号,只能借助奔波霸学长的账号,登录学校。需要下载EasyConnect,登上学长提供的账号密码,就可以使用学校的服务器啦!
FileZilla是一款用于沟通本地存储与服务器存储空间的软件,也就是说,想要在服务器上跑自己的数据集,就需要用FileZilla吧自己的数据传送到服务器。下载后输入IP地址,再输入学长给的AI Max账号密码,就能获得操作服务器存储空间的权限了。
ssh是一款VSCode的插件,在VSCode商店中就能够搜索到该插件。安装以后,会发现最左侧的功能栏里面多了一个图标,点进去之后,在点击1号位置的加号,输入自己的地址(2号位置),再登陆AI Max的账号就行了。注意选择的是linux系统。
通过FileZilla把yolov5传到服务器上,然后用VSCode打开就行了。
除了从github上down下来yolov5的代码之外,我们还需要对服务器(或者个人PC)的环境进行配置,首先需要安装Anaconda3,服务器的电脑已经安装了,我也不再多费口舌。用VSCode打开终端,输入
conda create -n YOlov5 python=3.8
conda activate YOlov5
之后进入yolov5的根目录,安装必要的环境:
pip install -r requirements.txt
等待安装完了之后,看一下pytorch的版本能不能对的上自己的cuda版本,笔者对不上(torch为cuda10,但是cuda是11.0),因此需要卸载该版本的torch和torchvision。去官网找到对应的下载指令,下载CUDA11.0版本的pytorch,指令自己去官网找吧。
装好必备环境之后,就可以开始整理数据和修改参数了
首先说明一下我的数据集,不同于网上的其他博客,我的label是json转成yolo的.txt格式(其他文章大多数都是.xml转yolo),而且已经转好了,所以我可以堂而皇之的省略掉转换的过程。
首先在根目录下创建文件夹:images ImageSets和labels(注意: images内为数据集原始图片,labels内为已经转换好的yolo标注,即.txt文件)
根目录下创建 1make_txt.py 文件,代码如下:
import os
import random
trainval_percent = 0.1
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:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
上面的代码用于将整个数据集进行划分,分别分为trainval,test,train和val
下面的代码作用是将划分好的代码加上绝对路径,放在data文件夹下面:命名为DivideLabel.py
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets = ['train', 'test','val']
if not os.path.exists('data/labels/'):
os.makedirs('data/labels/')
for image_set in sets:
image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()
list_file = open('data/%s.txt' % (image_set), 'w')
for image_id in image_ids:
list_file.write('data/images/%s.jpg\n' % (image_id))
list_file.close()
这里的yaml和以往的cfg文件是差不多的,但需要配置一份属于自己数据集的yaml文件。可以复制data目录下的任一.yaml文件,大家都喜欢复制COCO.yaml,我也就使用了这个文件,将文件重新命名为ship.yaml
主要修改三个地方,在下图中有详细的操作:
models下有四个模型,smlx需要训练的时间依次增加,按照需求选择一个文件进行修改即可:
师兄恰巧有yolov5m的权重文件,使用这里修改了yolov5m.yaml。修改过程就只需要将nc的类别修改为自己数据集的类别就行了。
这里需要对train.py文件内的参数进行修改,把他写的东西换成是自己要用的就好了。修改的地方在418到425行:
def parse_opt(known=False):
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default='weights/yolov5m.pt', help='initial weights path')
parser.add_argument('--cfg', type=str, default='models/yolov5m.pt', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/ship.yaml', help='dataset.yaml path')
parser.add_argument('--hyp', type=str, default='data/hyps/hyp.scratch.yaml', help='hyperparameters path')
parser.add_argument('--epochs', type=int, default=100)
parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
2、3、4行的weights,cfg,data按照自己之前准备的数据和各类文件填写就好了。epochs迭代次数自己决定,因为自己是验证一下配置的环境是否成功,使用default只设置了100。迭代次数越长,跑的时间就越长。batch-size过高可能会影响电脑运行速度,还是要根据自己电脑硬件条件决定增加还是减少
python train.py --data ship.yaml --cfg yolov5m.yaml --weights weights/yolov5m.pt --epochs 10 --batch-size 32
然后就开始运行了:
(YOlov5) root@interactive68949:/opt/data/private/wangze/yolov5-master/yolov5-master# python train.py --data ship.yaml --cfg yolov5m.yaml --weights weights/yolov5m.pt --epochs 10 --batch-size 32
train: weights=weights/yolov5m.pt, cfg=yolov5m.yaml, data=ship.yaml, hyp=data/hyps/hyp.scratch.yaml, epochs=10, batch_size=32, imgsz=640, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, evolve=None, bucket=, cache=None, image_weights=False, device=, multi_scale=False, single_cls=False, adam=False, sync_bn=False, workers=8, project=runs/train, entity=None, name=exp, exist_ok=False, quad=False, linear_lr=False, label_smoothing=0.0, upload_dataset=False, bbox_interval=-1, save_period=-1, artifact_alias=latest, local_rank=-1, freeze=0
github: skipping check (not a git repository), for updates see https://github.com/ultralytics/yolov5
YOLOv5 2021-8-11 torch 1.7.1 CUDA:0 (TITAN RTX, 24220.3125MB)
hyperparameters: lr0=0.01, lrf=0.2, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0
Weights & Biases: run 'pip install wandb' to automatically track and visualize YOLOv5 runs (RECOMMENDED)
TensorBoard: Start with 'tensorboard --logdir runs/train', view at http://localhost:6006/
from n params module arguments
0 -1 1 5280 models.common.Focus [3, 48, 3]
1 -1 1 41664 models.common.Conv [48, 96, 3, 2]
2 -1 1 65280 models.common.C3 [96, 96, 2]
3 -1 1 166272 models.common.Conv [96, 192, 3, 2]
4 -1 1 629760 models.common.C3 [192, 192, 6]
5 -1 1 664320 models.common.Conv [192, 384, 3, 2]
6 -1 1 2512896 models.common.C3 [384, 384, 6]
7 -1 1 2655744 models.common.Conv [384, 768, 3, 2]
8 -1 1 1476864 models.common.SPP [768, 768, [5, 9, 13]]
9 -1 1 4134912 models.common.C3 [768, 768, 2, False]
10 -1 1 295680 models.common.Conv [768, 384, 1, 1]
11 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
12 [-1, 6] 1 0 models.common.Concat [1]
13 -1 1 1182720 models.common.C3 [768, 384, 2, False]
14 -1 1 74112 models.common.Conv [384, 192, 1, 1]
15 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
16 [-1, 4] 1 0 models.common.Concat [1]
17 -1 1 296448 models.common.C3 [384, 192, 2, False]
18 -1 1 332160 models.common.Conv [192, 192, 3, 2]
19 [-1, 14] 1 0 models.common.Concat [1]
20 -1 1 1035264 models.common.C3 [384, 384, 2, False]
21 -1 1 1327872 models.common.Conv [384, 384, 3, 2]
22 [-1, 10] 1 0 models.common.Concat [1]
23 -1 1 4134912 models.common.C3 [768, 768, 2, False]
24 [17, 20, 23] 1 40410 models.yolo.Detect [5, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [192, 384, 768]]
Model Summary: 391 layers, 21072570 parameters, 21072570 gradients, 50.5 GFLOPs
Transferred 498/506 items from weights/yolov5m.pt
Scaled weight_decay = 0.0005
optimizer: SGD with parameter groups 83 weight, 86 weight (no decay), 86 bias
train: Scanning '/opt/data/private/wangze/yolov5-master/yolov5-master/data/train' images and labels...2700 found, 0 missing, 0 empty, 1 corrupted: 100%|███████████████████████████████| 2700/2700 [00:02<00:00, 932.35it/s]
train: WARNING: Ignoring corrupted image and/or label data/images/trainimg0468.jpg: non-normalized or out of bounds coordinate labels
train: New cache created: /opt/data/private/wangze/yolov5-master/yolov5-master/data/train.cache
val: Scanning '/opt/data/private/wangze/yolov5-master/yolov5-master/data/val' images and labels...30 found, 0 missing, 0 empty, 0 corrupted: 100%|█████████████████████████████████████████| 30/30 [00:00<00:00, 335.44it/s]
val: New cache created: /opt/data/private/wangze/yolov5-master/yolov5-master/data/val.cache
Plotting labels...
autoanchor: Analyzing anchors... anchors/target = 2.30, Best Possible Recall (BPR) = 1.0000
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs/train/exp7
Starting training for 10 epochs...
Epoch gpu_mem box obj cls labels img_size
0/9 12.2G 0.06682 0.02724 0.04497 32 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:39<00:00, 2.15it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 3.91it/s]
all 30 30 0.189 0.571 0.246 0.13
Epoch gpu_mem box obj cls labels img_size
1/9 12.2G 0.04252 0.01902 0.043 32 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:36<00:00, 2.30it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 5.54it/s]
all 30 30 0.383 0.666 0.461 0.32
Epoch gpu_mem box obj cls labels img_size
2/9 12.2G 0.03569 0.01488 0.03932 25 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:37<00:00, 2.28it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 5.50it/s]
all 30 30 0.381 0.774 0.476 0.314
Epoch gpu_mem box obj cls labels img_size
3/9 12.2G 0.03232 0.01323 0.03531 36 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:37<00:00, 2.26it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 5.24it/s]
all 30 30 0.525 0.843 0.712 0.457
Epoch gpu_mem box obj cls labels img_size
4/9 12.2G 0.03249 0.01264 0.03299 28 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:37<00:00, 2.25it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 5.52it/s]
all 30 30 0.647 0.837 0.819 0.613
Epoch gpu_mem box obj cls labels img_size
5/9 12.2G 0.03246 0.01223 0.02788 28 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:37<00:00, 2.27it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 4.98it/s]
all 30 30 0.838 0.834 0.833 0.533
Epoch gpu_mem box obj cls labels img_size
6/9 12.2G 0.03137 0.01188 0.02538 30 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:36<00:00, 2.33it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 5.60it/s]
all 30 30 0.852 0.82 0.886 0.693
Epoch gpu_mem box obj cls labels img_size
7/9 12.2G 0.02757 0.01152 0.02236 26 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:36<00:00, 2.33it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 4.83it/s]
all 30 30 0.924 0.86 0.917 0.749
Epoch gpu_mem box obj cls labels img_size
8/9 12.2G 0.03008 0.01179 0.02374 41 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:36<00:00, 2.32it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 5.58it/s]
all 30 30 0.88 0.756 0.882 0.708
Epoch gpu_mem box obj cls labels img_size
9/9 12.2G 0.026 0.01127 0.02038 29 640: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 85/85 [00:36<00:00, 2.34it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 4.24it/s]
all 30 30 0.743 0.946 0.877 0.748
freedom 30 7 0.703 1 0.978 0.846
nimitz 30 3 0.4 0.899 0.585 0.428
burke 30 7 0.874 1 0.978 0.831
ticonderoga 30 6 0.91 0.833 0.881 0.742
wasp 30 7 0.827 1 0.961 0.892
10 epochs completed in 0.108 hours.
Optimizer stripped from runs/train/exp7/weights/last.pt, 42.5MB
Optimizer stripped from runs/train/exp7/weights/best.pt, 42.5MB
Results saved to runs/train/exp7
运行detect.py
python detect.py --weights runs/train/exp7/weights/best.pt --source data/Samples/ --device 0 --save-txt
上文提到Results saved to runs/train/exp7,所以我们使用最好的模型来进行测试,即runs/train/exp7/weights/best.pt
source data/Samples/ 代表的是需要预测的图片路径,我在data里面建立了此文件夹,放了几张图片。
运行结果:
(YOlov5) root@interactive68949:/opt/data/private/wangze/yolov5-master/yolov5-master# python detect.py --weights runs/train/exp7/weights/best.pt --source data/Samples/ --device 0 --save-txt
detect: weights=['runs/train/exp7/weights/best.pt'], source=data/Samples/, imgsz=640, conf_thres=0.25, iou_thres=0.45, max_det=1000, device=0, view_img=False, save_txt=True, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs/detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False
YOLOv5 2021-8-11 torch 1.7.1 CUDA:0 (TITAN RTX, 24220.3125MB)
Fusing layers...
Model Summary: 308 layers, 21053802 parameters, 0 gradients, 50.4 GFLOPs
image 1/4 /opt/data/private/wangze/yolov5-master/yolov5-master/data/Samples/trainimg0001.jpg: 512x640 1 freedom, Done. (0.102s)
image 2/4 /opt/data/private/wangze/yolov5-master/yolov5-master/data/Samples/trainimg0037.jpg: 512x640 1 freedom, Done. (0.019s)
image 3/4 /opt/data/private/wangze/yolov5-master/yolov5-master/data/Samples/trainimg0093.jpg: 512x640 1 burke, Done. (0.017s)
image 4/4 /opt/data/private/wangze/yolov5-master/yolov5-master/data/Samples/trainimg0094.jpg: 512x640 1 freedom, Done. (0.016s)
Results saved to runs/detect/exp2
4 labels saved to runs/detect/exp2/labels
Done. (0.217s)
结果显示4 labels saved to runs/detect/exp2/labels,从VSCode打开该路径,就会出现预测的情况了:
从结果看,仅仅训练了10个epochs,就有这样的效果,已经很不错了
经过一下午的实践,总算是在服务器上跑通了yolov5,对自己来说也算是不小的收获了。希望再接再厉噢。