概述

带GUI界面的,基于python sklearn knn算法的手写数字识别器,可用于识别手写数字,训练数据集为mnist。

详细

前言

k-近邻(kNN, k-NearestNeighbor)算法是一种基本分类与回归方法,
通俗点来说,就是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的 k 个实例,这 k 个实例的多数属于某个类,就把该输入实例分为这个类。

python 第三方库scikit-learn(sklearn)提供了knn的分类器。

MNIST手写数字数据库(Mixed National Institute of Standards and Technology database)包含
70000张手写数字图片。这些数字是通过美国国家统计局的员工和美国高校的学生收集的。每张图片
都是28x28的灰度图。

用mnist数据集训练出一个knn分类器,对新输入的手写数字进行识别。

准备工作

1.安装必要的第三方库:

pip install scikit-learn 
pip install numpy
pip install wxPython

安装PIL,在以下地址下载PIL库进行安装:
http://effbot.org/media/downloads/PIL-1.1.7.win32-py2.7.exe
(或在http://effbot.org/downloads/ 中找到与你操作系统及python版本相对应
版本的PIL)

2.下载mnist数据集:
可以从以下地址下载mnist数据集。
http://yann.lecun.com/exdb/mnist/
如下:

项目结构图

整体的项目结构十分简单,一共两个脚本文件,一个是GUI界面脚本(digit_gui.py),
一个是分类器脚本(model.py)。
如下:

实现过程的部分代码展示

1. 在model.py中导入相关的库:

import numpy as np
import os
from PIL import Image
import random
from sklearn.neighbors import KNeighborsClassifier as knn
from sklearn.externals import joblib

2. 编写model.py中的相关函数,

将图片转为向量:

def img2vec(fname):
'''将jpg等格式的图片转为向量'''
im = Image.open(fname).convert('L')
im = im.resize((28,28))
tmp = np.array(im)
vec = tmp.ravel()
return vec

随机抽取1000张图片作为训练集:

def split_data(paths):
'''随机抽取1000张图片作为训练集'''
fn_list = os.llistdir(paths)
X = []
y = []
d0 = random.sample(fn_list,1000)
for i,name in enumerate(d0):
y.append(name[0])
X.append(img2vec(name))
dataset = np.array([X,y])
return X,y

构建分类器:

def knn_clf(X_train,label):
'''构建分类器'''
clf = knn()
clf.fit(X_train,label)
return clf

保存模型:

def save_model(model,output_name):
'''保存模型'''
joblib.dump(model,ouotput_name)

3. 训练模型:

X_train,y_label = split_data(file_path)
clf = knn_clf(X_train,y_label)
save_model(clf,'mnist_knn1000.m')

4. 在digit_gui.py中编写用户界面:
导入相关的库:

import wx
from collections import namedtuple
from PIL import Image
import os
import model

编写界面:

class MainWindow(wx.Frame):
def __init__(self,parent,title):
wx.Frame.__init__(self,parent,title=title,size=(600,-1))
static_font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL) Size = namedtuple("Size",['x','y'])
s = Size(100,50)
sm = Size(100,25) self.fileName = None
self.model = model b_labels = [u'open',u'run'] TipString = [u'选择图片', u'识别数字'] funcs = [self.choose_file,self.run] '''create input area'''
self.in1 = wx.TextCtrl(self,-1,size = (2*s.x,3*s.y))
self.out1 = wx.TextCtrl(self,-1,size = (s.x,3*s.y)) '''create button'''
self.sizer0 = wx.FlexGridSizer(rows=1, hgap=4, vgap=2)
self.sizer0.Add(self.in1) buttons = []
for i,label in enumerate(b_labels):
b = wx.Button(self, id = i,label = label,size = (1.5*s.x,s.y))
buttons.append(b)
self.sizer0.Add(b) self.sizer0.Add(self.out1) '''set the color and size of labels and buttons'''
for i,button in enumerate(buttons):
button.SetForegroundColour('red')
button.SetFont(static_font)
button.SetToolTipString(TipString[i])
button.Bind(wx.EVT_BUTTON,funcs[i]) '''layout'''
self.SetSizer(self.sizer0)
self.SetAutoLayout(1)
self.sizer0.Fit(self) self.CreateStatusBar()
self.Show(True)

界面如下:

编写控件的回调函数:

    def run(self,evt):
if self.fileName is None:
self.raise_msg(u'请选择一幅图片')
return None
else:
model_path = os.path.join(origin_path,'mnist_knn1000.m')
clf = model.load_model(model_path)
ans = model.tester(self.fileName,clf)
self.out1.Clear()
self.out1.write(str(ans)) def choose_file(self,evt):
'''choose img'''
dlg = wx.FileDialog(
self, message="Choose a file",
defaultDir=os.getcwd(),
defaultFile="",
wildcard=wildcard,
style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR
)
if dlg.ShowModal() == wx.ID_OK:
paths = dlg.GetPaths()
dlg.Destroy()
self.in1.Clear()
self.in1.write(paths[0])
self.fileName = paths[0]
im = Image.open(self.fileName)
im.show()
else:
return None

运行效果

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

用python实现的的手写数字识别器的更多相关文章

  1. 使用神经网络来识别手写数字【译】(三)- 用Python代码实现

    实现我们分类数字的网络 好,让我们使用随机梯度下降和 MNIST训练数据来写一个程序来学习怎样识别手写数字. 我们用Python (2.7) 来实现.只有 74 行代码!我们需要的第一个东西是 MNI ...

  2. 手写数字识别 ----在已经训练好的数据上根据28*28的图片获取识别概率(基于Tensorflow,Python)

    通过: 手写数字识别  ----卷积神经网络模型官方案例详解(基于Tensorflow,Python) 手写数字识别  ----Softmax回归模型官方案例详解(基于Tensorflow,Pytho ...

  3. 手写数字识别 ----卷积神经网络模型官方案例注释(基于Tensorflow,Python)

    # 手写数字识别 ----卷积神经网络模型 import os import tensorflow as tf #部分注释来源于 # http://www.cnblogs.com/rgvb178/p/ ...

  4. 手写数字识别 ----Softmax回归模型官方案例注释(基于Tensorflow,Python)

    # 手写数字识别 ----Softmax回归模型 # regression import os import tensorflow as tf from tensorflow.examples.tut ...

  5. [Python]基于CNN的MNIST手写数字识别

    目录 一.背景介绍 1.1 卷积神经网络 1.2 深度学习框架 1.3 MNIST 数据集 二.方法和原理 2.1 部署网络模型 (1)权重初始化 (2)卷积和池化 (3)搭建卷积层1 (4)搭建卷积 ...

  6. 吴裕雄--天生自然python机器学习实战:K-NN算法约会网站好友喜好预测以及手写数字预测分类实验

    实验设备与软件环境 硬件环境:内存ddr3 4G及以上的x86架构主机一部 系统环境:windows 软件环境:Anaconda2(64位),python3.5,jupyter 内核版本:window ...

  7. Python 手写数字识别-knn算法应用

    在上一篇博文中,我们对KNN算法思想及流程有了初步的了解,KNN是采用测量不同特征值之间的距离方法进行分类,也就是说对于每个样本数据,需要和训练集中的所有数据进行欧氏距离计算.这里简述KNN算法的特点 ...

  8. python手写神经网络实现识别手写数字

    写在开头:这个实验和matlab手写神经网络实现识别手写数字一样. 实验说明 一直想自己写一个神经网络来实现手写数字的识别,而不是套用别人的框架.恰巧前几天,有幸从同学那拿到5000张已经贴好标签的手 ...

  9. python机器学习使用PCA降维识别手写数字

    PCA降维识别手写数字 关注公众号"轻松学编程"了解更多. PCA 用于数据降维,减少运算时间,避免过拟合. PCA(n_components=150,whiten=True) n ...

随机推荐

  1. Codeforces Beta Round #7 A. Kalevitch and Chess 水题

    A. Kalevitch and Chess 题目连接: http://www.codeforces.com/contest/7/problem/A Description A famous Berl ...

  2. mysql 存储过程案列一个。

    -- 设置分隔符 DELIMITER // /*初始化*/ DROP PROCEDURE IF EXISTS useCursor // /*建立 存储过程 create */ CREATE PROCE ...

  3. 装饰者模式:轻松记住IO类的关系与API

    开门见山 目录 概述与模型 1.概述 含义:动态地将责任附加到对象上.若要拓展功能,装饰者提供了比继承更有弹性的替代方案. 初衷:需要动态为某一个类拓展.通常我们会使用继承,但是继承的话,会产生很多子 ...

  4. TCP/IP具体解释--TCP/UDP优化设置总结& MTU的相关介绍

    首先要看TCP/IP协议,涉及到四层:链路层,网络层.传输层,应用层. 当中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Data)在应 ...

  5. SqlServer收缩数据库语句

    ALTER DATABASE [Spacebuilder] SET RECOVERY SIMPLEDBCC SHRINKDATABASE([Spacebuilder], 0)ALTER DATABAS ...

  6. 辛星跟您解析在CSS面包屑中三角形的定位问题

    刚才看到有位网友非常纳闷第二个棕色三角形是怎么定位的,我当感觉在以下说不清楚,就特别开了一片博客.来说清楚它.首先,前面的代码我们先抄下来,至于前面这部分代码是怎么来的,读我的用CSS制作面包屑导航的 ...

  7. U-Boot中的filesize环境变量

    U-Boot中的环境命令可以使用$(filesize)来确定刚下载(传输)得到的文件大小. 因为使用类似tftp命令传输文件后,会自动更新filesize环境变量.如:setenv updateroo ...

  8. 从Log4j迁移到LogBack的理由

    英文原文:Reasons to prefer logback over log4j 无论从设计上还是实现上,Logback相对log4j而言有了相对多的改进.不过尽管难以一一细数,这里还是列举部分理由 ...

  9. Linux C/C++开发工具

    1. vim + ctags + taglist + cscope + cppcomplete + global 2.emacs+插件 可以查看 http://blog.163.com/yu_hong ...

  10. appium+python自动化26-模拟手势点击坐标(tap)

    ​# 前言: 有时候定位元素的时候,你使出了十八班武艺还是定位不到,怎么办呢?(面试经常会问) 那就拿出绝招:点元素所在位置的坐标 tap用法 1.tap是模拟手指点击,一般页面上元素 的语法有两个参 ...