今天我们的主角是keras,其简洁性和易用性简直出乎David 9我的预期。大家都知道keras是在TensorFlow上又包装了一层,向简洁易用的深度学习又迈出了坚实的一步。

所以,今天就来带大家写keras中的Hello World , 做一个手写数字识别的cnn。回顾cnn架构:

我们要处理的是这样的灰度像素图:

我们先来看跑完的结果(在Google Colab上运行

x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/12
60000/60000 [==============================] - 12s 193us/step - loss: 0.2672 - acc: 0.9166 - val_loss: 0.0648 - val_acc: 0.9792
Epoch 2/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0892 - acc: 0.9731 - val_loss: 0.0433 - val_acc: 0.9866
Epoch 3/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0666 - acc: 0.9796 - val_loss: 0.0353 - val_acc: 0.9874
Epoch 4/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0578 - acc: 0.9829 - val_loss: 0.0327 - val_acc: 0.9887
Epoch 5/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0483 - acc: 0.9856 - val_loss: 0.0295 - val_acc: 0.9901
Epoch 6/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0433 - acc: 0.9869 - val_loss: 0.0313 - val_acc: 0.9895
Epoch 7/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0379 - acc: 0.9879 - val_loss: 0.0267 - val_acc: 0.9913
Epoch 8/12
60000/60000 [==============================] - 9s 147us/step - loss: 0.0353 - acc: 0.9891 - val_loss: 0.0263 - val_acc: 0.9913
Epoch 9/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0327 - acc: 0.9904 - val_loss: 0.0275 - val_acc: 0.9905
Epoch 10/12
60000/60000 [==============================] - 9s 146us/step - loss: 0.0323 - acc: 0.9898 - val_loss: 0.0260 - val_acc: 0.9914
Epoch 11/12
60000/60000 [==============================] - 9s 147us/step - loss: 0.0286 - acc: 0.9913 - val_loss: 0.0283 - val_acc: 0.9909
Epoch 12/12
60000/60000 [==============================] - 9s 147us/step - loss: 0.0267 - acc: 0.9922 - val_loss: 0.0268 - val_acc: 0.9906
Test loss: 0.026836299882206368
Test accuracy: 0.9906

所以我们跑的是keras_mnist_cnn.py。最后达到99%的预测准确率。首先来解释一下输出:

测试样本格式是28*28像素的1通道,灰度图,数量为60000个样本。

测试集是10000个样本。

一次epoch是一次完整迭代(所有样本都训练过),这里我们用了12次迭代,最后一次迭代就可以收敛到99.06%预测准确率了。

接下来我们看代码:

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

一开始我们导入一些基本库,包括:

  • minst数据集
  • Sequential类,可以封装各种神经网络层,包括Dense全连接层,Dropout层,Cov2D卷积层,等等
  • 我们都直到Keras支持两个后端TensorFlow和Theano,可以在$HOME/.keras/keras.json中配置

接下来,我们准备训练集和测试集,以及一些重要参数:

# batch_size 太小会导致训练慢,过拟合等问题,太大会导致欠拟合。所以要适当选择
batch_size = 128
# 0-9手写数字一个有10个类别
num_classes = 10
# 12次完整迭代,差不多够了
epochs = 12
# 输入的图片是28*28像素的灰度图
img_rows, img_cols = 28, 28
# 训练集,测试集收集非常方便
(x_train, y_train), (x_test, y_test) = mnist.load_data() # keras输入数据有两种格式,一种是通道数放在前面,一种是通道数放在后面,
# 其实就是格式差别而已
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
# 把数据变成float32更精确
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# 把类别0-9变成独热码
y_train = keras.utils.np_utils.to_categorical(y_train, num_classes)
y_test = keras.utils.np_utils.to_categorical(y_test, num_classes)

然后,是令人兴奋而且简洁得令人吃鲸的训练构造cnn和训练过程:

# 牛逼的Sequential类可以让我们灵活地插入不同的神经网络层
model = Sequential()
# 加上一个2D卷积层, 32个输出(也就是卷积通道),激活函数选用relu,
# 卷积核的窗口选用3*3像素窗口
model.add(Conv2D(32,
activation='relu',
input_shape=input_shape,
nb_row=3,
nb_col=3))
# 64个通道的卷积层
model.add(Conv2D(64, activation='relu',
nb_row=3,
nb_col=3))
# 池化层是2*2像素的
model.add(MaxPooling2D(pool_size=(2, 2)))
# 对于池化层的输出,采用0.35概率的Dropout
model.add(Dropout(0.35))
# 展平所有像素,比如[28*28] -> [784]
model.add(Flatten())
# 对所有像素使用全连接层,输出为128,激活函数选用relu
model.add(Dense(128, activation='relu'))
# 对输入采用0.5概率的Dropout
model.add(Dropout(0.5))
# 对刚才Dropout的输出采用softmax激活函数,得到最后结果0-9
model.add(Dense(num_classes, activation='softmax'))
# 模型我们使用交叉熵损失函数,最优化方法选用Adadelta
model.compile(loss=keras.metrics.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
# 令人兴奋的训练过程
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,
verbose=1, validation_data=(x_test, y_test))

完整地训练完毕之后,可以计算一下预测准确率:

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

参考链接:
1、nooverfit.com/wp/keras-手把手入门1-手写数字识别-深度学习实战/

2、https://blog.csdn.net/yzh201612/article/details/69400002

MINST手写数字识别(二)—— 卷积神经网络(CNN)的更多相关文章

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

    代码 import torch from torchvision import datasets from torch.utils.data import DataLoader import torc ...

  2. 利用神经网络算法的C#手写数字识别(二)

    利用神经网络算法的C#手写数字识别(二)   本篇主要内容: 让项目编译通过,并能打开图片进行识别.   1. 从上一篇<利用神经网络算法的C#手写数字识别>中的源码地址下载源码与资源, ...

  3. MINST手写数字识别(三)—— 使用antirectifier替换ReLU激活函数

    这是一个来自官网的示例:https://github.com/keras-team/keras/blob/master/examples/antirectifier.py 与之前的MINST手写数字识 ...

  4. MINST手写数字识别(一)—— 全连接网络

    这是一个简单快速入门教程——用Keras搭建神经网络实现手写数字识别,它大部分基于Keras的源代码示例 minst_mlp.py. 1.安装依赖库 首先,你需要安装最近版本的Python,再加上一些 ...

  5. Kaggle竞赛丨入门手写数字识别之KNN、CNN、降维

    引言 这段时间来,看了西瓜书.蓝皮书,各种机器学习算法都有所了解,但在实践方面却缺乏相应的锻炼.于是我决定通过Kaggle这个平台来提升一下自己的应用能力,培养自己的数据分析能力. 我个人的计划是先从 ...

  6. BP神经网络的手写数字识别

    BP神经网络的手写数字识别 ANN 人工神经网络算法在实践中往往给人难以琢磨的印象,有句老话叫“出来混总是要还的”,大概是由于具有很强的非线性模拟和处理能力,因此作为代价上帝让它“黑盒”化了.作为一种 ...

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

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

  8. 手写数字识别 卷积神经网络 Pytorch框架实现

    MNIST 手写数字识别 卷积神经网络 Pytorch框架 谨此纪念刚入门的我在卷积神经网络上面的摸爬滚打 说明 下面代码是使用pytorch来实现的LeNet,可以正常运行测试,自己添加了一些注释, ...

  9. TensorFlow 卷积神经网络手写数字识别数据集介绍

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 手写数字识别 接下来将会以 MNIST 数据集为例,使用卷积层和池 ...

随机推荐

  1. ASP.NET中MessageBox的实现

    asp.net中没有MessageBox这个控件,固然可以插入Winform里的MessageBox,但一般不提倡,所以只能变通实现,主要有这几种方法: 1.直接利用javascript的alert和 ...

  2. P3803 【模板】多项式乘法(NTT)

    传送门 NTT好像是比FFT快了不少 然而感觉不是很看得懂……主要是点值转化为系数表示那里…… upd:大概已经搞明白是个什么玩意儿了……吧…… //minamoto #include<bits ...

  3. Modulation of Lipid Metabolism by Celastrol (文献分享一组-赵倩倩)

    文献名:Modulation of Lipid Metabolism by Celastrol (雷公藤红素对脂质代谢调节作用的研究) 期刊名:Journal of Proteome Research ...

  4. C语言提高代码效率的几种方法

    一段完美的代码不仅在于找到一个给定的问题的解决方案,但在它的简单性,有效性,紧凑性和效率(内存).设计的代码比实际执行更难.因此,每一个程序员当用C语言开发时,都应该保持这些基本的东西在头脑中.本文向 ...

  5. shell学习(6)- curl

    在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具. 语法 cur ...

  6. python 对mongdb的简单操作

    准备工作:1.选择安装合适的mongodb到本地电脑,2.创建mongodb实例,3,开启mongodb实例,4,下载pymongo第三方库,5.下载pycharm对mongodb可视化支持的插件mo ...

  7. Codeforces Round #541 (Div. 2) C.Birthday

    链接:https://codeforces.com/contest/1131/problem/C 题意: 求给的n个数,相邻差值最小的排列方式.1-n相邻. 思路: sort后隔一个取一个,取到底后再 ...

  8. STM32使用注意事项

    一 IO引脚: 1.1 PC13~PC15作为IO输出的限制,PC13/PC15输出最大2MHZ,负载2PF,驱动电流不超过3mA,所以不能用来驱动LED. 2 输出的引脚是否可以用来读引脚: cas ...

  9. [未读]深入浅出node.js

    还没看过,据说很多内容来自国外译文.

  10. MDX之Case When用法

    with member [Measures].[终端销售数量总计] as sum(ytd([日期].[年月].CurrentMember),[Measures].[终端销售数量]) member [M ...