Pytorch中的CTC loss
pytorch中已经内置了ctc loss,可以非常方便的进行使用。主要就是两个API,一个是创建ctc loss;一个是计算ctc loss。
创建ctc loss的api
ctc_loss = nn.CTCLoss(blank=len(CHARS)-1, reduction='mean')
# blank:表示空白符blank的序号。刚才我们在举例的时候说过,CTC增加了一个blank的符号。此处传入的就是空白符的序号。例如我们的预测文本中如果只包含26个英文字母,其序号分别用0~25表示,那么blank可以定义为26。
计算ctc loss
loss = ctc_loss(log_probs, targets, input_lengths, target_lengths)
# log_probs:网络的输出,shape为:(T, N, C),T就是输出的序列长度,N对应的是batch size,C对应的
# 是每个字符有多少中可能。例如刚才的预测26个字母+1个blank符号,那么C就是27
# targets:标签值。shape为:(X),指的是N个数据的标签合在一起(一维度)
# input_lengths:每个图片的预测长度(实际上如果就是[T,T,T,T...]共N个)
# target_lengths:每个图片的标签长度,根据实际情况指定ctc loss举例假设
使用ctc loss预测车牌号
每个字符有 31(省份) + 36(字母和数字) + 1(blank空白符) = 68种可能,如下所示:
dict={0: '京',
1: '沪',
2: '津',
3: '渝',
......
31: '0',
32: '1',
33: '2',
34: '3',
35: '4',
......
41: 'A',
42: 'B',
43: 'C',
......
67: '-'];
车牌的长度有7个字符(蓝牌)和8个字符(绿牌),CTC建议的输出长度为2max_len + 1, 为了考虑到每两个字符之间都有一个blank的情况。即输出长度为28+1 = 17个。
batch size 假设为2,那么最终网络的输出log_probs的shape为 T * N * C = 17 * 2 * 68;
假设batch size为2的两张图片的标签分别为“京A88888”以及“沪AD12345”,转换成字符对应的序号就是:[0,41,38,36,48,38,38] 和 [1,41,44,32,33,34,35,36]。那么最终的targets就是:[0,41,38,36,48,38,38,1,41,44,32,33,34,35,36]。
input_lengths 为[17, 17],
target_lengths为[7,8]
修改车牌识别网络有了CTC loss之后,我们就不需要像以前那样对蓝牌和绿牌进行分开训练了,可以放在一个网络里面进行训练。如下图所示为网络的最终结构。网络最终输出的是17*68维度的预测矩阵。
预测矩阵与原车牌的对应关系如下图所示
视频误检
虽然上述图片测试效果比较好。但是使用真正的视频测试,仍然会出现误检的情况。即一个车牌由于角度的不同被识别成不同的车牌号(但是这些车牌号都比较接近)。如下图所示,视频中出现了三辆车,但是却识别出了多个车牌。
分析上面的误检,首先,省份比较容易预测错误。这是由于CCPD数据集主要从安徽的停车场中收集的,因此车牌中省份是“皖”的数据量特别大,而其他省份的就会少很多。因此如果不做一些数据增强或者训练策略,很容易导致车牌对“皖”的预测偏好。不过这个对于我们用车牌来识别车辆实体来说,问题不大,我们可以直接忽略省份位。因为在同时一时间,同一地点,出现两个省份不同而其他位全相同的车的概率几乎为0。然后处理一下多个相似车牌的问题,实际上可以通过计算两个车牌之间的相似性来排除误检。还是基于之前那个假设,同一地点,同一时间出现AT95S5与AT9SS5的概率是非常小的,因此当判断出两个车牌的相似性很高时,我们可以认为一个车牌。
总结一下处理流程,如下图所示:
转载
作者:DL-Practise
链接:https://www.zhihu.com/question/48418510/answer/2435692399
著作权归作者所有。