教你使用keras在kaggle数字识别大赛中拿到前百名

1、写在前面

    最近一直在研究深度学习,每一种深度学习算法都让我感受打开了新世界的大门。git

    没想到第一次在kaggle上随便参加了个简单比赛就取得了前5%的成绩,虽然只是一个简单的比赛,可是这个结果也让初学者的我很是开心。github

   

   目前个人模型的识别率是99.771%,爬到52名以后就往上爬不动了。若是有大佬有能提升识别率,甚至识别率达到100%的方法,或者对这篇文章有任何意见建议,欢迎和我交流。算法

个人微博是@阿扣是谁哇  欢迎来找我玩OVObash

2、模型选择

   在此咱们选择最简单的神经网络模型MLP网络


   为何选择MLP呢?有以下几个缘由:app


   一、由于up主如今很穷,用的电脑仍是13年的macbook,仍是只有集显的那种,卷积神经网络up主也测试过,可是训练起来电脑有点吃力,因此就放弃了╮(╯▽╰)╭。机器学习

   二、kaggle中提供的训练数据和传统的mnist数据维度彻底同样,都是长宽为28像素的黑白图像,单张图只有784维,即便不进行池化卷积等操做,须要训练的参数也只有不到20万个。函数

   三、若是简单的神经网络能解决问题,就不要用复杂的模型了(固然复杂的模型也要能理解而且能coding),毕竟如今显卡那么贵.......算了扯远了.....学习



3、代码详解


该项目完整代码:在这里测试

(https://github.com/hikariming/Digit_Recognizer_99.771-/blob/master/digit_kaggle.py)


一、引入各类包

这一步就不细说啦,大概就是引入各类包,最主要的仍是引入keras还有numpy

# -*- coding: utf-8 -*-
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD
import numpy as np
import csv
复制代码

二、引入训练数据


定义一个打开训练集的函数,训练数据从kaggle上下载下来便可,下载下来的数据的shape为(42000,784),即有42000个训练数据。

def LoadTraincsvfile():
    tmp=np.loadtxt('/Users/itwork/Desktop/train_set/big-mnist/train.csv',dtype=np.str,delimiter=',')
    x_data=tmp[1:,1:].astype(np.float)
    y_data=tmp[1:,0].astype(np.float)
    return x_data,y_data
#打开从kaggle上下载下来的训练数据
x_data,y_data=LoadTraincsvfile()

复制代码

三、扩充训练数据


为了达到更高的识别率,咱们须要更多的训练数据,我的感受常规的经过图像变形的方法对手写数字没啥卵用(毕竟手写的数字通过变形、翻转以后就不像数字了,并且训练数据像素比较低),因此我放弃了这种扩充数据集的方法。

在这里,我直接把标准的mnist数据集也引入进训练集中,mnist里面有60000万个28x28的手写数字图像。



path = './mnist.npz'
f = np.load(path)
x_train1, y_train1 = f['x_train'], f['y_train']
x_test1, y_test1 = f['x_test'], f['y_test']
f.close()
x_train1 = x_train1.reshape(60000, 784).astype('float32')复制代码



把kaggle上的手写训练数据和mnist手写数据结合一下,就有102000条训练数据了,这样训练数据就扩充了2倍多。

x_train=np.concatenate((x_data[0:42000,:],x_train1),axis=0)
y_train=np.concatenate((y_data[0:42000],y_train1),axis=0)复制代码


四、构建测试集(可忽略)、数据标准化


在这里的测试集其实没啥子用,为了提升准确度我把全部kaggle给的训练数据全都当作训练集了,这里的测试集和训练集是重合的。


数据标准化很是简单,直接把单个像素点除个255就好

#构件测试集
x_test=x_data[41000:,:]
y_test=y_data[41000:]
print (x_train.shape)
print (y_train.shape)

#数据标准化
x_train /= 255
x_test /= 255复制代码

五、创建网络开始训练+调参


正片开始了,创建好粗略的MLP模型的以后,慢慢的调参。


我主要调整了损失函数(改变损失函数以后,识别率忽然飙升,我也没搞懂为啥会这样- -),学习率,每层的神经元的个数

在没有调参和修改损失函数前,这个模型的识别率大概在97%左右,通过调参识别率就上升到了99.7%了,损失函数的值已经降到了10的-5仍是-7次方了,能够说很是夸张。

在这里我没有用dropout,up主不是很喜欢用dropout,由于总以为它会形成网络内随机性和风险增长,下降识别率

此处代码不详细说,参考keras官方文档便可。

model = Sequential()

model.add(Dense(200, activation='relu', input_dim=784))
model.add(Dense(120, activation='relu'))
model.add(Dense(10, activation='softmax'))
#使用adam加速方法,beta的值是adam创始人论文的推荐值,所以就不调了
adam = keras.optimizers.Adam(lr=0.0005, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(loss='binary_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

model.fit(x_train, y_train,
          epochs=50,
          batch_size=256)
score = model.evaluate(x_test, y_test, batch_size=4096)
print(model.metrics_names)
print(score)
复制代码


六、对未知数据进行预测,将结果上传到kaggle

每个kaggle上的比赛,对上传的结果文件格式都有必定的要求,格式要求在相应竞赛的附件里面有,本身下载下来参考便可。



根据Digit_Recognizer比赛的要求,咱们对测试集进行预测,并将预测结果输出成csv文件:


#预测部分
is_predict=1
if(is_predict):
    #将测试数据标准化
    tmp = np.loadtxt('/Users/itwork/Desktop/train_set/big-mnist/test.csv', dtype=np.str, delimiter=',')
    x_predict = tmp[1:, :].astype(np.float)
    x_predict /= 255
    #进行预测
    classes = model.predict_classes(x_predict)
   
    #输出结果
    resultlist = []
    imgid = 1
    for i in classes:
        res_data = {'ImageId': imgid, 'Label': i}
        resultlist.append(res_data)
        imgid = imgid + 1

    headers = ['ImageId', 'Label']
    with open('result.csv', 'w', newline='') as f:
        # 标头在这里传入,做为第一行数据
        writer = csv.DictWriter(f, headers)
        writer.writeheader()
        for row in resultlist:
            writer.writerow(row)

复制代码

4、后记

一、比赛方面

   数字识别虽然是最简单的机器学习分类问题之一,可是能玩到这么高的识别率,对于萌新如个人人来讲仍是挺开心的。

   损失函数的构建公式对预测结果影响仍是挺大的,但愿本身能多多理解损失函数的内涵吧。

   kaggle上有很多人已经达到了100%的识别率了,真心佩服,真心想知道他们是怎么实现的。

二、最后的唠叨

   计算机视觉这方面的内容因为我电脑机能的缘由就暂时无法学了QAQ,建议各位想学深度学习的孩子仍是砸锅卖铁弄台好电脑。

    kaggle上的大部分计算机视觉的题目,光是将训练集就直接能够把个人笔记本电脑内存塞满,电脑崩溃╮(╯▽╰),即便解决了内存问题。若是显卡很差的话,即便你用迁移学习,训练一趟也仍是要花几个小时,简直无法玩。


接下来我会研究LSTM这些RNN的相关技术,参加一下kaggle上面的文本识别比赛,有兴趣的朋友欢迎组个队呀~若是你不嫌弃我电脑卡技术菜的话2333

相关文章
相关标签/搜索