python实现手写数字识别(小白入门)

合集下载

手写数字识别系统的设计与实现

手写数字识别系统的设计与实现

手写数字识别系统的设计与实现随着数字化时代的到来,智能化已经成为了趋势,人工智能的发展需要更精准有效的数据判别处理。

实现手写数字识别系统,可以广泛应用于智能交互、机器人、OCR等领域。

本文将描述手写数字识别系统的设计和实现过程。

一、系统设计手写数字识别系统输入手写数字图像,输出代表数字的数值。

总体设计思路如下:1.数据采集与存储用户输入手写数字图像后,通过归一化等方法去除噪点,存储为图片格式,可以使用20x20像素,黑白二值化的PNG格式存储。

2.特征提取与向量化将图片转化为向量,提取手写数字特征。

常用的特征提取方法是SIFT描述符提取和HOG特征提取,本文采用HOG特征提取方法。

基本步骤如下:a. 图像预处理:将彩色图片转化为灰度图片b. 局部块划分:将图片分为若干块c. 计算梯度直方图:对每一个块进行梯度直方图的计算d. 归一化:将梯度直方图归一化,得到HOG向量3.分类模型及算法采用深度学习神经网络模型进行分类,训练集采用MNIST公开数据集,由于输入的都是28*28的黑白图片,最后需要对数据进行调整,不符合识别输入数据的标准,将输入大小调整为20*20。

采用神经网络库tensorflow,设计softmax回归模型,定义交叉熵损失函数并使用梯度下降法或Adam优化算法最小化损失。

4.模型评估和调优使用测试集对模型进行评估,计算准确率、精度、召回率、F1值等,并采用正则化、dropout等技术对模型进行优化和调整。

5.系统集成与优化将OCR识别模型和手写数字识别系统进行整合,并加入人机交互的界面设计,实现常规数字识别等操作。

二、系统实现整套系统使用python语言实现,通过tensorflow实现深度神经网络模型的训练和预测。

主要步骤如下:1.数据采集与存储:从kaggle网站上下载手写数字数据集,并使用python pandas库对数据集进行处理和存储,确保数据安全、方便、快速可靠的存储和使用。

python课程设计手写数字识别

python课程设计手写数字识别

python课程设计手写数字识别一、教学目标本课程的目标是使学生掌握Python编程语言的基本知识,学会手写数字识别的原理和实现方法。

通过本课程的学习,学生将能够:1.理解Python编程语言的基本语法和数据结构;2.掌握机器学习的基本概念和常用算法;3.学会使用Python库实现手写数字识别模型;4.能够独立完成手写数字识别项目的开发和优化。

二、教学内容本课程的教学内容主要包括以下几个部分:1.Python编程基础:介绍Python语言的基本语法、数据类型、控制结构、函数、模块等基本知识;2.机器学习理论:讲解机器学习的基本概念、常用算法和模型,如线性回归、支持向量机、神经网络等;3.手写数字识别:介绍手写数字识别的原理和常用算法,如感知机、支持向量机、神经网络等;4.实践项目:通过实际操作,让学生学会使用Python库实现手写数字识别模型,并进行优化和调试。

三、教学方法为了提高学生的学习兴趣和主动性,本课程将采用多种教学方法相结合的方式进行教学:1.讲授法:讲解Python编程基础和机器学习理论;2.案例分析法:分析实际案例,让学生了解手写数字识别的应用场景;3.实验法:引导学生动手实践,实现手写数字识别模型;4.讨论法:学生进行小组讨论,分享学习心得和经验,互相促进。

四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将提供以下教学资源:1.教材:选用国内权威的Python编程和机器学习教材;2.参考书:推荐学生阅读相关的国内外经典著作;3.多媒体资料:提供在线视频教程、课件、实验代码等资源;4.实验设备:为学生提供必要的实验设备和软件环境。

五、教学评估为了全面、客观、公正地评估学生的学习成果,本课程将采用以下评估方式:1.平时表现:通过课堂参与、提问、讨论等方式评估学生的学习态度和理解程度;2.作业:布置相关的编程练习和实验报告,评估学生对知识点的掌握和实际操作能力;3.考试:安排期末考试,测试学生对课程知识的全面理解和应用能力。

Python利用逻辑回归模型解决MNIST手写数字识别问题详解

Python利用逻辑回归模型解决MNIST手写数字识别问题详解

Python利⽤逻辑回归模型解决MNIST⼿写数字识别问题详解本⽂实例讲述了Python利⽤逻辑回归模型解决MNIST⼿写数字识别问题。

分享给⼤家供⼤家参考,具体如下:1、MNIST⼿写识别问题MNIST⼿写数字识别问题:输⼊⿊⽩的⼿写阿拉伯数字,通过机器学习判断输⼊的是⼏。

可以通过TensorFLow下载MNIST⼿写数据集,通过import引⼊MNIST数据集并进⾏读取,会⾃动从⽹上下载所需⽂件。

%matplotlib inlineimport tensorflow as tfimport tensorflow.examples.tutorials.mnist.input_data as input_datamnist=input_data.read_data_sets('MNIST_data/',one_hot=True)import matplotlib.pyplot as pltdef plot_image(image): #图⽚显⽰函数plt.imshow(image.reshape(28,28),cmap='binary')plt.show()print("训练集数量:",mnist.train.num_examples,"特征值组成:",mnist.train.images.shape,"标签组成:",bels.shape)batch_images,batch_labels=mnist.train.next_batch(batch_size=10) #批量读取数据print(batch_images.shape,batch_labels.shape)print('标签值:',np.argmax(bels[1000]),end=' ') #np.argmax()得到实际值print('独热编码表⽰:',bels[1000])plot_image(mnist.train.images[1000]) #显⽰数据集中第1000张图⽚输出训练集的数量有55000个,并打印特征值的shape为(55000,784),其中784代表每张图⽚由28*28个像素点组成,由于是⿊⽩图⽚,每个像素点只有⿊⽩单通道,即通过784个数可以描述⼀张图⽚的特征值。

python神经网络编程之手写数字识别

python神经网络编程之手写数字识别

python神经⽹络编程之⼿写数字识别⽬录写在之前⼀、代码框架⼆、准备⼯作三、框架的开始四、训练模型构建五、⼿写数字的识别六、源码七、思考写在之前⾸先是写在之前的⼀些建议:⾸先是关于这本书,我真的认为他是将神经⽹络⾥⾮常棒的⼀本书,但你也需要注意,如果你真的想⾃⼰动⼿去实现,那么你⼀定需要有⼀定的python基础,并且还需要有⼀些python数据科学处理能⼒然后希望⼤家在看这边博客的时候对于神经⽹络已经有⼀些了解了,知道什么是输⼊层,什么是输出层,并且明⽩他们的⼀些理论,在这篇博客中我们仅仅是展开⼀下代码;然后介绍⼀下本篇博客的环境等:语⾔:Python3.8.5环境:jupyter库⽂件: numpy | matplotlib | scipy⼀、代码框架我们即将设计⼀个神经⽹络对象,它可以帮我们去做数据的训练,以及数据的预测,所以我们将具有以下的三个⽅法:⾸先我们需要初始化这个函数,我们希望这个神经⽹络仅有三层,因为再多也不过是在隐藏层去做⽂章,所以先做⼀个简单的。

那么我们需要知道我们输⼊层、隐藏层和输出层的节点个数;训练函数,我们需要去做训练,得到我们需要的权重。

通过我们已有的权重,将给定的输⼊去做输出。

⼆、准备⼯作现在我们需要准备⼀下:1.将我们需要的库导⼊import numpy as npimport scipy.special as speimport matplotlib.pyplot as plt2.构建⼀个类class neuralnetwork:# 我们需要去初始化⼀个神经⽹络def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):passdef train(self, inputs_list, targets_list):passdef query(self, inputs_list):pass3.我们的主函数input_nodes = 784 # 输⼊层的节点数hidden_nodes = 88 # 隐藏层的节点数output_nodes = 10 # 输出层的节点数learn_rate = 0.05 # 学习率n = neuralnetwork(input_nodes, hidden_nodes, output_nodes, learn_rate)4.导⼊⽂件data_file = open("E:\sklearn_data\神经⽹络数字识别\mnist_train.csv", 'r')data_list = data_file.readlines()data_file.close()file2 = open("E:\sklearn_data\神经⽹络数字识别\mnist_test.csv")answer_data = file2.readlines()file2.close()这⾥需要介绍以下这个数据集,训练集在这⾥,测试集在这⾥三、框架的开始def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):self.inodes = inputnodes # 输⼊层节点设定self.hnodes = hiddennodes # 影藏层节点设定self.onodes = outputnodes # 输出层节点设定self.lr = learningrate # 学习率设定,这⾥可以改进的self.wih = (np.random.normal(0.0, pow(self.hnodes, -0.5),(self.hnodes, self.inodes))) # 这⾥是输⼊层与隐藏层之间的连接self.who = (np.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes, self.hnodes))) # 这⾥是隐藏层与输出层之间的连接self.activation_function = lambda x: spe.expit(x) # 返回sigmoid函数Δw j,k =α∗E k ∗ sigmoid (O k )∗(1−sigmoid(O k ))⋅O j ⊤def query(self, inputs_list):inputs = np.array(inputs_list, ndmin=2).T # 输⼊进来的⼆维图像数据hidden_inputs = np.dot(self.wih, inputs) # 隐藏层计算,说⽩了就是线性代数中的矩阵的点积hidden_outputs = self.activation_function(hidden_inputs) # 将隐藏层的输出是经过sigmoid函数处理final_inputs = np.dot(self.who, hidden_outputs) # 原理同hidden_inputsfinal_outputs = self.activation_function(final_inputs) # 原理同hidden_outputsreturn final_outputs # 最终的输出结果就是我们预测的数据这⾥我们对预测这⼀部分做⼀个简单的解释:我们之前的定义输出的节点是10个,对应的是⼗个数字。

PyTorch基础——使用卷积神经网络识别手写数字

PyTorch基础——使用卷积神经网络识别手写数字

PyTorch基础——使⽤卷积神经⽹络识别⼿写数字⼀、介绍实验内容内容包括⽤ PyTorch 来实现⼀个卷积神经⽹络,从⽽实现⼿写数字识别任务。

除此之外,还对卷积神经⽹络的卷积核、特征图等进⾏了分析,引出了过滤器的概念,并简单⽰了卷积神经⽹络的⼯作原理。

知识点使⽤ PyTorch 数据集三件套的⽅法卷积神经⽹络的搭建与训练可视化卷积核、特征图的⽅法⼆、数据准备引⼊相关包import torchimport torch.nn as nnfrom torch.autograd import Variableimport torch.optim as optimimport torch.nn.functional as Fimport torchvision.datasets as dsetsimport torchvision.transforms as transformsimport matplotlib.pyplot as pltimport numpy as np%matplotlib inline定义超参数# 定义超参数image_size = 28 #图像的总尺⼨28*28num_classes = 10 #标签的种类数num_epochs = 20 #训练的总循环周期batch_size = 64 #⼀个撮(批次)的⼤⼩,64张图⽚使⽤ PyTorch 数据加载三套件PyTorch ⾃带的数据加载器,包括dataset,sampler,以及data loader这三个对象组成的套件。

为什么要使⽤ PyTorch ⾃带的数据加载器?当数据集很⼩,格式⽐较规则的时候,数据加载三套件的优势并不明显。

但是当数据格式⽐较特殊,以及数据规模很⼤(内存⽆法同时加载所有数据)的时候,三套件的威⼒就会显现出来了。

特别是,当需要⽤不同的处理器来并⾏加载数据的时候,PyTorch 数据加载器还可以⾃动进⾏数据的分布式加载。

详解PyTorch手写数字识别(MNIST数据集)

详解PyTorch手写数字识别(MNIST数据集)

详解PyTorch⼿写数字识别(MNIST数据集)MNIST ⼿写数字识别是⼀个⽐较简单的⼊门项⽬,相当于深度学习中的 Hello World,可以让我们快速了解构建神经⽹络的⼤致过程。

虽然⽹上的案例⽐较多,但还是要⾃⼰实现⼀遍。

代码采⽤ PyTorch 1.0 编写并运⾏。

导⼊相关库import torchimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optimfrom torchvision import datasets, transformsimport torchvisionfrom torch.autograd import Variablefrom torch.utils.data import DataLoaderimport cv2torchvision ⽤于下载并导⼊数据集cv2 ⽤于展⽰数据的图像获取训练集和测试集# 下载训练集train_dataset = datasets.MNIST(root='./num/',train=True,transform=transforms.ToTensor(),download=True)# 下载测试集test_dataset = datasets.MNIST(root='./num/',train=False,transform=transforms.ToTensor(),download=True)root ⽤于指定数据集在下载之后的存放路径transform ⽤于指定导⼊数据集需要对数据进⾏那种变化操作train是指定在数据集下载完成后需要载⼊的那部分数据,设置为 True 则说明载⼊的是该数据集的训练集部分,设置为 False 则说明载⼊的是该数据集的测试集部分download 为 True 表⽰数据集需要程序⾃动帮你下载这样设置并运⾏后,就会在指定路径中下载 MNIST 数据集,之后就可以使⽤了。

超详细PyTorch实现手写数字识别器的示例代码

超详细PyTorch实现⼿写数字识别器的⽰例代码前⾔深度学习中有很多玩具数据,mnist就是其中⼀个,⼀个⼈能否⼊门深度学习往往就是以能否玩转mnist数据来判断的,在前⾯很多基础介绍后我们就可以来实现⼀个简单的⼿写数字识别的⽹络了数据的处理我们使⽤pytorch⾃带的包进⾏数据的预处理import torchimport torchvisionimport torchvision.transforms as transformsimport numpy as npimport matplotlib.pyplot as plttransform = pose([transforms.ToTensor(),transforms.Normalize((0.5), (0.5))])trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True,num_workers=2)注释:transforms.Normalize⽤于数据的标准化,具体实现mean:均值总和后除个数std:⽅差每个元素减去均值再平⽅再除个数norm_data = (tensor - mean) / std这⾥就直接将图⽚标准化到了-1到1的范围,标准化的原因就是因为如果某个数在数据中很⼤很⼤,就导致其权重较⼤,从⽽影响到其他数据,⽽本⾝我们的数据都是平等的,所以标准化后将数据分布到-1到1的范围,使得所有数据都不会有太⼤的权重导致⽹络出现巨⼤的波动trainloader现在是⼀个可迭代的对象,那么我们可以使⽤for循环进⾏遍历了,由于是使⽤yield返回的数据,为了节约内存观察⼀下数据def imshow(img):img = img / 2 + 0.5 # unnormalizenpimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()# torchvision.utils.make_grid 将图⽚进⾏拼接imshow(torchvision.utils.make_grid(iter(trainloader).next()[0]))构建⽹络from torch import nnimport torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(in_channels=1, out_channels=28, kernel_size=5) # 14self.pool = nn.MaxPool2d(kernel_size=2, stride=2) # ⽆参数学习因此⽆需设置两个self.conv2 = nn.Conv2d(in_channels=28, out_channels=28*2, kernel_size=5) # 7self.fc1 = nn.Linear(in_features=28*2*4*4, out_features=1024)self.fc2 = nn.Linear(in_features=1024, out_features=10)def forward(self, inputs):x = self.pool(F.relu(self.conv1(inputs)))x = self.pool(F.relu(self.conv2(x)))x = x.view(inputs.size()[0],-1)x = F.relu(self.fc1(x))return self.fc2(x)下⾯是卷积的动态演⽰in_channels:为输⼊通道数彩⾊图⽚有3个通道⿊⽩有1个通道out_channels:输出通道数kernel_size:卷积核的⼤⼩stride:卷积的步长padding:外边距⼤⼩输出的size计算公式h = (h - kernel_size + 2*padding)/stride + 1w = (w - kernel_size + 2*padding)/stride + 1 MaxPool2d:是没有参数进⾏运算的实例化⽹络优化器,并且使⽤GPU进⾏训练net = Net()opt = torch.optim.Adam(params=net.parameters(), lr=0.001)device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")net.to(device)Net((conv1): Conv2d(1, 28, kernel_size=(5, 5), stride=(1, 1))(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(conv2): Conv2d(28, 56, kernel_size=(5, 5), stride=(1, 1))(fc1): Linear(in_features=896, out_features=1024, bias=True)(fc2): Linear(in_features=1024, out_features=10, bias=True))训练主要代码for epoch in range(50):for images, labels in trainloader:images = images.to(device)labels = labels.to(device)pre_label = net(images)loss = F.cross_entropy(input=pre_label, target=labels).mean()pre_label = torch.argmax(pre_label, dim=1)acc = (pre_label==labels).sum()/torch.tensor(labels.size()[0], dtype=torch.float32)net.zero_grad()loss.backward()opt.step()print(acc.detach().cpu().numpy(), loss.detach().cpu().numpy())F.cross_entropy交叉熵函数源码中已经帮助我们实现了softmax因此不需要⾃⼰进⾏softmax操作了torch.argmax计算最⼤数所在索引值acc = (pre_label==labels).sum()/torch.tensor(labels.size()[0], dtype=torch.float32)# pre_label==labels 相同维度进⾏⽐较相同返回True不同的返回False,True为1 False为0, 即可获取到相等的个数,再除总个数,就得到了Accuracy准确度了预测testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)testloader = torch.utils.data.DataLoader(testset, batch_size=128, shuffle=True,num_workers=2)images, labels = iter(testloader).next()images = images.to(device)labels = labels.to(device)with torch.no_grad():pre_label = net(images)pre_label = torch.argmax(pre_label, dim=1)acc = (pre_label==labels).sum()/torch.tensor(labels.size()[0], dtype=torch.float32)print(acc)总结本节我们了解了标准化数据·、卷积的原理、简答的构建了⼀个⽹络,并让它去识别⼿写体,也是对前⾯章节的总汇了到此这篇关于超详细PyTorch实现⼿写数字识别器的⽰例代码的⽂章就介绍到这了,更多相关PyTorch ⼿写数字识别器内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

Python遇见机器学习----TensorFlow搭建神经网络实现手写识别

Python遇见机器学习----TensorFlow搭建神经网络实现手写识别总体概览:利用神经网络来进行手写识别就是将输入手写的数据经过一系列分析最终生成判决结果的过程。

使用的神经网络模型如下:输入数据是像素为28 × 28 = 784的黑白图片(共55000张)使用10位one-hot编码:0 -> 10000000001 -> 010*******2 -> 00100000003 -> 00010000004 -> 00001000005 -> 00000100006 -> 00000010007 -> 00000001008 -> 00000000109 -> 0000000001只需识别神经网络输出结果向量中对应第几列的值最大,对应的索引即为识别结果。

卷积层yers.conv2d:yers.conv2d(inputs,filters,kernel_size,strides=(1, 1),padding='valid',activation=None,)•inputs: 张量输入•filters: 整数,输出空间的维数(即卷积中滤波器的个数)•kernel_size: 一个整数或两个整数的元组/列表,指定二维卷积窗口的高度和宽度。

可以是单个整数,以便为所有空间维度指定相同的值•strides: 一个整数或两个整数的元组/列表,指定卷积在高度和宽度上的步长。

可以是单个整数,以便为所有空间维度指定相同的值。

指定任何stride值!= 1与指定任何dilation_rate值!= 1不兼容•padding: "valid" 或 "same" (不区分大小写)•activation: 激活函数。

将其设置为None为保持线性激活在这个例子中第一层卷积层定义如下:# 第1层卷积conv1 = yers.conv2d(inputs=input_x_images, # 形状28*28*1filters=32, # 输出深度为32kernel_size=[5, 5], # 滤波器在二维的大小strides=1, # 采样步长padding='same', # 表示输出大小不变,因此需要在外围补零两圈activation=tf.nn.relu) # 输出形状变为[28, 28, 32]池化层(亚采样)yers.max_pooling2d:yers.max_pooling2d(inputs,pool_size,strides,)•inputs: 要池化的张量。

Python与机器学习-- 手写数字识别应用

mlp = MLPClassifier(solver='sgd', activation='relu',alpha=1e-4,hidden_layer_sizes=(10,10), random_state=1,max_iter=500,verbose=10,learning_rate_init =.001)
Car 情报局
方案二:使用神经网络实现数字手写体识别 Car 情报局
• 模型评估报告
precision
recall f1-score
support
0 0.94 0.97 0.96 980
1 0.97 0.99 0.98 1135
2 0.93 0.92 0.93 1032
3 0.92 0.92 0.92 1010
手写数字识别应用
知识回顾:机器学习的方法
Car 情报局
机器学习算法
监督学习
无监督学习
分类 预测
回归 分析
聚类 分析
关联 规则
半监督学习
强化学习
时间差 Q-learning 学习
主要教学内容
模式识别应用 文字识别 机器学习方法
项目:手写数字识别 数据准备 数据可视化 模型训练 模型分析与识别结果的可视化 SVM 神经网络
方案一:使用SVM实现数字手写体识别
• 模型评估
print('预测开始....') y_pred = model_svc.predict(x_test) print('10000个测试数据的测试精确率:') print(model_svc.score(x_test,y_test))
10000个测试数据的测试精确率: 0.9099

Python利用三层神经网络实现手写数字分类详解

Python利⽤三层神经⽹络实现⼿写数字分类详解⽬录前⾔⼀、神经⽹络组成⼆、代码实现1.引⼊库2.导⼊数据集3.全连接层4.ReLU激活函数层5.Softmax损失层6.⽹络训练与推断模块三、代码debug四、结果展⽰补充前⾔本⽂做的是基于三层神经⽹络实现⼿写数字分类,神经⽹络设计是设计复杂深度学习算法应⽤的基础,本⽂将介绍如何设计⼀个三层神经⽹络模型来实现⼿写数字分类。

⾸先介绍如何利⽤⾼级编程语⾔Python搭建神经⽹络训练和推断框架来实现⼿写数字分类的训练和使⽤。

⼀、神经⽹络组成⼀个完整的神经⽹络通常由多个基本的⽹络层堆叠⽽成。

本实验中的三层全连接神经⽹络由三个全连接层构成,在每两个全连接层之间会插⼊ReLU激活函数引⼊⾮线性变换,最后使⽤Softmax层计算交叉嫡损失,如下图所⽰。

因此本实验中使⽤的基本单元包括全连接层、ReLU激活函数、Softmax损失函数。

⼆、代码实现1.引⼊库import numpy as npimport structimport os2.导⼊数据集MNIST_DIR = "mnist_data"TRAIN_DATA = "train-images-idx3-ubyte"TRAIN_LABEL = "train-labels-idx1-ubyte"TEST_DATA = "t10k-images-idx3-ubyte"TEST_LABEL = "t10k-labels-idx1-ubyte"数据集下载后⼀定记得解压3.全连接层class FullyConnectedLayer(object):def __init__(self, num_input, num_output): # 全连接层初始化self.num_input = num_inputself.num_output = num_outputdef init_param(self, std=0.01): # 参数初始化self.weight = np.random.normal(loc=0, scale=std, size=(self.num_input, self.num_output))self.bias = np.zeros([1, self.num_output])def forward(self, input): # 前向传播计算self.input = inputself.output = np.dot(self.input,self.weight)+self.biasreturn self.outputdef backward(self, top_diff): # 反向传播的计算self.d_weight =np.dot(self.input.T,top_diff)self.d_bias = top_diff #bottom_diff = np.dot(top_diff,self.weight.T)return bottom_diffdef update_param(self, lr): # 参数更新self.weight = self.weight - lr * self.d_weightself.bias = self.bias - lr * self.d_biasdef load_param(self, weight, bias): # 参数加载assert self.weight.shape == weight.shapeassert self.bias.shape == bias.shapeself.weight = weightself.bias = biasdef save_param(self): # 参数保存return self.weight, self.bias4.ReLU激活函数层class ReLULayer(object):def forward(self, input): # 前向传播的计算self.input = inputoutput = np.maximum(self.input,0)return outputdef backward(self, top_diff): # 反向传播的计算b = self.inputb[b>0] =1b[b<0] = 0bottom_diff = np.multiply(b,top_diff)return bottom_diff5.Softmax损失层class SoftmaxLossLayer(object):def forward(self, input): # 前向传播的计算input_max = np.max(input, axis=1, keepdims=True)input_exp = np.exp(input- input_max)#(64,10)partsum = np.sum(input_exp,axis=1)sum = np.tile(partsum,(10,1))self.prob = input_exp / sum.Treturn self.probdef get_loss(self, label): # 计算损失self.batch_size = self.prob.shape[0]bel_onehot = np.zeros_like(self.prob)bel_onehot[np.arange(self.batch_size), label] = 1.0loss = -np.sum(bel_onehot*np.log(self.prob)) / self.batch_sizereturn lossdef backward(self): # 反向传播的计算bottom_diff = (self.prob - bel_onehot)/self.batch_sizereturn bottom_diff6.⽹络训练与推断模块class MNIST_MLP(object):def __init__(self, batch_size=64, input_size=784, hidden1=32, hidden2=16, out_classes=10, lr=0.01, max_epoch=1,print_iter=100): self.batch_size = batch_sizeself.input_size = input_sizeself.hidden1 = hidden1self.hidden2 = hidden2self.out_classes = out_classesself.lr = lrself.max_epoch = max_epochself.print_iter = print_iterdef shuffle_data(self):np.random.shuffle(self.train_data)def build_model(self): # 建⽴⽹络结构self.fc1 = FullyConnectedLayer(self.input_size, self.hidden1)self.relu1 = ReLULayer()self.fc2 = FullyConnectedLayer(self.hidden1, self.hidden2)self.relu2 = ReLULayer()self.fc3 = FullyConnectedLayer(self.hidden2, self.out_classes)self.softmax = SoftmaxLossLayer()self.update_layer_list = [self.fc1, self.fc2, self.fc3]def init_model(self):for layer in self.update_layer_list:layer.init_param()def forward(self, input): # 神经⽹络的前向传播h1 = self.fc1.forward(input)h1 = self.relu1.forward(h1)h2 = self.fc2.forward(h1)h2 = self.relu2.forward(h2)h3 = self.fc3.forward(h2)self.prob = self.softmax.forward(h3)return self.probdef backward(self): # 神经⽹络的反向传播dloss = self.softmax.backward()dh2 = self.fc3.backward(dloss)dh2 = self.relu2.backward(dh2)dh1 = self.fc2.backward(dh2)dh1 = self.relu1.backward(dh1)dh1 = self.fc1.backward(dh1)def update(self, lr):for layer in self.update_layer_list:layer.update_param(lr)def load_mnist(self, file_dir, is_images='True'):bin_file = open(file_dir, 'rb')bin_data = bin_file.read()bin_file.close()if is_images:fmt_header = '>iiii'magic, num_images, num_rows, num_cols = struct.unpack_from(fmt_header, bin_data, 0)else:fmt_header = '>ii'magic, num_images = struct.unpack_from(fmt_header, bin_data, 0)num_rows, num_cols = 1, 1data_size = num_images * num_rows * num_colsmat_data = struct.unpack_from('>' + str(data_size) + 'B', bin_data, struct.calcsize(fmt_header))mat_data = np.reshape(mat_data, [num_images, num_rows * num_cols])return mat_datadef load_data(self):train_images = self.load_mnist(os.path.join(MNIST_DIR, TRAIN_DATA), True)train_labels = self.load_mnist(os.path.join(MNIST_DIR, TRAIN_LABEL), False)test_images = self.load_mnist(os.path.join(MNIST_DIR, TEST_DATA), True)test_labels = self.load_mnist(os.path.join(MNIST_DIR, TEST_LABEL), False)self.train_data = np.append(train_images, train_labels, axis=1)self.test_data = np.append(test_images, test_labels, axis=1)def load_model(self, param_dir):params = np.load(param_dir).item()self.fc1.load_param(params['w1'], params['b1'])self.fc2.load_param(params['w2'], params['b2'])self.fc3.load_param(params['w3'], params['b3'])def save_model(self, param_dir):params = {}params['w1'], params['b1'] = self.fc1.save_param()params['w2'], params['b2'] = self.fc2.save_param()params['w3'], params['b3'] = self.fc3.save_param()np.save(param_dir, params)def train(self):max_batch_1 = self.train_data.shape[0] / self.batch_sizemax_batch = int(max_batch_1)for idx_epoch in range(self.max_epoch):mlp.shuffle_data()for idx_batch in range(max_batch):batch_images = self.train_data[idx_batch * self.batch_size:(idx_batch + 1) * self.batch_size, :-1] batch_labels = self.train_data[idx_batch * self.batch_size:(idx_batch + 1) * self.batch_size, -1] prob = self.forward(batch_images)loss = self.softmax.get_loss(batch_labels)self.backward()self.update(self.lr)if idx_batch % self.print_iter == 0:print('Epoch %d, iter %d, loss: %.6f' % (idx_epoch, idx_batch, loss))def evaluate(self):pred_results = np.zeros([self.test_data.shape[0]])for idx in range(int(self.test_data.shape[0] / self.batch_size)):batch_images = self.test_data[idx * self.batch_size:(idx + 1) * self.batch_size, :-1]prob = self.forward(batch_images)pred_labels = np.argmax(prob, axis=1)pred_results[idx * self.batch_size:(idx + 1) * self.batch_size] = pred_labelsaccuracy = np.mean(pred_results == self.test_data[:, -1])print('Accuracy in test set: %f' % accuracy)7.完整流程if __name__ == '__main__':h1, h2, e = 128, 64, 20mlp = MNIST_MLP(hidden1=h1, hidden2=h2,max_epoch=e)mlp.load_data()mlp.build_model()mlp.init_model()mlp.train()mlp.save_model('mlp-%d-%d-%depoch.npy' % (h1,h2,e))mlp.load_model('mlp-%d-%d-%depoch.npy' % (h1, h2, e))mlp.evaluate()三、代码debugpycharm在初次运⾏时,会在以下代码报错:mlp.load_model('mlp-%d-%d-%depoch.npy' % (h1, h2, e))ValueError: Object arrays cannot be loaded when allow_pickle=False经过上⽹查看原因后,发现是numpy版本太⾼引起解决⽅法:点击报错处,进⼊源代码(.py),注释掉693⾏:#if not allow_pickle:#raise ValueError("Object arrays cannot be loaded when "# "allow_pickle=False")# Now read the actual data.if dtype.hasobject:# The array contained Python objects. We need to unpickle the data.#if not allow_pickle:#raise ValueError("Object arrays cannot be loaded when "# "allow_pickle=False")if pickle_kwargs is None:pickle_kwargs = {}try:array = pickle.load(fp, **pickle_kwargs)except UnicodeError as err:if sys.version_info[0] >= 3:# Friendlier error message四、结果展⽰在不改变⽹络结构的条件下我通过⾃⾏调节参数主要体现在:if __name__ == '__main__':h1, h2, e = 128, 64, 20class MNIST_MLP(object):def __init__(self, batch_size=64, input_size=784, hidden1=32, hidden2=16, out_classes=10, lr=0.01, max_epoch=1,print_iter=100):为了提⾼准确率,当然你可以从其他⽅⾯进⾏修改,以下是我得出的输出结果:补充ValueError: Object arrays cannot be loaded when allow_pickle=False解决⽅案在读.npz⽂件时报下⾯错误:population_data=np.load("./data/populations.npz")print(population_data.files)#⾥⾯有两个数组 data feature_namesdata=population_data['data']print(data)print(population_data['feature_names'])报错:['data', 'feature_names']Traceback (most recent call last):File "E:/pycharm file/使⽤scikit-learn构建模型/构建⼀元线性模型.py", line 32, in <module>data=population_data['data']File "E:\pycharm file\venv\lib\site-packages\numpy\lib\npyio.py", line 262, in __getitem__pickle_kwargs=self.pickle_kwargs)File "E:\pycharm file\venv\lib\site-packages\numpy\lib\format.py", line 692, in read_arrayraise ValueError("Object arrays cannot be loaded when "ValueError: Object arrays cannot be loaded when allow_pickle=False报错为:numpy版本太⾼,我⽤的是1.16.3,应该降级为1.16.2两种解决⽅案:Numpy 1.16.3⼏天前发布了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

python实现手写数字识别(小白入门)要实现手写数字识别,可以使用机器学习库Scikit-learn和图像处理库OpenCV。

下面是一个简单的示例代码:
```python
import cv2
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
#加载手写数字数据集
digits = datasets.load_digits
X = digits.images.reshape((len(digits.images), -1))
y = digits.target
#划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
#创建K近邻分类器
knn = KNeighborsClassifier
#训练分类器
knn.fit(X_train, y_train)
#从图像文件中读取手写数字图像
image = cv2.imread('handwritten_digit.png',
cv2.IMREAD_GRAYSCALE)
#调整图像大小为8x8
image = cv2.resize(image, (8, 8))
#将图像转换为一维数组
image = image.reshape(1, -1)
#使用分类器进行预测
prediction = knn.predict(image)
print("预测结果:", prediction[0])
```
在这个示例中,首先使用`datasets.load_digits(`函数加载
Scikit-learn库中的手写数字数据集。

然后,将数据集划分为训练集和测试集,使用K近邻分类器进行训练。

接下来,使用OpenCV库读取手写数字图像,并将其调整为8x8大小。

然后,将图像转换为一维数组,并使用训练好的分类器进行预测。

最后,输出预测结果。

注意,这只是一个简单的示例代码,实际的手写数字识别可能需要更复杂的算法和更大规模的数据集。

相关文档
最新文档