使用LeNet对于旋转数字进行识别:合并数字集合

Posted 卓晴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用LeNet对于旋转数字进行识别:合并数字集合相关的知识,希望对你有一定的参考价值。

简 介: 将所有机械旋转字符合成一个大的训练集合(3415个样本),使用其中80%作为训练样本集合,利用LeNet网络进行训练。最终在测试集合上获得95%的识别率。对于误差超过1的样本只要0.7%。

关键词 LeNet旋转数字

合并数字集合
文章目录
旋转机械数字
合并数字集合-灰度
训练LeNet网络
构建网络

 

§01 并数字集合


1.1 旋转机械数字

  在 2021年人工神经网络第四次作业-第四题:旋转的数字 对于一组采集自机械 电能表 显示表盘的数字图片进行实验。发现训练的LeNet网络的推广性不强。

1.1.1 训练数字集合

(1)20

数据集合参数:
个数:1000
尺寸:38,56
色彩:彩色

  在训练之前将所有的数字都修改成了灰度图。

``▲ 图1.1.1 训练所使用的1000个彩色数字集合>``

(2)11

数据集合参数:
个数:180
尺寸:39,56
色彩:黑白

▲ 图1.1.2 测试数据集合

1.1.2 训练结果

  如下是使用1000个字符集合对于180个数据进行识别的结果。在传统的LeNet的基础上增加了Dropout层,测试集合的识别结果大体为50 ~ 60%左右。

▲ 图1.1.1 训练结果

1.2 合并数字集合-灰度

  在 处理图像数据:拉伸、旋转、剪切等等 对于六个数字集合进行和合并。

  下面是合并后的数字集合。

▲ 图1.2.1 合并后的数字集合

  后面使用该集合对于LeNet进行训练,测试训练的精度。

1.2.1 合并成灰度数据集合

  在训练之前将该数据集合都变成灰度图片。

(1)合并代码

grayimg = [mean(img,axis=2).T[:,:,newaxis].T for img in imgall]
print(type(grayimg))
print(shape(grayimg))
<class 'list'>
(3415, 1, 45, 35)
合并集合数据:
个数:3415
色彩:灰度
结构:(3415,1,45,35)
种类:List,Item=array

(2)检查合并结果

PIC_ROW         = 3
PIC_COL         = 5
plt.figure(figsize=(10,9))
for j in range(PIC_ROW):
    for i in range(PIC_COL):
        id = i+j*PIC_COL
        plt.subplot(PIC_ROW, PIC_COL, id+1)

        img = grayimg[index[id]][0]
        plt.imshow(img, cmap=plt.cm.gray)
        plt.title(str(imglabel[index[id]]), fontsize=20, color='r')

▲ 图1.2.2 变成灰度集合的数据集

(3)存储数据集合

outdir = '/home/aistudio/work/rotatedigit/alldigit30_45'
outfile = 'alldigit_gray'
savez(os.path.join(outdir, outfile), imgdata=grayimg, imglabel=imglabel)

  将数据存储在:

/home/aistudio/work/rotatedigit/alldigit30_45/alldigit_gray.npz

 

§02 练LeNet网络


2.1 构建网络

2.1.1 加载数据

import sys,os,math,time
import matplotlib.pyplot as plt
from numpy import *

import paddle

 #------------------------------------------------------------

datafile = '/home/aistudio/work/rotatedigit/alldigit30_45/alldigit_gray.npz'
data = load(datafile)
print(data.files)

imgdata = data['imgdata'].tolist()
imglabel = data['imglabel'].tolist()
 #------------------------------------------------------------
index = list(range(len(imglabel)))
random.shuffle(index)

TRAIN_RATIO     = 0.8
train_number = int(len(imglabel)*TRAIN_RATIO)

traindata = [imgdata[id] for id in index[:train_number]]
trainlabel = [int(imglabel[id]) for id in index[:train_number]]
testdata = [imgdata[id] for id in index[train_number:]]
testlabel = [int(imglabel[id]) for id in index[train_number:]]

(1)显示数据

print(type(traindata), "\\n",  shape(traindata))
print(type(trainlabel), "\\n",  shape(trainlabel))
['imgdata', 'imglabel']
<class 'list'> 
 (2732, 1, 45, 35)
<class 'list'> 
 (2732,)
PIC_ROW         = 3
PIC_COL         = 5
plt.figure(figsize=(10,8))
for j in range(PIC_ROW):
    for i in range(PIC_COL):
        id = i+j*PIC_COL
        plt.subplot(PIC_ROW, PIC_COL, id+1)
        plt.axis('off')
        plt.imshow(traindata[id][0], cmap=plt.cm.gray)
        plt.title(str(trainlabel[id]), fontsize=12, color='blue')

▲ 图2.1.1 测试几种的数字

(2)构建训练加载函数

class Dataset(paddle.io.Dataset):
    def __init__(self, num_samples):
        super(Dataset, self).__init__()
        self.num_samples = num_samples

    def __getitem__(self, index):
        data = traindata[index]
        label = trainlabel[index]
        return paddle.to_tensor(data,dtype='float32'), paddle.to_tensor(label,dtype='int64')

    def __len__(self):
        return self.num_samples

_dataset = Dataset(len(trainlabel))
train_loader = paddle.io.DataLoader(_dataset, batch_size=100, shuffle=True)


##### <font  color=purple>&emsp;Ⅰ.测试加载函数</font>
```python
tdata = train_loader().next()

traind = tdata[0].numpy()
trainl = tdata[1].numpy()

 #------------------------------------------------------------

PIC_ROW         = 3
PIC_COL         = 5
plt.figure(figsize=(10,8))
for j in range(PIC_ROW):
    for i in range(PIC_COL):
        id = i+j*PIC_COL
        plt.subplot(PIC_ROW, PIC_COL, id+1)
        plt.axis('off')
        plt.imshow(traind[id][0], cmap=plt.cm.gray)
        plt.title(str(trainl[id]), fontsize=12, color='blue')

▲ 图2.1.2 训练加载函数所获得图片

2.1.2 构建LeNet

imgwidth = 35
imgheight = 45
inputchannel = 1
kernelsize   = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2

class lenet(paddle.nn.Layer):
    def __init__(self, ):
        super(lenet, self).__init__()
        self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
        self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
        self.mp1    = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
        self.mp2    = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
        self.L1     = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
        self.L2     = paddle.nn.Linear(in_features=120, out_features=86)
        self.L3     = paddle.nn.Linear(in_features=86, out_features=targetsize)

    def forward(self, x):
        x = self.conv1(x)
        x = paddle.nn.functional.relu(x)
        x = self.mp1(x)
        x = self.conv2(x)
        x = paddle.nn.functional.relu(x)
        x = self.mp2(x)
        x = paddle.flatten(x, start_axis=1, stop_axis=-1)
        x = self.L1(x)
        x = paddle.nn.functional.relu(x)
        x = self.L2(x)
        x = paddle.nn.functional.relu(x)
        x = self.L3(x)
        return x

model = lenet()

2.1.3 构建训练函数

imgwidth = 45
imgheight = 35
inputchannel = 1
kernelsize   = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2

class lenet(paddle.nn.Layer):
    def __init__(self, ):
        super(lenet, self).__init__()
        self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
        self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
        self.mp1    = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
        self.mp2    = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
        self.L1     = paddle.nn.Linear(in_features=ft

以上是关于使用LeNet对于旋转数字进行识别:合并数字集合的主要内容,如果未能解决你的问题,请参考以下文章

使用Keras训练Lenet网络来进行手写数字识别

电能表中的旋转木马

通过PyTorch构建的LeNet-5网络对手写数字进行训练和识别

深度学习从LeNet-5识别手写数字入门深度学习

深度学习面试题12:LeNet(手写数字识别)

AI常用框架和工具丨10. TensorFlow实现基于LeNet5的手写数字识别