一、准备阶段
首先在官方给出的数据中,已经有关于图像坐标的JSON文件,所以不需要我们再使用labelme去对每一张图片进行标注,只需要我们读取后,按照一定的方式保存就可以了。以下是参考别人的代码。
import os
import cv2
import json
train_json = json.load(open('mchar_train.json'))
for x in train_json:
img=cv2.imread("images/train/"+x)
width=img.shape[1]
height=img.shape[0]
train_label =list(map(int,train_json[x]['label']))
train_height=list(map(int,train_json[x]['height']))
train_left=list(map(int,train_json[x]['left']))
train_width=list(map(int,train_json[x]['width']))
train_top=list(map(int,train_json[x]['top']))
loc_pic="labels/train/"+x.split('.')[0]+'.txt'
pic=open(loc_pic,"w")
for i in range(len(train_label)):
pic_label=train_label[i]
pic_x=(train_left[i]+train_width[i]/2)/width
pic_y=(train_top[i]+train_height[i]/2)/height
pic_width=train_width[i]/width
pic_height=train_height[i]/height
pic.write(str(pic_label)+" "+str(pic_x)+" "+str(pic_y)+" "+str(pic_width)+" "+str(pic_height))
pic.write("\n")
pic.close()
每一个文件保存了图中的数据,和数据的位置,这个和标注后的文件格式是一样的。所以可以直接用。
二、修改模型配置
nc: 10 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
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
在模型中,修改分类数量nc,网络深度和宽度.
train: tianchi\images\train # train images (relative to 'path') 128 images
val: tianchi\images\val # val images (relative to 'path') 128 images
test: tianchi\images\test # test images (optional)
nc: 10 # number of classes
names: ['0','1','2','3','4','5','6','7','8','9',] # class names
在数据读取模块的时候修改读取的目录,修改分类数量和分类的具体标签。
parser.add_argument('--cfg', type=str, default='models/myyolov5s.yaml', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/mydata.yaml', help='dataset.yaml path')
在训练模型中,修改数据和配置文件,改为自己的。
三、训练
在训练完成后会保存一个最佳模型文件和最后模型文件,之后我们使用最佳模型对数据进行训练。
四、测试数据
使用以下代码进行测试,并且使最后的结果保存成txt文件。
python detect.py --weights runs/train/exp/weights/best.pt --source tianchi/images/test/ --save-txt
parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'runs/train/exp17/weights/best.pt', help='model path(s)')
parser.add_argument('--source', type=str, default='tianchi/images/test', help='file/dir/URL/glob, 0 for webcam')
修改模型地址和测试数据地址。
训练完成依然保存成和训练时使用的数据一样的格式,所以之后需要用代码将数据保存成官方要求的格式。
import pandas as pd
import glob
import os
def get(elem):
return elem[1]
label_path=glob.glob('D:/Program Files (x86)/Data/yolov5-6.2/runs/detect/exp2/labels/*.txt')
label_path.sort()
df_submit = pd.read_csv('mchar_sample_submit_A.csv')
df_submit.set_index('file_name')
for x in label_path:
text=open(x,'r')
result_list=[]
for line in text.readlines():
result_list.append((line.split(' ')[0],line.split(' ')[1]))
result_list.sort(key=get)
result=''
for j in result_list:
result+=j[0]
label_path=x.split('\\')[-1].split('.')[0]+'.png'
df_submit['file_code'][df_submit['file_name']==label_path]=result
text.close()
df_submit.to_csv('submit.csv', index=None)
五、结果
在不经过修改的情况下,第一次结果大概在0.91左右,达到了预期的要求
六、后续优化和思考
后续的优化主要在两个方向,一个是测试不同的超参数,另一个是进行一定程度的模型融合。
在超参数的测试中,主要将网络的深度和宽度进行了拓展。
depth_multiple: 1.00 # model depth multiple
width_multiple: 1.00 # layer channel multiple
因为在数据处理阶段,会进行Mosaic数据增强
会对图像进行旋转,偏移等,但是对于数字,不进行翻转可能效果更好(6 9反转结果会有很大不同)。所以在超参数的设置时,首先考虑的就是不要有翻转。