1. 知识点准备

在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念。

a. 卷积

关于卷积的概念和细节可以参考这里,卷积运算有两个非常重要特性,以下面这个一维的卷积为例子:

第一个特性是稀疏连接。可以看到, layer m 上的每一个节点都只与 layer m-1 对应区域的三个节点相连接。这个局部范围也叫感受野。第二个特性是相同颜色的线条代表了相同的权重,即权重共享。这样做有什么好处呢?一方面权重共享可以极大减小参数的数目,学习起来更加有效,另一方面,相同的权重可以让过滤器不受图像位置的影响来检测图像的特性,从而使 CNN 具有更强的泛化能力。

b. 池化

理论上,我们将图像利用不同的过滤器通过卷积之后得到了多个卷积之后的图像,然后直接利用这些图像进行分类,但是这样计算量太大了。利用池化操作可以将数据量减小,同时在一定程度上保留原有的图像特征。关于 pooling, 概念更加简单了,详情可以参考这里。池化又可以分为平均池化和最大池化,这里我们将采用最大池化。注意到,池化的区域是不重叠的,卷积的感受野是重叠的。

2. 卷积神经网络的搭建

下图是手写数字识别中采用的 lenet-5 简单的卷积神经网络模型:

  1. 原图是 28 × 28 的手写数字图片,通过第一次 20 个 5 × 5 的卷积核之后,得到 20 张卷积图片。卷积核的权重是取一定范围内的随机值,这样,一张 28 × 28 的图片就变为 20 张 (28-5+1)× (28-5+1)=24×24 的图片了。

  2. 将 24×24 的图片进行 2 × 2 的最大池化,得到 20 张 12 × 12 的图片。该图片的像素还需要进行 tanh 函数的变换才能作为下一个卷积层的输入。

  3. 将 tanh 变化之后的 12 × 12 大小的图片同样进行 20 × 50 个 5 × 5 的卷积操作之后得到 50 张 (12-5+1)× (12-5+1) = 8 × 8 的图片。

  4. 将 8×8 的图片进行 2×2 的最大池化,得到 50 张 4×4 的图片,再经过 tanh 函数进行归一化处理,就可以作为 MLP 的 800 个输入了。

  5. 余下来就是 MLP 的训练工作了。

3. LR, MLP,CNN 识别代码

已经训练好的模型系数的下载地址

三种方法识别手写数字的代码:

 import cPickle

 import numpy

 import theano
import theano.tensor as T
from theano.tensor.signal import downsample
from theano.tensor.nnet import conv ########################################
# define the classifer constructs
######################################## class LogisticRegression(object):
def __init__(self, input, W=None, b=None): if W is None:
fle = open("../model_param/lr_sgd_best.pkl")
W, b = cPickle.load(fle)
fle.close() self.W = W
self.b = b self.outputs = T.nnet.softmax(T.dot(input, self.W) + b) self.pred = T.argmax(self.outputs, axis=1) class MLP(object):
def __init__(self, input, params=None):
if params is None:
fle = open("../model_param/mlp_best.pkl")
params = cPickle.load(fle)
fle.close() self.hidden_W, self.hidden_b, self.lr_W, self.lr_b = params self.hiddenlayer = T.tanh(T.dot(input, self.hidden_W) + self.hidden_b) self.outputs = T.nnet.softmax(T.dot(self.hiddenlayer, self.lr_W) \
+ self.lr_b) self.pred = T.argmax(self.outputs, axis=1) class CNN(object):
def __init__(self, input, params=None):
if params is None:
fle = open("../model_param/cnn_best.pkl")
params = cPickle.load(fle)
fle.close() ################
self.layer3_W, self.layer3_b, self.layer2_W, self.layer2_b, \
self.layer1_W, self.layer1_b, self.layer0_W, self.layer0_b = params # compute layer0
self.conv_out0 = conv.conv2d(input=input, filters=self.layer0_W)
# filter_shape=(20, 1, 5, 5), image_shape=(1, 1, \
# 28, 28))
self.pooled_out0 = downsample.max_pool_2d(input=self.conv_out0, \
ds=(2, 2), ignore_border=True)
self.layer0_output = T.tanh(self.pooled_out0 + \
self.layer0_b.dimshuffle('x', 0, 'x', 'x')) # compute layer1
self.conv_out1 = conv.conv2d(input=self.layer0_output, filters=self.layer1_W)
# filter_shape=(50, 20, 5, 5), image_shape=(1, 20, \
# 12, 12))
self.pooled_out1 = downsample.max_pool_2d(input=self.conv_out1, \
ds=(2, 2), ignore_border=True)
self.layer1_output = T.tanh(self.pooled_out1 + \
self.layer1_b.dimshuffle('x', 0, 'x', 'x')) # compute layer2
self.layer2_input = self.layer1_output.flatten(2) self.layer2_output = T.tanh(T.dot(self.layer2_input, self.layer2_W) + \
self.layer2_b) # compute layer3
self.outputs = T.nnet.softmax(T.dot(self.layer2_output, self.layer3_W)\
+ self.layer3_b) self.pred = T.argmax(self.outputs, axis=1) ########################################
# build classifier
######################################## def lr(input):
input.shape = 1, -1 x = T.fmatrix('x')
classifer = LogisticRegression(input=x) get_p_y = theano.function(inputs=[x], outputs=classifer.outputs)
pred_y = theano.function(inputs=[x], outputs=classifer.pred)
return (get_p_y(input), pred_y(input)) def mlp(input):
input.shape = 1, -1 x = T.fmatrix('x')
classifer = MLP(input=x) get_p_y = theano.function(inputs=[x], outputs=classifer.outputs)
pred_y = theano.function(inputs=[x], outputs=classifer.pred)
return (get_p_y(input), pred_y(input)) def cnn(input):
input.shape = (1, 1, 28, 28)
x = T.dtensor4('x')
classifer = CNN(input=x)
get_p_y = theano.function(inputs=[x], outputs=classifer.outputs)
pred_y = theano.function(inputs=[x], outputs=classifer.pred)
return (get_p_y(input), pred_y(input))

CNN 手写数字识别的更多相关文章

  1. 卷积神经网络CNN 手写数字识别

    1. 知识点准备 在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念. a. 卷积 关于卷积的概念和细节可以参考这里,卷积运算有两个非常重要特性, ...

  2. Keras cnn 手写数字识别示例

    #基于mnist数据集的手写数字识别 #构造了cnn网络拟合识别函数,前两层为卷积层,第三层为池化层,第四层为Flatten层,最后两层为全连接层 #基于Keras 2.1.1 Tensorflow ...

  3. pytorch CNN 手写数字识别

    一个被放弃的入门级的例子终于被我实现了,虽然还不太完美,但还是想记录下 1.预处理 相比较从库里下载数据集(关键是经常失败,格式也看不懂),更喜欢直接拿图片,从网上找了半天,最后从CSDN上下载了一个 ...

  4. kaggle 实战 (2): CNN 手写数字识别

    文章目录 Tensorflow 官方示例 CNN 提交结果 Tensorflow 官方示例 import tensorflow as tf mnist = tf.keras.datasets.mnis ...

  5. keras框架的CNN手写数字识别MNIST

    参考:林大贵.TensorFlow+Keras深度学习人工智能实践应用[M].北京:清华大学出版社,2018. 首先在命令行中写入 activate tensorflow和jupyter notebo ...

  6. 【深度学习系列】手写数字识别卷积神经--卷积神经网络CNN原理详解(一)

    上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...

  7. Android+TensorFlow+CNN+MNIST 手写数字识别实现

    Android+TensorFlow+CNN+MNIST 手写数字识别实现 SkySeraph 2018 Email:skyseraph00#163.com 更多精彩请直接访问SkySeraph个人站 ...

  8. 第三节,TensorFlow 使用CNN实现手写数字识别(卷积函数tf.nn.convd介绍)

    上一节,我们已经讲解了使用全连接网络实现手写数字识别,其正确率大概能达到98%,这一节我们使用卷积神经网络来实现手写数字识别, 其准确率可以超过99%,程序主要包括以下几块内容 [1]: 导入数据,即 ...

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

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

随机推荐

  1. 烂泥: KVM虚拟机Linux系统增加硬盘

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. Linux虚拟机在使用过程中,硬盘空间不够使用.由于前期没有做LVM,所以只能手动添加新的硬盘. 给虚拟机添加硬盘有两种方法: 1.通过virsh at ...

  2. Android开发学习总结(一)——搭建最新版本的Android开发环境

    Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...

  3. Mac OS X 设置取消开机自动启动

    1. 启动系统设置 (System Preferences) 2. 点以上截图的 用户/组 (User&Groups) 3. 切换到 “登录选项” (Login Items) 可以看到有saf ...

  4. 生成大小为100的数组,从1到100,随机插入,不连续,也不重复[C#]

    生成大小为100的数组,从1到100,随机插入,不连续,也不重复. 实现思路 生成一个100位的集合listA,放1到100 创建一个空的集合listB,用来存放结果 创建一个变量c,临时存储生成的数 ...

  5. 本地数据下,radiobutton和图片组合,利用adapter+listview进行单选

    浮生偷得半日闲,等接口定义的过程中,重新复习下adapter+listview实现单选的方法 主界面 <RelativeLayout xmlns:android="http://sch ...

  6. LAMP编译参数查看

    Linux下查看Nginx.Napache.MySQL.PHP的编译参数的命令如下: 1.nginx编译参数:#/usr/local/nginx/sbin/nginx -V2.apache编译参数:# ...

  7. jmap,jhat分析内存

    分析JAVA Application的内存使用时,jmap是一个很实用的轻量级工具.使用jmap可以查看heap空间的概要情况,粗略的掌握heap的使用情况.也可以生成heapdump文件,再使用jh ...

  8. dipole antenna simulation by CST

    CST偶极子天线仿真,半波振子天线 一.本文使用CST仿真频率为1GHz的偶极子天线,使用2013版本.仿真的步骤为 1.选择一个CST的天线工程模板 2.设置好默认的单位 3.设置背景的材料(空气腔 ...

  9. cri-o 创建非infra容器

    1.// cri-o/server/container.go // CreateContainer creates a new container in specified PodSandbox fu ...

  10. MIT jos 6.828 Fall 2014 训练记录(lab 6)

    源代码参见我的github: https://github.com/YaoZengzeng/jos 在这个实验中将实现一个基于Intel 82540M(又称E1000)的网卡驱动.不过,一个网卡驱动还 ...