使用LeNet对于旋转数字进行识别:合并数字集合
Posted 卓晴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用LeNet对于旋转数字进行识别:合并数字集合相关的知识,希望对你有一定的参考价值。
简 介: 将所有机械旋转字符合成一个大的训练集合(3415个样本),使用其中80%作为训练样本集合,利用LeNet网络进行训练。最终在测试集合上获得95%的识别率。对于误差超过1的样本只要0.7%。
关键词
: LeNet,旋转数字
§01 合并数字集合
1.1 旋转机械数字
在 2021年人工神经网络第四次作业-第四题:旋转的数字 对于一组采集自机械 电能表 显示表盘的数字图片进行实验。发现训练的LeNet网络的推广性不强。
1.1.1 训练数字集合
(1)20
-
数据集合参数:
-
个数
:1000
尺寸
:38,56
色彩
:彩色
在训练之前将所有的数字都修改成了灰度图。
(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> Ⅰ.测试加载函数</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对于旋转数字进行识别:合并数字集合的主要内容,如果未能解决你的问题,请参考以下文章