赞
踩
已记录一下自己的代码在GPU服务器端跑的时候流程和遇到的问题以及解决方法。
需要具备部分基础知识。
国际惯例,写在前面
-----------------------------------------------------------------------------------------------
声明:本文章仅供个人学习之用,由于作者能力有限,相关观点和信息仅供参考。
如有侵权请联系。
欢迎各位读者老爷提问和交流。
我们的目标是星辰大海!
因为公司原因,通知xshell和xftp没有版权,不让用了。如何解决远程登录到服务器上成为了第一个问题。
(1)安装remote插件。
安装 Remote Development插件,会自动安装这么多个。
(2)连接到服务器
点击这里的加号,被水印挡住了,或者按按下shift+ctrl+p,输入Remote-SSH: Connect to Host。
输入你要远程访问的IP地址
你可以每次都输入密码,或者自行配置
Host代表连接的名称(自定义)
HostName是服务器的地址
IdentityFile是免密登录需要的 是本地id_rsa文件的路径
User是登录服务器的用户名
Port是端口号
IdentitiesOnly也是免密登录值为yes
(1)下载anaconda
- # 切换root用户,输入密码
- su root
- # 进入root目录,安装脚本存放路径
- cd /root
- # 下载anaconda安装脚本(本教程采用清华源)
- wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2020.07-Linux-x86_64.sh
- # 安装anaconda
- bash Anaconda3-2020.07-Linux-x86_64.sh
-
- # Please, press ENTER to continue -> 回车继续
- # 阅读协议,同意按回车(跳过ctrl+c)
- # Do you accept the license terms? [yes|no] -> 同意协议输入yes回车
- # Anaconda3 will now be installed into this location -> 选择安装路径(本文安装/usr/local/anaconda3),等待安装
- # by running conda init? [yes|no] -> 是否添加系统环境,输入yes回车
- # 待安装结束
-
- # 刷新当前用户环境(激活环境)
- source ~/.bashrc
-
-
-
- #添加国内源
- conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- conda config --set show_channel_urls yes
-
- ## 新建虚拟环境
- conda create -n python36 python=3.6.5
- # 删除虚拟环境
- conda remove -n python36 --all
-
- # 查看所有环境
- conda env list
- # 激活虚拟环境
- conda activate python36
- # 退出当前虚拟环境
- conda deactivate python36
一定要记得最后一句,刷新
(2)使用conda安装requirement.txt,pip报错
- $ git clone https://github.com/ultralytics/yolov5
- $ cd yolov5
- $ pip3 install -r requirements.txt
-
- while read requirement; do conda install --yes $requirement || pip install $requirement; done < requirements.txt
(1)自己的数据集有几类,要和yaml文件中对应起来,我这里使用的是yolov5s,2类
(2) 照抄一个yaml文件,修改一下,需要按照自己的数据类型具体修改。
在data路径下,新建一个自己的xxx.yaml
需要修改的东西非常少,就是训练集,测试集,测试类别,类别名称。
但是需要注意的是,train:后面有个空格,跟的是你的数据的路径,注意,这里知道文件夹,当时看csdn看到一个写到train.txt的我一度以为我有问题
在这里我产生了问题,
我获取到的数据比较干净,在Annotations中是已经标注好的v5.txt格式 ,JPEGImages里面是原图片。
注意细节:
- ├── data
- │ ├── Annotations 进行 detection 任务时的标签文件,xml 形式,文件名与图片名一一对应
- │ ├── images 存放 .jpg 格式的图片文件
- │ ├── ImageSets 存放的是分类和检测的数据集分割文件,包含train.txt, val.txt,trainval.txt,test.txt
- │ ├── labels 存放label标注信息的txt文件,与图片一一对应
-
-
- ├── ImageSets(train,val,test建议按照8:1:1比例划分)
- │ ├── train.txt 写着用于训练的图片名称
- │ ├── val.txt 写着用于验证的图片名称
- │ ├── trainval.txt train与val的合集
- │ ├── test.txt 写着用于测试的图片名称
yolov5使用的是txt格式,每个图像对应一个txt文件,文件每一行为一个目标的信息,包括class,x_center,y_center,width,height格式。
格式如下:
那么问题来了。
很多朋友的数据都是标准的xml格式。
第一步,我们需要把xml转换成txt
xml2txt.py
- # -*- coding: utf-8 -*-
- import xml.etree.ElementTree as ET
- import pickle
- import os
- from os import listdir, getcwd
- from os.path import join
-
- #import shutil
-
- sets = ['train', 'test', 'val']
-
- #classes = ['1', '2', '3', '4', '5']
-
- '''
- classes = ['asamu', 'baishikele', 'baokuangli', 'aoliao', 'bingqilinniunai', 'chapai', 'fenda', 'guolicheng',
- 'haoliyou', 'heweidao', 'hongniu', 'hongniu2', 'hongshaoniurou', 'kafei', 'kaomo_gali', 'kaomo_jiaoyan',
- 'kaomo_shaokao', 'kaomo_xiangcon', 'kele', 'laotansuancai', 'liaomian', 'lingdukele', 'maidong', 'mangguoxiaolao',
- 'moliqingcha', 'niunai', 'qinningshui', 'quchenshixiangcao', 'rousongbing', 'suanlafen', 'tangdaren', 'wangzainiunai',
- 'weic', 'weitanai', 'weitaningmeng', 'wulongcha', 'xuebi', 'xuebi2', 'yingyangkuaixian', 'yuanqishui', 'xuebi-b', 'kebike',
- 'tangdaren3', 'chacui', 'heweidao2', 'youyanggudong', 'baishikele-2', 'heweidao3', 'yibao', 'kele-b', 'AD', 'jianjiao', 'yezhi',
- 'libaojian', 'nongfushanquan', 'weitanaiditang', 'ufo', 'zihaiguo', 'nfc', 'yitengyuan', 'xianglaniurou', 'gudasao', 'buding',
- 'ufo2', 'damaicha', 'chapai2', 'tangdaren2', 'suanlaniurou', 'bingtangxueli', 'weitaningmeng-bottle', 'liziyuan', 'yousuanru',
- 'rancha-1', 'rancha-2', 'wanglaoji', 'weitanai2', 'qingdaowangzi-1', 'qingdaowangzi-2', 'binghongcha', 'aerbeisi', 'lujikafei',
- 'kele-b-2', 'anmuxi', 'xianguolao', 'haitai', 'youlemei', 'weiweidounai', 'jindian', '3jia2', 'meiniye', 'rusuanjunqishui',
- 'taipingshuda', 'yida', 'haochidian', 'wuhounaicha', 'baicha', 'lingdukele-b', 'jianlibao', 'lujiaoxiang', '3+2-2',
- 'luxiangniurou', 'dongpeng', 'dongpeng-b', 'xianxiayuban', 'niudufen', 'zaocanmofang', 'wanglaoji-c', 'mengniu',
- 'mengniuzaocan', 'guolicheng2', 'daofandian1', 'daofandian2', 'daofandian3', 'daofandian4', 'yingyingquqi', 'lefuqiu']
- '''
- def convert(size, box):
- dw = 1. / size[0]
- dh = 1. / size[1]
- x = (box[0] + box[1]) / 2.0
- y = (box[2] + box[3]) / 2.0
- w = box[1] - box[0]
- h = box[3] - box[2]
- x = x * dw
- w = w * dw
- y = y * dh
- h = h * dh
- return (x, y, w, h)
-
- path = 'your path'# /a/Annotations 这里就是路径到a
-
- def convert_annotation(image_id):
- in_file = open(path+'Annotations/%s.xml' % (image_id))
- #print(111,in_file)
- out_file = open(path+'labels/%s.txt' % (image_id), 'w')
- tree = ET.parse(in_file)
- root = tree.getroot()
- size = root.find('size')
- w = int(size.find('width').text)
- h = int(size.find('height').text)
- for obj in root.iter('object'):
- #try:
- #difficult = obj.find('difficult').text
- #except AttributeError:
- # difficult = obj.find('Difficult').text
- cls = obj.find('name').text
- if cls not in classes:# or int(difficult) == 1:
- continue
- cls_id = classes.index(cls)
- xmlbox = obj.find('bndbox')
- b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
- float(xmlbox.find('ymax').text))
- bb = convert((w, h), b)
- out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
-
- wd = getcwd()
- print(wd)
- for image_set in sets:
- if not os.path.exists(path+'labels/'):
- os.makedirs(path+'labels/')
- image_ids = open(path+'ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
- #print(111,image_ids)
- list_file = open(path+'%s.txt' % (image_set), 'w')
- for image_id in image_ids:
- list_file.write(path+'images/%s.jpg\n' % (image_id))
-
- convert_annotation(image_id)
- list_file.close()
-
-
第二步,把一个整个的数据集进行切割,比如你有100张数据,80张用来训练,20张用来测试。
- # -*- coding: utf-8 -*-
- import os
- import random
- trainval_percent = 0.2
- train_percent = 0.8
- xmlfilepath = 'hat_data/Annotations'
- txtsavepath = 'hat_data/ImageSets/Main/'
- 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(txtsavepath+'trainval.txt', 'w')
- ftest = open(txtsavepath+'test.txt', 'w')
- ftrain = open(txtsavepath+'train.txt', 'w')
- fval = open(txtsavepath+'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()
-
-
-
这样会生成几个文件
第三步,按照文件把文件进行划分,
在yolov5中标准对应的是images和labels,你可以修改成自己的文件名字,但是那样子你得在/data/dataset.py中进行修改代码,反正都可以,
- # -*- coding: utf-8 -*-
- import os
- import shutil
-
-
- def locate(path):
- temp = []
-
- with open(path+'val.txt','rb') as f:
- #r = f.readlines()
- for line in f.readlines():
- #print(str(line.strip()).split("'")[1])
- temp.append(str(line.strip()).split("'")[1])
- return temp
-
-
-
-
- def object_save(path,pic,pic_save):
- temp = locate(path)
- #print(temp)
- if not os.path.exists(pic_save+'val'):
- os.makedirs(pic_save+'val')
- if not os.path.exists(pic_save+'train'):
- os.makedirs(pic_save+'train')
- for i in os.listdir(pic):
- if i[:-4] in temp:
- print(i)
- shutil.copyfile(pic+i,pic_save+'val/'+i)
- else:
- shutil.copyfile(pic+i,pic_save+'train/'+i)
-
- if __name__ == '__main__':
- ImageSets_path = './ImageSets/Main/'
- pic_path = './JPEGImages/'
- pic_save_path = './images/'
- object_save(ImageSets_path,pic_path,pic_save_path)
-
- labels_path = './Annotations/'
- labels_save_path = './labels/'
- object_save(ImageSets_path,labels_path,labels_save_path)
(3)修改train.py
(4)python train.py
1.AssertionError: train: No labels in images/train.cache. Can not train without labels. See https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data
查了网上很多资料,出现这个问题都在数据格式转换上面,我再三检查,我没什么问题。
改来改去,把yaml中路径换成了绝对路径,可以了。
老人,地铁,手机
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。