完成了Kaggle上的Digit Recognizer的任务。
Keras简介
Keras是一个高层神经网络API,Keras由纯Python编写而成并基Tensorflow、Theano以及CNTK后端。Keras 为支持快速实验而生,能够把你的idea迅速转换为结果,有如下优点:
- 简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性)
- 支持CNN和RNN,或二者的结合
- 无缝CPU和GPU切换
Keras搭建网络
导入模块
import numpy as np //科学计算库
import pandas as pd //这里主要用来读CSV文件,从Kaggle上下载的。
如果要使用MNIST数据集,应该要作如下操作:
from keras.datasets import mnist
...
...
(X_train, y_train), (X_test, y_test) = mnist.load_data()
然后,
from sklearn.model_selection import train_test_split //切分数据集,一部分为训练集,一部分为测试集。
from keras.utils.np_utils import to_categorical // 独热编码转换
from keras.models import Sequential //序贯模型,神经层按顺序排列
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
//Dense:全连接层
//Dropout:为输入数据施加Dropout,在训练过程中每次更新参数时随机断开一定百分比(rate)的输入神经元,用于防止过拟合。
//Flatten:用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。
//Conv2D:二维卷积层
//MaxPool2D:二位最大池化层
from keras.optimizers import Adam //Adam优化器
数据预处理
train = pd.read_csv("data/train.csv")
test = pd.read_csv("data/test.csv")
X_train = X_train.values.reshape(-1,28,28,1)/255.0 //-1代表输入数据个数不确定,28代表尺寸,1代表通道数
test = test.values.reshape(-1,28,28,1)/255.0
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 0.1)
//把训练集分为训练集(0.9)和测试集(0.1)
搭建网络
网络的结构为Input -> [[Conv2D->relu]*2 -> MaxPool2D -> Dropout]*2 -> Flatten -> Dense -> Dropout -> Output
model = Sequential()
model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',
activation ='relu', input_shape = (28,28,1))) //32个卷积核
model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',
activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same',
activation ='relu'))
model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same',
activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten()) //变一维
model.add(Dense(256, activation = "relu")) //256个神经元的全连接层
model.add(Dropout(0.5))
model.add(Dense(10, activation = "softmax"))
adam = Adam(lr=0.0001) //Adam优化器学习率
model.compile(optimizer = adam , loss = "categorical_crossentropy", metrics=["accuracy"])
//loss function为交叉熵函数
训练
model.fit(X_train, Y_train, epochs=5, batch_size=64)
//epoch代表所有训练样本的一个正向传递和一个反向传递。
//batch_size为每次训练在训练集中取的样本训练个数。
测试和分类
loss, accuracy = model.evaluate(X_val, Y_val) //之前分出来的测试集
print('\ntest loss: ', loss)
print('\ntest accuracy: ', accuracy)
测试集结果
test loss: 0.04941115902071553
test accuracy: 0.9857142857142858
最后对输入的未知图片进行分类
results = model.predict(test)
results = np.argmax(results,axis = 1)
results = pd.Series(results,name="Label")
submission = pd.concat([pd.Series(range(1,28001),name = "ImageId"),results],axis = 1)
submission.to_csv("data/cnn_mnist_datagen.csv",index=False)//输出到文件
最后在网站上提交
训练模型在测试数据上有99.357%准确率。