kaggle数字识别比赛介绍:
基于MINST数据集上训练的Kaggle入门项目Digit Recognizer的处理方案,参考比赛地址链接
kaggle数字识别比赛(识别率99.37%)代码github带数据集可参考 github地址链接
注明:kaggle数字识别比赛(识别率99.37%)代码来自项目Kernels,作者Peter Grenholm使用keras实现CNN网络,源代码请参照 源代码地址
kaggle数字识别比赛(识别率99.37%)代码翻译:
## Convolutional Neural Networks
如果您想将机器学习应用于图像识别,那么卷积神经网络(CNN)就是您的选择。在过去的几年里,它一直在席卷竞争对手,但也许它的第一次重大成功发生在90年代后期,当时Yann LeCun使用它以99.5%的准确度解决了MNIST。我将向您展示如何在Keras中完成它,这是一个用户友好的python神经网络库。
这里的许多其他笔记本使用简单的全连接网络(无卷积)来实现96-97%,这对该数据集来说效果不佳。相比之下,我将在这里向您展示的几乎是最先进的。在内核中(<20分钟训练),我们将达到99%,但如果你一夜之间训练(或使用GPU),你应该达到99.5。如果你在几次运行中进行模型的融合,你应该接近99.77%的最佳公布准确度。 (忽略排行榜上的100%结果;它们是通过重复提交来学习测试集而创建的)
开始:
如果您还没有Keras,可以通过conda或pip轻松安装。它依赖于tensorflow或theano,所以你应该先安装这些。 Keras已在内核和亚马逊深度学习AMI上提供。
#导入numpy包后续进行数据处理
import numpy as np # linear algebra
#导入matplotlib包后续进行画图
import matplotlib.pyplot as plt
#内嵌画图,使图像显示在该页面内
%matplotlib inline
#导入train_test_split包划分数据集为训练集,验证集
from sklearn.model_selection import train_test_split
#导入confusion_matrix(混淆矩阵),查看真实值被正确或者错误预测的个数
from sklearn.metrics import confusion_matrix
#one-hot编码,采用独热码编码,直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制,构造稀疏矩阵,解决分类值表示的问题对模型产生的负面影响
from keras.utils.np_utils import to_categorical # convert to one-hot-encoding
#导入顺序Sequential模型,后续可直接在Sequential上构建神经网络
from keras.models import Sequential
#Dense:全连接层;Dropout正则化数据;Flatten压平数据连接全连接层,Conv2D卷积层卷积计算,BatchNormalization数据规范化输出数据的均值接近0,其标准差接近1
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D, BatchNormalization
#导入优化器Adam,基于一阶梯度的随机目标函数优化算法
from keras.optimizers import Adam
#导入ImageDataGenerator图像增广技术来扩充我们的数据集
from keras.preprocessing.image import ImageDataGenerator
#导入LearningRateScheduler动态修改学习率的回调函数
from keras.callbacks import LearningRateScheduler
Using TensorFlow backend.
#根据自己所下载数据设置对应的路径
train_file = "/home/lqm/下载/kaggle/digit_data/digit-recognizer/train.csv"
test_file = "/home/lqm/下载/kaggle/digit_data/digit-recognizer/test.csv"
output_file = "/home/lqm/kaggle_result/submission.csv"
导入数据
与往常一样,我们将数据拆分为训练集和验证集,以便我们可以评估模型的性能。
#numpy导入数据,np.loadtxt
#loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
#fname要读取的文件、文件名、或生成器。
#dtype数据类型,默认float。
#comments注释。
#delimiter分隔符,默认是空格。
#skiprows跳过前几行读取,默认是0,必须是int整型。
#usecols:要读取哪些列,0是第一列。例如,usecols = (1,4,5)将提取第2,第5和第6列。默认读取所有列。
#unpack如果为True,将分列读取
raw_data = np.loadtxt(train_file, skiprows=1, dtype='int', delimiter=',')
raw_data
array([[1, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[1, 0, 0, ..., 0, 0, 0],
...,
[7, 0, 0, ..., 0, 0, 0],
[6, 0, 0, ..., 0, 0, 0],
[9, 0, 0, ..., 0, 0, 0]])
#raw_data[:,1:]表示第一横轴(第0行)的全部数与第一横轴(第0行)第1个数到全部数两两对应组成数组索引,然后取该索引值再组成新的array
#raw_data[:,1:]这里根据数据结构去掉标签得到训练集
raw_data[:,1:]
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]])
#raw_data[:,0]表示第一横轴(第0行)的全部数与数字1两两对应组成数组索引,然后取该索引值再组成新的数组
#raw_data[:,0]这里根据数据结构只取标签
raw_data[:,0]
array([1, 0, 1, ..., 7, 6, 9])
#划分数据集为训练集和验证集
#train_test_split(train_data,train_target,test_size=0.3, random_state=0)
#train_data:被划分的样本特征集
#train_target:被划分的样本标签
#test_size:如果是浮点数,在0-1之间,表示验证集样本占比;如果是整数的话就是样本的数量
#random_state:是随机数的种子,使每次产生的随机数一样
x_train, x_val, y_train, y_val = train_test_split(raw_data[:,1:], raw_data[:,0], test_size=0.1)
每个数据点由784个值组成。完全连接的网络只是将所有这些值视为相同,但CNN将其视为28x28平方。这两个图解释了差异:很容易理解为什么CNN可以获得更好的结果。
#subplots:子图显示,fig, ax = su