深度学习实战之手写签名识别(100%准确率语音播报)

幼敏悟过人,读书辄成诵。这篇文章主要讲述深度学习实战之手写签名识别(100%准确率语音播报)相关的知识,希望能为你提供帮助。

【深度学习实战之手写签名识别(100%准确率语音播报)】 手写签名在日常生活中随处可见,简单来说就是亲笔书写自己的名字,在纸质文档上使用手写签名主要用以确定签字者的身份,并表示签字者同意所签署文档中规定的内容,对文档的真实性负责,且具有法律效力。由此看见手写签名的重要性。在现实的生活中不乏有不法分子模仿其他人的字体,进而模仿他人的签名获得不发的利益。尽管会有鉴别字体的工作,但在鉴别时不仅不准确,而且还十分的消耗人力以及财力。为了解决这一客观显示存在的问题,笔者结合着人工智能的思想和并使用计算机视觉技术对手写签名进行训练,得到了高达100%的训练准确率。并将训练模型进行优化后运用实现了一套手写签名识别系统。
1.开发环境笔者的开发环境如下,大家可以参考进行配置
  • python3.6或python3.7
  • pytorch1.0.1
  • torchvision 0.2.2.post3
  • visom
  • ubuntu16.04和windows10
2. 准备阶段在完成了上述的环境搭建后,即可进入到准备阶段了。这里准备的有数据集的准备、以及相关代码的主备。
  • 数据集的准备
笔者这里的数据集是自己准备的,收集了六个人的手写签名,约4500张签名图片
深度学习实战之手写签名识别(100%准确率语音播报)

文章图片

深度学习实战之手写签名识别(100%准确率语音播报)

文章图片



  • 数据集的划分
笔者这里将数据集进行六分类的划分,每一类约有750张图片
数据集划分为训练数据、验证数据、测试数据
其中训练数据、验证数据、测试数据的具体划分如下图所示
深度学习实战之手写签名识别(100%准确率语音播报)

文章图片



  • 载入数据
在上述的步骤中已经准备好了相应的数据集,同时也划分好了训练数据、验证数据、测试数据的部分。在完成了理论的设计后,该怎么使用代码对数据进行划分呢,代码如下所示

class Data(Dataset):
def __init__(self,root,resize,mode):
super(Data,self).__init__()
# 保存参数
self.root=root
self.resize=resize
# 给每一个类做映射
self.name2label=# "daj":0 ,"hjj":1……
for name in sorted(os.listdir(os.path.join(root))):
# 过滤掉文件夹
if not os.path.isdir(os.path.join(root,name)):
continue
# 保存在表中; 将最长的映射作为最新的元素的label的值
self.name2label[name]=len(self.name2label.keys())
# print(self.name2label)
# 加载文件
self.images,self.labels=self.load_csv(images.csv)
# 裁剪数据
if mode==train:
self.images=self.images[:int(0.6*len(self.images))]# 将数据集的60%设置为训练数据集合
self.labels=self.labels[:int(0.6*len(self.labels))]# label的60%分配给训练数据集合
elif mode==val:
self.images = self.images[int(0.6 * len(self.images)):int(0.8 * len(self.images))]# 从60%-80%的地方
self.labels = self.labels[int(0.6 * len(self.labels)):int(0.8 * len(self.labels))]
else:
self.images = self.images[int(0.8 * len(self.images)):]# 从80%的地方到最末尾
self.labels = self.labels[int(0.8 * len(self.labels)):]
# image+label 的路径

在使用上述的代码后即可将已有的数据集的60%划分为训练数据、20%划分为验证数据、20%划分为测试数据。
# 3. 训练阶段
在完成了上述的操作后,即可进入到训练阶段。这里笔者使用的是比较经典的神经网络结构--ResNet.
由何凯明团队所提出来的。其深度残差网络(Deep Residual Network)在2015年的ImageNet上取得冠军。具体网络的特点,读者可自行Google了解,这里笔者就不再赘述。

  • 搭建ResNet网络结构
搭建的网络结构代码如下:

class ResBlk(nn.Module):

def __init__(self, ch_in, ch_out, stride=1):
super(ResBlk, self).__init__()

self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=stride, padding=1)
self.bn1 = nn.BatchNorm2d(ch_out)
self.conv2 = nn.Conv2d(ch_out, ch_out, kernel_size=3, stride=1, padding=1)
self.bn2 = nn.BatchNorm2d(ch_out)

self.extra = nn.Sequential()
if ch_out != ch_in:
# [b, ch_in, h, w] => [b, ch_out, h, w]
self.extra = nn.Sequential(
nn.Conv2d(ch_in, ch_out, kernel_size=1, stride=stride),
nn.BatchNorm2d(ch_out)
)


def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
# short cut.
# extra module: [b, ch_in, h, w] => [b, ch_out, h, w]
# element-wise add:
out = self.extra(x) + out
out = F.relu(out)

return out

class ResNet18(nn.Module):

def __init__(self, num_class):
super(ResNet18, self).__init__()

self.conv1 = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, stride=3, padding=0),
nn.BatchNorm2d(16)
)
# followed 4 blocks

    推荐阅读