赛题理解
这次参加的是阿里天池和datawhale发起的街景字符编码识别赛事,赛事的网址为https://tianchi.aliyun.com/competition/entrance/531795/introduction
几天提交下来,现在最高的正确率在0.89左右,下面是我每次提交的正确率:
之后我会详细叙述每次提交的过程和之后改进的措施。
方法选择
这次的题目是很典型的字符识别问题,一张图片里有多个字符,将它们全部识别出来就算对,识别错误、识别多了和识别少了都算错。那么首先很快就有两个思路:
一是把问题转换为定长字符识别,用简单的卷积神经网络训练模型,0~9识别为0~9,空白字符用其它方式表示。
第二种就是我采用的方法,将问题转化为目标识别问题,用yolo或者fastrcnn来训练模型。虽然最终结果只要将字符识别出来就行了,不用额外进行定位,但用目标检测模型可以很好的简化问题,所以就采用了第二种方法。而在fastrcnn和yolo之间,我比较常用yolo,但是理论上fastrcnn在准确率上表现是优于yolo模型的,yolo的优势在于识别速度快,而在这个题目中对速度并没有要求,所以追求更高准确率可以去尝试用fastrcnn解决这个问题。
Ubuntu下darknet的安装
安装darknet的资料网上有很多,这里就不再过多赘述了,主要是简要介绍一下流程。首先CUDA、cuDNN以及OpenCV是肯定需要的,如果没有这些,对于比赛中3W张图片的训练集,训练时间肯定是会大大拉长的。在安装好这些后,在github上访问https://github.com/AlexeyAB/darknet,然后git clone就行了。
最终文件夹里有这些文件:
(这里我是截的windows下的图,但是实际上我是在Ubuntu下操作的,因为Ubuntu用的不是很多,而且在Ubuntu下打开后面数据集3W张图片的文件夹会很卡,所以除了训练模型,其他操作我都是在windows下进行的。)
在实际运行前,还要下载yolov4的权重文件,yolov4.weights
然后打开Makefile,
GPU=0
CUDNN=0
CUDNN_HALF=0
OPENCV=0
AVX=0
OPENMP=0
LIBSO=0
ZED_CAMERA=0 # ZED SDK 3.0 and above
ZED_CAMERA_v2_8=0 # ZED SDK 2.X
这个时候我是习惯先什么都不改,确保GPU/CUDNN/OPENCV都等于0。然后在终端运行
make -j12 #多核电脑可以在-j后加上核数乘2的数字,可以加快编译的速度
命令,之后就会生成一个darknet的可执行文件,然后运行
./darknet detect cfg/yolov4.cfg yolov4.weights data/person.jpg
程序运行一段时间后,返回
horse: 100%
person: 100%
dog: 99%
证明darknet框架成功下载,没有下错、少下文件等情况,之后解决GPU的问题,将Makefile改为
GPU=1
CUDNN=1
CUDNN_HALF=0
OPENCV=1
重复上述步骤。
再编译,那么你的yolo现在就会基于GPU进行运算了,速度会比之前快很多。
数据处理
在安装好darknet后,接下来就是要处理数据了。因为官方给的数据集和yolo训练需要的数据还是有很大不同的,就拿训练集为例,官方给名为mchar_train.json,用Jupyter notebook读取:
import json
import pprint
f = open(
"mchar_train.json",
encoding='utf-8')
data = json.load(f)
pprint.pprint(data)
结果为
{
'000000.png': {
'height': [219, 219],
'label': [1, 9],
'left': [246, 323],
'top': [77, 81],
'width': [81, 96]},
'000001.png': {
'height': [32, 32],
'label': [2, 3],
'left': [77, 98],
'top': [29, 25],
'width': [23, 26]},
'000002.png': {
'height': [15, 15],
'label': [2,