loss是训练集损失值.  acc是训练集准确率。val_loss是测试集上的损失值,val_acc是测试集上的准确率。

用深度学习框架跑过实际问题的朋友一定有这样的感觉: 太神奇了, 它竟然能自己学习重要的特征 ! 下一步我们改教会计算机什么?莫非是教会他们寻找新的未知特征

对于卷积神经网络cnn, 其中每个卷积核就是一个cnn习得的特征, 详见David 9之前的关于cnn博客

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

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

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

识别0-9的手写数字,60来行代码就能搞定,简单易懂,全程无尿点。我们先来看单机版跑完的结果

  1. (python3_env) yanchao727@yanchao727-VirtualBox:~$ python keras_mnist_cnn.py
  2. Using TensorFlow backend.
  3. x_train shape: (60000, 28, 28, 1)
  4. 60000 train samples
  5. 10000 test samples
  6. Train on 60000 samples, validate on 10000 samples
  7. Epoch 1/12
  8. 60000/60000 [==============================] - 446s - loss: 0.3450 - acc: 0.8933 - val_loss: 0.0865 - val_acc: 0.9735
  9. Epoch 2/12
  10. 60000/60000 [==============================] - 415s - loss: 0.1246 - acc: 0.9627 - val_loss: 0.0565 - val_acc: 0.9819
  11. Epoch 3/12
  12. 60000/60000 [==============================] - 389s - loss: 0.0957 - acc: 0.9717 - val_loss: 0.0493 - val_acc: 0.9842
  13. Epoch 4/12
  14. 60000/60000 [==============================] - 385s - loss: 0.0805 - acc: 0.9761 - val_loss: 0.0413 - val_acc: 0.9865
  15. Epoch 5/12
  16. 60000/60000 [==============================] - 366s - loss: 0.0708 - acc: 0.9788 - val_loss: 0.0361 - val_acc: 0.9874
  17. Epoch 6/12
  18. 60000/60000 [==============================] - 368s - loss: 0.0619 - acc: 0.9824 - val_loss: 0.0355 - val_acc: 0.9875
  19. Epoch 7/12
  20. 60000/60000 [==============================] - 363s - loss: 0.0585 - acc: 0.9826 - val_loss: 0.0345 - val_acc: 0.9875
  21. Epoch 8/12
  22. 60000/60000 [==============================] - 502s - loss: 0.0527 - acc: 0.9837 - val_loss: 0.0339 - val_acc: 0.9883
  23. Epoch 9/12
  24. 60000/60000 [==============================] - 444s - loss: 0.0501 - acc: 0.9852 - val_loss: 0.0309 - val_acc: 0.9891
  25. Epoch 10/12
  26. 60000/60000 [==============================] - 358s - loss: 0.0472 - acc: 0.9861 - val_loss: 0.0308 - val_acc: 0.9897
  27. Epoch 11/12
  28. 60000/60000 [==============================] - 358s - loss: 0.0441 - acc: 0.9872 - val_loss: 0.0330 - val_acc: 0.9893
  29. Epoch 12/12
  30. 60000/60000 [==============================] - 381s - loss: 0.0431 - acc: 0.9871 - val_loss: 0.0304 - val_acc: 0.9901
  31. Test loss: 0.0303807387119
  32. Test accuracy: 0.9901

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

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

测试集是10000个样本。

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

loss是训练集损失值.  acc是训练集准确率。val_loss是测试集上的损失值,val_acc是测试集上的准确率。

接下来我们看代码:

  1. from __future__ import print_function
  2. import keras
  3. from keras.datasets import mnist
  4. from keras.models import Sequential
  5. from keras.layers import Dense, Dropout, Flatten
  6. from keras.layers import Conv2D, MaxPooling2D
  7. from keras import backend as K

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

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

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

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

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

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

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

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

整个cnn的MNIST手写数字识别就训练完毕了,是不是非常简单,如果觉得注释还不够详尽,请自己试试源码感受下,或者看看我们文章的底部参考文献。

keras_mnist_cnn.py 完整源码:

  1. '''Trains a simple convnet on the MNIST dataset.
  2. Gets to 99.25% test accuracy after 12 epochs
  3. (there is still a lot of margin for parameter tuning).
  4. 16 seconds per epoch on a GRID K520 GPU.
  5. '''
  6. from __future__ import print_function
  7. import keras
  8. from keras.datasets import mnist
  9. from keras.models import Sequential
  10. from keras.layers import Dense, Dropout, Flatten
  11. from keras.layers import Conv2D, MaxPooling2D
  12. from keras import backend as K
  13. batch_size = 128
  14. num_classes = 10
  15. epochs = 12
  16. # input image dimensions
  17. img_rows, img_cols = 28, 28
  18. # the data, shuffled and split between train and test sets
  19. (x_train, y_train), (x_test, y_test) = mnist.load_data()
  20. if K.image_data_format() == 'channels_first':
  21. x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
  22. x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
  23. input_shape = (1, img_rows, img_cols)
  24. else:
  25. x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
  26. x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
  27. input_shape = (img_rows, img_cols, 1)
  28. x_train = x_train.astype('float32')
  29. x_test = x_test.astype('float32')
  30. x_train /= 255
  31. x_test /= 255
  32. print('x_train shape:', x_train.shape)
  33. print(x_train.shape[0], 'train samples')
  34. print(x_test.shape[0], 'test samples')
  35. # convert class vectors to binary class matrices
  36. y_train = keras.utils.np_utils.to_categorical(y_train, num_classes)
  37. y_test = keras.utils.np_utils.to_categorical(y_test, num_classes)
  38. model = Sequential()
  39. model.add(Conv2D(32,
  40. activation='relu',
  41. input_shape=input_shape,
  42. nb_row=3,
  43. nb_col=3))
  44. model.add(Conv2D(64, activation='relu',
  45. nb_row=3,
  46. nb_col=3))
  47. # model.add(MaxPooling2D(pool_size=(2, 2)))
  48. model.add(MaxPooling2D(pool_size=(2, 2)))
  49. model.add(Dropout(0.35))
  50. model.add(Flatten())
  51. model.add(Dense(128, activation='relu'))
  52. model.add(Dropout(0.5))
  53. model.add(Dense(num_classes, activation='softmax'))
  54. model.compile(loss=keras.metrics.categorical_crossentropy,
  55. optimizer=keras.optimizers.Adadelta(),
  56. metrics=['accuracy'])
  57. model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,
  58. verbose=1, validation_data=(x_test, y_test))
  59. score = model.evaluate(x_test, y_test, verbose=0)
  60. print('Test loss:', score[0])
  61. print('Test accuracy:', score[1])

参考文献:

  1. https://github.com/fchollet/keras/tree/master/examples
  2. https://keras.io/backend/

 

keras CNN解读的更多相关文章

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

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

  2. cnn进行端到端的验证码识别改进

    keras_cnn.py 训练及建模 #!/usr/bin/env python # coding=utf- """ 利用keras cnn进行端到端的验证码识别, 简单 ...

  3. Keras教程

    In this step-by-step Keras tutorial, you’ll learn how to build a convolutional neural network in Pyt ...

  4. 机器学习开源项目精选TOP30

    本文共图文结合,建议阅读5分钟. 本文为大家带来了30个广受好评的机器学习开源项目. 640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1 最近,Mybridge发布了 ...

  5. GitHub排名TOP30的机器学习开源项目/贪心学院

    对于机器学习者来说,阅读开源代码并基于代码构建自己的项目,是一个非常有效的学习方法.看看以下这些Github上平均star为3558的开源项目,你错了哪些? 1. FastText:快速文本表示和文本 ...

  6. GitHub排名TOP30的机器学习开源项目

    对于机器学习者来说,阅读开源代码并基于代码构建自己的项目,是一个非常有效的学习方法.看看以下这些Github上平均star为3558的开源项目,你错了哪些? 1. FastText:快速文本表示和文本 ...

  7. 热点 | github近期热点项目汇总

    本文是近期Github热点项目的汇总,如果你想了解更多优秀的github项目,请关注我们公众号的github系列文章. 推荐 | 7个你最应该知道的机器学习相关github项目 热点 | 六月Gith ...

  8. ApacheCN 人工智能知识树 v1.0

    贡献者:飞龙 版本:v1.0 最近总是有人问我,把 ApacheCN 这些资料看完一遍要用多长时间,如果你一本书一本书看的话,的确要用很长时间.但我觉得这是非常麻烦的,因为每本书的内容大部分是重复的, ...

  9. 1个小时!从零制作一个! AI图片识别WEB应用!

    0 前言 近些年来,所谓的人工智能也就是AI. 在媒体的炒作下,变得神乎其神,但实际上,类似于图片识别的AI,其原理只不过是数学的应用. 线性代数,概率论,微积分(著名的反向传播算法). 大家觉得这些 ...

随机推荐

  1. os & sys

    os os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd os.c ...

  2. C语言常用标准库函数

    数学函数: 在math.h中 abs(x) :求整型数x的绝对值 cos(x):x(弧度)的余弦 fabs(x):求浮点数x的绝对值 ceil(x):求不小于x的最小整数 floor(x):求不大于x ...

  3. ios 获取当前时间

    1.第一种返回的时间是一个整个的字符串. NSDate *timeDate = [NSDate date]; NSDateFormatter *dateFormatter = [[NSDateForm ...

  4. jQuery 向另一个页面传参,同时跳转到该页面

    为了使参数能够传递到另外一个页面,使用ajax的跳转方式 $.ajax({ type: "POST", url:"/admin/sysjgl/sysjck/sjcs&qu ...

  5. 【gRPC使用问题2】按照问题1操作生成出来的代码,import的proto内定义的message未生成出来

    1.问题 其实元数据proto里是有定义message,但是 这个message的定义是在另一个 proto文件内,被 api.proto导入,事实上 我是对 api.proto 进行命令行生成代码的 ...

  6. 制作根文件系统之内核如何启动init进程

    start_kernel其实也是内核的一个进程,它占用了进程号0,start_kernel的内容简写如下: asmlinkage void __init start_kernel(void) //内核 ...

  7. ajax 之POST请求,参数序列化

    比如,,我们在没有使用jquery的时候,没有$.post来让我们使用,那我们像下面这样直接发送: var params1 = { username: username, passwrod: pass ...

  8. HTTP.ResponseCode

    HTTP响应码: http://blog.csdn.net/cutbug/article/details/4024818

  9. wepy中页面的跳转

    1.在pages中创建好页面之后,需要在app.wpy中的config中配置好页面路由:2.如果跳转的按钮在page页面中 this.$navigate({url:"content" ...

  10. mysql cmd 无法登录

    第一次折腾mysql诉苦记 版本注明: mysql 5.7.21 本地部署mysql,配置完成后(配置没有问题) cmd命令连接mysql: mysql -uroot -p 提示: ERROR 104 ...