From b87e8a371e232288e6d4a8f07f6d2047df670dae Mon Sep 17 00:00:00 2001 From: dayhaha <18800111918@163.com> Date: Wed, 4 Jan 2017 20:02:25 +0800 Subject: [PATCH] follow comments, except for the formula part --- recognize_digits/.gitignore | 4 + recognize_digits/README.md | 674 +++++++++---------- recognize_digits/{src => }/cnn_mnist.py | 0 recognize_digits/{src => }/evaluate.py | 0 recognize_digits/image/Conv_layer.png | Bin 56507 -> 150788 bytes recognize_digits/image/cnn_train_log.png | Bin 0 -> 50549 bytes recognize_digits/image/mlp_train_log.png | Bin 58618 -> 57452 bytes recognize_digits/image/softmax_train_log.png | Bin 59217 -> 59423 bytes recognize_digits/{src => }/load_data.py | 0 recognize_digits/{src => }/mlp_mnist.py | 0 recognize_digits/{src => }/mnist_provider.py | 0 recognize_digits/{src => }/plot_error.py | 0 recognize_digits/{src => }/predict.py | 0 recognize_digits/{src => }/softmax_mnist.py | 0 recognize_digits/{src => }/train.sh | 0 15 files changed, 330 insertions(+), 348 deletions(-) create mode 100644 recognize_digits/.gitignore rename recognize_digits/{src => }/cnn_mnist.py (100%) rename recognize_digits/{src => }/evaluate.py (100%) create mode 100644 recognize_digits/image/cnn_train_log.png rename recognize_digits/{src => }/load_data.py (100%) rename recognize_digits/{src => }/mlp_mnist.py (100%) rename recognize_digits/{src => }/mnist_provider.py (100%) rename recognize_digits/{src => }/plot_error.py (100%) rename recognize_digits/{src => }/predict.py (100%) rename recognize_digits/{src => }/softmax_mnist.py (100%) rename recognize_digits/{src => }/train.sh (100%) diff --git a/recognize_digits/.gitignore b/recognize_digits/.gitignore new file mode 100644 index 00000000..3133248f --- /dev/null +++ b/recognize_digits/.gitignore @@ -0,0 +1,4 @@ +data/raw_data +data/train.list +data/test.list +*.log diff --git a/recognize_digits/README.md b/recognize_digits/README.md index 04e417cc..237e5644 100644 --- a/recognize_digits/README.md +++ b/recognize_digits/README.md @@ -1,51 +1,127 @@ # 手写字符识别教程 ## 背景介绍 -当我们学习编程的时候,编写的第一个程序一般是实现打印"Hello World"。而就像编程语言有"Hello World",机器学习则 -有MNIST数据库。MNIST数据库是手写字符,属于机器学习中典型的图像分类问题,而由于其问题简单,数据集完备,因此 -常常被作为机器学习入门的教程。 - - -该数据库的提供者Yann LeCun,他早起在手写字符识别上做了很多研究,在研究过程中 -提出了卷积神经网络,大幅度的提高了识别能力,也因此成为了深度学习领域的奠基人之一。如今的深度学习领域,卷积 -神经网络占据了至关重要的地位,从最早Yann LeCun提出的简单LeNet,到如今ImageNet大赛上的优胜模型VGGNet,GoogLeNet, -虽然在网络结构上要复杂很多,但是其核心还是与LeNet类似,只不过在网络的组织上面有了更多的技巧,如GoogLeNet的 -Inception模块,以及深度学习为了防止过拟合,还会加入正则,BatchNorm等等方法。 - +当我们学习编程的时候,编写的第一个程序一般是实现打印"Hello World"。而就像编程语言有"Hello World",机器学习则有 [MNIST](http://yann.lecun.com/exdb/mnist/) 数据库。MNIST数据库是手写字符,属于机器学习中典型的图像分类问题,而由于其问题简单,数据集完备,因此常常被作为机器学习入门的教程。 MNIST数据库作为一个简单的计算机视觉数据集,包含一系列如下的手写数字:
图1. MNIST图片示例
+
分类器 | +预处理 | +测试误差 | +参考文献 | +
---|---|---|---|
linear classifier (1-layer NN) | +none | +12.0 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
linear classifier (1-layer NN) | +deskewing | +8.4 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
2-layer NN, 300 hidden units, mean square error | +none | +4.7 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
2-layer NN, 300 HU | +deskewing | +1.6 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
2-layer NN, 800 HU, Cross-Entropy Loss | +none | +1.6 | +[Simard et al., ICDAR 2003] (https://www.microsoft.com/en-us/research/publication/best-practices-for-convolutional-neural-networks-applied-to-visual-document-analysis/) | +
Convolutional net LeNet-1 | +subsampling to 16x16 pixels | +1.7 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
Convolutional net LeNet-4 | +none | +1.1 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
Convolutional net LeNet-5, [no distortions] | +none | +0.95 | +[LeCun et al. 1998] (http://yann.lecun.com/exdb/publis/index.html#lecun-98) | +
@@ -54,19 +130,38 @@ $$ y_i = \frac{e^{net_i}}{\sum_j e^{net_j}} $$ 注:图中权重用黑线表示,偏置用红线表示,+1代表偏置参数的系数为1
+神经网络模型的构建包括网络配置在内,通常有以下几个步骤: + +1. 网络结构配置 +2. 初始化参数,其中包括训练参数权重W和偏置b,以及超参数训练速度 $\eta$、 `batchSize` 和训练轮次 `Pass` 等等,训练参数随着网络的迭代不断更新,而超参数一般是在网络初始化的时候给定好的。 +3. 前向传播计算网络输出和代价损失函数。 +4. 根据代价损失函数进行反向误差传播,更新训练参数。 +5. 重复3~4步骤,直至网络训练误差达到规定的程度或训练轮次达到设定值。 + +对于以上步骤4,神经网络的训练采用 `backpropagation` 的形式,其一般会定义一个损失函数(也称目标函数),训练的目的是为了减小目标函数的 +值。在分类问题中,我们一般采用交叉熵代价损失函数(cross entropy),其形式如下: + + ### 多层感知器(Multilayer Perceptron, MLP) -#### 原理介绍: -在softmax回归中,我们采用了最简单的两层神经网络,分别为输入的datalayer层和输出的softmax层,模型比较简单,意味着 + +在softmax回归中,我们采用了最简单的两层神经网络,分别为输入的datalayer层和输出的 `softmax` 层,模型比较简单,意味着 其拟合能力有限。因此,为了达到更好的识别效果,我们可以考虑在输入层和输出层中间加上若干个隐藏层。 + 在该网络层中,我们有输入X($x_i(i=0,1,2,...,n-1)$),输出标签Y($y_i(i=0,1,2,..9)$),为了表示方便,以下我们都直接 用向量计算来表示。经过第一层网络,我们可以得到: + $$ H_1 = activation(W_1X + b_1) $$ -上面,activation代表激活函数,其常见的为sigmoid,tanh或ReLU等函数。 + +上面,`activation` 代表激活函数,其常见的为 `sigmoid` ,`tanh` 或 `ReLU` 等函数。 经过第二层网络,可以得到: + $$ H_2 = activation(W_2H_1 + b_2) $$ + 最后,再经过输出层: + $$ Y = softmax(W_3H_2 + b_3) $$ + 得到的P即为最后的预测结果向量。
@@ -74,144 +169,101 @@ $$ Y = softmax(W_3H_2 + b_3) $$
注:图中权重用黑线表示,偏置用红线表示,+1代表偏置参数的系数为1
图4. 卷积层图片
图5. 池化层图片
图6. 卷积神经网络结构
-
-
+
t10k-images-idx3-ubyte | +测试数据图片,10,000条数据 | +
t10k-labels-idx1-ubyte | +测试数据标签,10,000条数据 | +
train-images-idx3-ubyte | +训练数据图片,60,000条数据 | +
train-labels-idx1-ubyte | +训练数据标签,60,000条数据 | +
+
+
图8. softmax回归训练误差图
图9. 多层感知器训练误差图
+
+图10. 卷积神经网络训练误差图
+
t*A%3$w;67h%`@ntU|t46Qg^@Zw&xn-2C+M|R^EWYo}nJIBa>%I?8A1nv7
z9^YvBIvC|D^L$b6+!Z~G>jkxgVz&x8ElJ8(cBn2!p3@tnr!84m4#!~yyER+q6IQP!
zTHo~}xRWG%sq=tNOkNLlvrPg+5E{q~nybq}T?5tlAuyQe&YP$hSHxG1x)kFM>?fKr
z=k#li4R0Q?er&XZsI;fzzGVHL;kQt8@d`JW?t|7aO$D)bZZyg5oKXH-0WLoF*ax~+
zjUE@6SG#=Gh_!lPvsCSu&faZYCCWg$eqg5U2Se4m>ZbA5IEK`0Q}~T}lW=0+xmBn4
ze(Ft^Fh>u4|NcFWLk;jY)zs9c4;yzDcy$BRpNvOoR gax=rEbf{Pb0$b6{Lb+|x&DK}^8=Z2Nz3t50tUNZ;Y;wzR
z@k!XW{0CB%^UG@9tV&1ma~okmp?JeBND?e@RwVtpTxNRS;gwid!&Z(r)NVr&5-Fez
z%tgQ;G|$kWbV0D^?qE%L3E)yC4Takc2c(?~Xr
z5<;d-tUdIa5e8!{ccFk7^iLp%@RkN0zqvg=u2M|{?6Onqy5-y7DeCf=LDVs{%vOR1
z9v2{5o*_M-&LKLE{>p3EcG`B_=n
r?y