上节我们讲了第一部分,如何用生成简易的车牌,这节课中我们会用PaddlePaddle来识别生成的车牌。


数据读取

  在上一节生成车牌时,我们可以分别生成训练数据和测试数据,方法如下(完整代码在这里):

 # 将生成的车牌图片写入文件夹,对应的label写入label.txt
def genBatch(self, batchSize,pos,charRange, outputPath,size):
if (not os.path.exists(outputPath)):
os.mkdir(outputPath)
outfile = open('label.txt','w')
for i in xrange(batchSize):
plateStr,plate = G.genPlateString(-1,-1)
print plateStr,plate
img = G.generate(plateStr);
img = cv2.resize(img,size);
cv2.imwrite(outputPath + "/" + str(i).zfill(2) + ".jpg", img);
outfile.write(str(plate)+"\n")

  生成好数据后,我们写一个reader来读取数据 ( reador.py )

 def reader_creator(data,label):
def reader():
for i in xrange(len(data)):
yield data[i,:],int(label[i])
return reader

  灌入模型时,我们需要调用paddle.batch函数,将数据shuffle后批量灌入模型中:

 # 读取训练数据
train_reader = paddle.batch(paddle.reader.shuffle(
reador.reader_creator(X_train,Y_train),buf_size=200),
batch_size=16) # 读取验证数据
val_reader = paddle.batch(paddle.reader.shuffle(
reador.reader_creator(X_val,Y_val),buf_size=200),
batch_size=16)
trainer.train(reader=train_reader,num_passes=20,event_handler=event_handler)

构建网络模型

  因为我们训练的是端到端的车牌识别,所以一开始构建了两个卷积-池化层训练,训练完后同步训练7个全连接层,分别对应车牌的7位字符,最后将其拼接起来,与原始的label计算Softmax值,预测训练结果。 

 def get_network_cnn(self):
# 加载data和label
x = paddle.layer.data(name='x', type=paddle.data_type.dense_vector(self.data))
y = paddle.layer.data(name='y', type=paddle.data_type.integer_value(self.label))
# 构建卷积-池化层-1
conv_pool_1 = paddle.networks.simple_img_conv_pool(
input=x,
filter_size=12,
num_filters=50,
num_channel=1,
pool_size=2,
pool_stride=2,
act=paddle.activation.Relu())
drop_1 = paddle.layer.dropout(input=conv_pool_1, dropout_rate=0.5)
# 构建卷积-池化层-2
conv_pool_2 = paddle.networks.simple_img_conv_pool(
input=drop_1,
filter_size=5,
num_filters=50,
num_channel=20,
pool_size=2,
pool_stride=2,
act=paddle.activation.Relu())
drop_2 = paddle.layer.dropout(input=conv_pool_2, dropout_rate=0.5) # 全连接层
fc = paddle.layer.fc(input = drop_2, size = 120)
fc1_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc1 = paddle.layer.fc(input = fc1_drop,size = 65,act = paddle.activation.Linear()) fc2_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc2 = paddle.layer.fc(input = fc2_drop,size = 65,act = paddle.activation.Linear()) fc3_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc3 = paddle.layer.fc(input = fc3_drop,size = 65,act = paddle.activation.Linear()) fc4_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc4 = paddle.layer.fc(input = fc4_drop,size = 65,act = paddle.activation.Linear()) fc5_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc5 = paddle.layer.fc(input = fc5_drop,size = 65,act = paddle.activation.Linear()) fc6_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc6 = paddle.layer.fc(input = fc6_drop,size = 65,act = paddle.activation.Linear()) fc7_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc7 = paddle.layer.fc(input = fc7_drop,size = 65,act = paddle.activation.Linear()) # 将训练好的7个字符的全连接层拼接起来
fc_concat = paddle.layer.concact(input = [fc21, fc22, fc23, fc24,fc25,fc26,fc27], axis = 0)
predict = paddle.layer.classification_cost(input = fc_concat,label = y,act=paddle.activation.Softmax())
return predict

训练模型

   构建好网络模型后,就是比较常见的步骤了,譬如初始化,定义优化方法, 定义训练参数,定义训练器等等,再把第一步里我们写好的数据读取的方式放进去,就可以正常跑模型了。

 class NeuralNetwork(object):
def __init__(self,X_train,Y_train,X_val,Y_val):
paddle.init(use_gpu = with_gpu,trainer_count=1) self.X_train = X_train
self.Y_train = Y_train
self.X_val = X_val
self.Y_val = Y_val def get_network_cnn(self): x = paddle.layer.data(name='x', type=paddle.data_type.dense_vector(self.data))
y = paddle.layer.data(name='y', type=paddle.data_type.integer_value(self.label))
conv_pool_1 = paddle.networks.simple_img_conv_pool(
input=x,
filter_size=12,
num_filters=50,
num_channel=1,
pool_size=2,
pool_stride=2,
act=paddle.activation.Relu())
drop_1 = paddle.layer.dropout(input=conv_pool_1, dropout_rate=0.5)
conv_pool_2 = paddle.networks.simple_img_conv_pool(
input=drop_1,
filter_size=5,
num_filters=50,
num_channel=20,
pool_size=2,
pool_stride=2,
act=paddle.activation.Relu())
drop_2 = paddle.layer.dropout(input=conv_pool_2, dropout_rate=0.5) fc = paddle.layer.fc(input = drop_2, size = 120)
fc1_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc1 = paddle.layer.fc(input = fc1_drop,size = 65,act = paddle.activation.Linear()) fc2_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc2 = paddle.layer.fc(input = fc2_drop,size = 65,act = paddle.activation.Linear()) fc3_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc3 = paddle.layer.fc(input = fc3_drop,size = 65,act = paddle.activation.Linear()) fc4_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc4 = paddle.layer.fc(input = fc4_drop,size = 65,act = paddle.activation.Linear()) fc5_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc5 = paddle.layer.fc(input = fc5_drop,size = 65,act = paddle.activation.Linear()) fc6_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc6 = paddle.layer.fc(input = fc6_drop,size = 65,act = paddle.activation.Linear()) fc7_drop = paddle.layer.dropout(input = fc,dropout_rate = 0.5)
fc7 = paddle.layer.fc(input = fc7_drop,size = 65,act = paddle.activation.Linear()) fc_concat = paddle.layer.concact(input = [fc21, fc22, fc23, fc24,fc25,fc26,fc27], axis = 0)
predict = paddle.layer.classification_cost(input = fc_concat,label = y,act=paddle.activation.Softmax())
return predict # 定义训练器
def get_trainer(self): cost = self.get_network() #获取参数
parameters = paddle.parameters.create(cost) optimizer = paddle.optimizer.Momentum(
momentum=0.9,
regularization=paddle.optimizer.L2Regularization(rate=0.0002 * 128),
learning_rate=0.001,
learning_rate_schedule = "pass_manual") # 创建训练器
trainer = paddle.trainer.SGD(
cost=cost, parameters=parameters, update_equation=optimizer)
return trainer # 开始训练
def start_trainer(self,X_train,Y_train,X_val,Y_val):
trainer = self.get_trainer() result_lists = []
def event_handler(event):
if isinstance(event, paddle.event.EndIteration):
if event.batch_id % 10 == 0:
print "\nPass %d, Batch %d, Cost %f, %s" % (
event.pass_id, event.batch_id, event.cost, event.metrics)
if isinstance(event, paddle.event.EndPass):
# 保存训练好的参数
with open('params_pass_%d.tar' % event.pass_id, 'w') as f:
parameters.to_tar(f)
# feeding = ['x','y']
result = trainer.test(
reader=val_reader)
# feeding=feeding)
print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics) result_lists.append((event.pass_id, result.cost,
result.metrics['classification_error_evaluator'])) # 开始训练
train_reader = paddle.batch(paddle.reader.shuffle(
reador.reader_creator(X_train,Y_train),buf_size=200),
batch_size=16) val_reader = paddle.batch(paddle.reader.shuffle(
reador.reader_creator(X_val,Y_val),buf_size=200),
batch_size=16)
# val_reader = paddle.reader(reador.reader_creator(X_val,Y_val),batch_size=16) trainer.train(reader=train_reader,num_passes=20,event_handler=event_handler)

输出结果

  上一步训练完以后,保存训练完的模型,然后写一个test.py进行预测,需要注意的是,在预测时,构建的网络结构得和训练的网络结构相同。

#批量预测测试图片准确率
python test.py /Users/shelter/test ##输出结果示例
output:
预测车牌号码为:津 K 4 2 R M Y
输入图片数量:100
输入图片行准确率:0.72
输入图片列准确率:0.86

  如果是一次性只预测一张的话,在终端里会显示原始的图片与预测的值,如果是批量预测的话,会打印出预测的总准确率,包括行与列的准确率。


总结

   车牌识别的方法有很多,商业化落地的方法也很成熟,传统的方法需要对图片灰度化,字符进行切分等,需要很多数据预处理的过程,端到端的方法可以直接将原始的图片灌进去进行训练,最后出来预测的车牌字符的结果,这个方法在构建了两层卷积-池化网络结构后,并行训练了7个全连接层来进行车牌的字符识别,可以实现端到端的识别。但是在实际训练过程中,仍然有一些问题,譬如前几个训练的全连接层的准确率要比最后一两个的准确率高,大家可以分别打印出每一个全连接层的训练结果准确率对比一下,可能是由于训练还没有收敛导致的,也可能有其他原因,如果在做的过程中发现有什么问题,或者有更好的方法,欢迎留言~

参考文献:

1.我的github:https://github.com/huxiaoman7/mxnet-cnn-plate-recognition

【深度学习】用PaddlePaddle进行车牌识别(二)的更多相关文章

  1. 【深度学习系列】用PaddlePaddle进行车牌识别(一)

    小伙伴们,终于到了实战部分了!今天给大家带来的项目是用PaddlePaddle进行车牌识别.车牌识别其实属于比较常见的图像识别的项目了,目前也属于比较成熟的应用,大多数老牌厂家能做到准确率99%+.传 ...

  2. 【深度学习系列】用PaddlePaddle进行车牌识别(二)

    上节我们讲了第一部分,如何用生成简易的车牌,这节课中我们会用PaddlePaddle来识别生成的车牌. 数据读取 在上一节生成车牌时,我们可以分别生成训练数据和测试数据,方法如下(完整代码在这里): ...

  3. keras框架下的深度学习(一)手写体识别

    这个系列文章主要记录使用keras框架来搭建深度学习模型的学习过程,其中有一些自己的想法和体会,主要学习的书籍是:Deep Learning with Python,使用的IDE是pycharm. 在 ...

  4. 深度学习论文翻译解析(十二):Fast R-CNN

    论文标题:Fast R-CNN 论文作者:Ross Girshick 论文地址:https://www.cv-foundation.org/openaccess/content_iccv_2015/p ...

  5. Python深度学习案例1--电影评论分类(二分类问题)

    我觉得把课本上的案例先自己抄一遍,然后将书看一遍.最后再写一篇博客记录自己所学过程的感悟.虽然与课本有很多相似之处.但自己写一遍感悟会更深 电影评论分类(二分类问题) 本节使用的是IMDB数据集,使用 ...

  6. 深度学习练手项目——DNN识别手写数字

    该案例主要目的是为了熟悉Keras基本用法,以及了解DNN基本流程. 示例代码: import numpy as np import matplotlib.pyplot as plt from ker ...

  7. 吴裕雄--天生自然python Google深度学习框架:MNIST数字识别问题

    import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data INPUT_NODE = 784 ...

  8. HyperLPR车牌识别

    简介 本文基于HyperLPR进行修改,完整代码参考https://github.com/Liuyubao/PlateRecognition. HyperLPR是一个使用深度学习针对对中文车牌识别的实 ...

  9. 2020国防科大综述:3D点云深度学习—综述(点云形状识别部分)

    目录 摘要 1.引言: 2.背景 2.1 数据集 2.2评价指标 3.3D形状分类 3.1基于多视图的方法 3.2基于体素的方法 3.3基于点的方法 3.3.1 点对多层感知机方法 3.3.2基于卷积 ...

随机推荐

  1. c# try-finally有什么用

     finally 代码块中的代码是 try-catch 结构执行完后无论有无异常发生都会执行的.finally 代码块中的代码是 try-catch 结构执行完后无论有无异常发生都会执行的.final ...

  2. Object Detection︱RCNN、faster-RCNN框架的浅读与延伸内容笔记

    一.RCNN,fast-RCNN.faster-RCNN进化史 本节由CDA深度学习课堂,唐宇迪老师教课,非常感谢唐老师课程中的论文解读,很有帮助. . 1.Selective search 如何寻找 ...

  3. 用DriverStudio开发USB驱动程序

    很多写Windows Device Driver的开发人员基本上都是使用Windows DDK进行开发的.但是,现在也有不少人都开始借助一些辅助工具.笔者去年开始接触到DriverStudio,发现它 ...

  4. .Net4.0 任务(Task)

    任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks 命名空间下任务相关类一览: 类 ...

  5. ORA-00904:标识符无效

    1.错误描述 ORA-00904:"TTT"."RN":标识符无效 00904 . 00000 - "%s:invalid identifier&qu ...

  6. Python与RabbitMQ交互

    RabbitMQ 消息队列 成熟的中间件RabbitMQ.ZeroMQ.ActiveMQ等等 RabbitMQ使用erlang语言开发,使用RabbitMQ前要安装erlang语言 RabbitMQ允 ...

  7. Django学习-17-CSRF

    CSRF(跨站请求伪造)         用户请求获取数据时,加入一段加密字符串,只有服务器能反解.         XSS(跨站脚本攻击),JS脚本在网站中运行,如果获取到用户Cookie,可以利用 ...

  8. Django学习-14-分页功能实例

    首先创建一个制作page的工具类                     utils                         --page_make.py                    ...

  9. python做基本的图像处理

    PIL是python中的图像处理类库,为python提供了基本的图像处理和基本操作.而PIL中最重要的就是Image模块,下面给出具体的例子来理解此模块. 读取一幅图像 我们用Image模块中的ope ...

  10. 版本控制工具--svn和git的使用(三) -----git的使用(1)

    安装 git官网就有git各个系统的安装包,可以根据自己系统安装相应的安装包.window的git安装包 依据国内网速原因,将安装放到网盘里,链接: https://pan.baidu.com/s/1 ...