Kaggle-MNIST上手

作者: Yung968 | 来源:发表于2019-02-07 23:11 被阅读13次

想学深度学习很久了,tensorflow实战框架也买回来了一段时间了,但是由于一直在学其他的东西,就没能学成。恰巧,最近逛各种社区,想着开拓一下思路。于是发现了Kaggle,好似终于找到了把我所正在学的东西和深度学习结合起来的机会。
这篇文章其实是一片随手笔记,是阅读@量化大司马3零基础用TensorFlow玩转Kaggle的“手写识别”的内容随手写下的东西。当然也顺手把代码补全了(敲了好久)。作为这个领域的菜鸟中的菜鸟,希望以后能继续向大佬们学习kaggle和深度学习。
文章还没写完,今天刚把小半部分代码理解完了,但是还有后半部分重要代码还没理解。又是深夜,睡觉去了。明日补。
以下是正文。


概述

MNIST是tensorflow的hello world(简单的Demo)。

Kaggle中的hello world是Digit Recognizer(手写图片识别)。

使用上述两者,上手时间tensorflow和Kaggle是一个不错的选择。

手写图片识别分别的实现分为三步:

  • 数据准备

  • 模型设计

  • 代码实现

数据有Kaggle官方数据,模型使用MNIST Demo中设计的思路。


数据

下载源。

Test——测试数据

28000条数据。每条数据是一个784大小的一维数组。是把一个28*28的图片给扁平化了。

Train——训练数据 + 验证数据

42000条数据。同样每一条数据都是一个一维数组,不过大小是784+1。加的那个1是label。(有监督学习)


一个好的算法都会利用其二维信息,但是鉴于这是一个上手,就先用一维结构进行分析。

显然这个数据集和相似度识别一样都存在同样的问题:采样率不一或者“速度”不一造成的尺度缩放问题。

但是没有噪声和local time shfting(比如缺失点和相等的时间平移)。


模型的设计

模型的组成是这样的:

  • 使用一个最简单的单层神经网络进行学习

  • 使用SoftMax来作为激活函数

  • 使用交叉熵来作为损失函数

  • 使用梯度下降来做优化方式

学习模型、激活函数、损失函数、学习方式这几个要素都是必要的,而这几个要素的实现都选择的最简单的形式。

神经网络

由多个神经元组成。每一个神经元都接收很多的输入:[x1, x2, x3, ..., xn],加权(a),加偏移(b)之后看看是不是超过了某个阈值,超过了发出1,没超过发出0。

单个神经元

由很多个神经元互相连接,形成了神经网络。


单个神经元

激活函数

每个神经元都会输出一个数值,一个神经网络有这么多神经元,最终决定输出那个呢?需要的就是激活函数。其实每一个源的输入都是一个函数,而最终的激活函数就是在做一个规划以达到最好函数:

线性的模型是这样的:


线性模型

非线性的是这样的:

非线性模型

显然,规划就是一个非常重要的课题。在经典教材《算法》中,没有提及规划算法,令很多人感到惋惜,现在终于可以理解原因了。

目前主流的几个激活函数是:sigmoid,tanh,ReLU。

sigmoid:采用S形函数,取值范围[0,1]

tanh:双切正切函数,取值范围[-1,1]

ReLU:简单而粗暴,大于0的留下,否则一律为0。

SoftMax

我们知道max(A,B),�是指A和B里哪个大就取哪个值,但我们有时候希望比较小的那个也有一定概率取到,怎么办呢?我们就按照两个值的大小,计算出概率,按照这个概率来取A或者B。比如A=9,B=1,那取A的概率是90%,取B的概率是10%。

这个看起来比max(A,B)这样粗暴的方式柔和一些,所以叫SoftMax(名字解释纯属个人瞎掰😑大家能理解概念就好)

损失函数

在各种学习算法中,必然要着重讲的就是损失函数和优化方式。

损失函数也相当于相似度预测时候的相似度:表征对数据拟合程度的反映,拟合的越好、损失应该越少。然后我们根据损失函数进行调整。

交叉熵:交叉熵通俗讲就是训练程度和圆满之间的差距,我们希望距离越小越好(= =没看很懂)

优化方式

训练过程是一个逐渐达到收敛的过程,必然需要一个优化方式(要不要损失函数干什么)。

这个概念可以这样理解,我们要解决的问题是一座山,答案在山底,我们从山顶到山底的过程就是解决问题的过程。

在山顶,想找到最快的下山的路。这个时候,我们的做法是什么呢?在每次选择道路的时候,选最陡的那条路。梯度是改变率或者斜度的另一个称呼,用数学的语言解释是导数。对于求损失函数最小值这样的问题,朝着梯度下降的方向走,就能找到最优值了。

梯度下降

代码实现

##############################################
# 载入数据,并对数据进行处理                     #
##############################################

import tensorflow as tf
import pandas as pd
import numpy as np

# 1 加载数据集,把对输入和结果进行分开
filePath = "~/Downloads/"
train = pd.read_csv(filePath + "train.csv")  # train中是仍然包含表头的
images = train.iloc[:, 1:].values  # 删除表头,images是numpy.ndarray
labels_flat = train[["label"]].values.ravel()  # 获取label

# 2 对输出进行处理
images = images.astype(np.float)
images = np.multiply(images, 1.0 / 255.0)  # 转化到256阶的灰度
print('输入数据的数量:(%g, %g)' % images.shape)  # ndarray.shape返回其维度

image_size = images.shape[1]
print('输入数据的纬度 => {0}'.format(image_size))

image_width = image_height = np.ceil(np.sqrt(image_size).astype(np.uint8))
print('图片的长 => {0}\n图片的高 => {1}'.format(image_width, image_height))

x = tf.placeholder('float', shape=[None, image_size])

# 3 对结果进行处理
labels_count = np.unique(labels_flat).shape[0]  # 获取label中不重复的个数,显然是10个:0-9
print('结果的种类 => {0}'.format(labels_count))


# 进行One-hot编码
def dense_to_one_hot(labels_dense, num_classes):
    num_labels = labels_dense.shape[0]
    index_offset = np.arange(num_labels) * num_classes
    labels_one_hot = np.zeros((num_labels, num_classes))
    labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
    return labels_one_hot


labels = dense_to_one_hot(labels_flat, labels_count)
labels = labels.astype(np.uint8)
print(type(labels.shape))
print('结果的数量:({0[0]}, {0[1]})'.format(labels.shape))

y = tf.placeholder('float', shape=[None, labels_count])

# 4 把输入数据划分训练集和验证集
# 把40000个数据作为训练集,2000个数据作为验证集
VALIDATION_SIZE = 2000

validation_images = images[:VALIDATION_SIZE]
validation_labels = labels[:VALIDATION_SIZE]

train_images = images[VALIDATION_SIZE:]
train_labels = labels[VALIDATION_SIZE:]

# 5 对训练集进行分批
batch_size = 100
n_batch = len(train_images)/batch_size
print(n_batch)

##############################################
# 建立神经网路、设置损失函数、设置梯度下降的优化参数 #
##############################################

# 6 设置一个简单的神经网络来对图片进行识别
weight = tf.Variable(tf.zeros([784, 10]))
biases = tf.Variable(tf.zeros([10]))
result = tf.matmul(x, weight) + biases
prediction = tf.nn.softmax(result)

# 7 创建损失函数、以交叉熵的平均值为衡量
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=prediction))

# 8 用梯度下降发优化参数
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

#################################################
# 初始化变量,设置好准确度的计算方法,在Session中运行  #
#################################################

# 9 初始化变量
init = tf.global_variables_initializer()

# 10 计算准确度
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

with tf.Session() as sess:
    # 初始化
    sess.run(init)
    # 循环50轮
    for epoch in range(50):
        for batch in range(int(n_batch)):
            # 按照分片取出数据
            batch_x = train_images[batch * batch_size:(batch + 1)*batch_size]
            batch_y = train_labels[batch * batch_size:(batch + 1) * batch_size]
            # 进行训练
            sess.run(train_step, feed_dict={x:batch_x, y:batch_y})
        # 每一轮计算一次准确度
        accuracy_n = sess.run(accuracy, feed_dict={x:validation_images, y:validation_labels})
        print('第' + str(epoch + 1) + "轮,准确度为:" + str(accuracy_n))

输出:

第1轮,准确度为:0.7925
第2轮,准确度为:0.808
第3轮,准确度为:0.8155
第4轮,准确度为:0.8535
第5轮,准确度为:0.876
第6轮,准确度为:0.8875
第7轮,准确度为:0.8915
第8轮,准确度为:0.895
第9轮,准确度为:0.897
第10轮,准确度为:0.897
第11轮,准确度为:0.899
第12轮,准确度为:0.9005
第13轮,准确度为:0.901
第14轮,准确度为:0.9035
第15轮,准确度为:0.9065
第16轮,准确度为:0.9075
第17轮,准确度为:0.908
第18轮,准确度为:0.909
第19轮,准确度为:0.9105
第20轮,准确度为:0.9105
第21轮,准确度为:0.911
第22轮,准确度为:0.911
第23轮,准确度为:0.9115
第24轮,准确度为:0.912
第25轮,准确度为:0.9125
第26轮,准确度为:0.9135
第27轮,准确度为:0.9135
第28轮,准确度为:0.9135
第29轮,准确度为:0.9135
第30轮,准确度为:0.914
第31轮,准确度为:0.9145
第32轮,准确度为:0.915
第33轮,准确度为:0.915
第34轮,准确度为:0.915
第35轮,准确度为:0.916
第36轮,准确度为:0.917
第37轮,准确度为:0.918
第38轮,准确度为:0.919
第39轮,准确度为:0.919
第40轮,准确度为:0.9195
第41轮,准确度为:0.9195
第42轮,准确度为:0.9195
第43轮,准确度为:0.919
第44轮,准确度为:0.9195
第45轮,准确度为:0.9185
第46轮,准确度为:0.919
第47轮,准确度为:0.919
第48轮,准确度为:0.919
第49轮,准确度为:0.919
第50轮,准确度为:0.9195

Process finished with exit code 0

我们这个网络识别的准确度是92%左右,这个成绩比较差,然而这只是我们最简单的模型而已

相关文章

  • Kaggle-MNIST上手

    想学深度学习很久了,tensorflow实战框架也买回来了一段时间了,但是由于一直在学其他的东西,就没能学成。恰巧...

  • 可用的kaggle-mnist代码

    摸鱼时探索kaggle比赛机制写了一个小代码

  • 上手

    经过近两个月的摸爬滚打,规律是基本上摸到了。只是趋势下的经济,日渐势微的收入,让人心生难受。 养家的男人,就这点收...

  • 上手OpenCV-目录

    全部文章 第一部分 上手OpenCV_GUI-L01-处理图片 上手OpenCV_GUI-L02-视频 上手Ope...

  • 机型判断

    方法 调用 判断是否是6以上手机 判断是否是5以上手机

  • vue

    angular: 国外 上手难 庞大 vue: 国产 上手简单 小巧 下载:1.官网下...

  • Masonry介绍与使用实践:快速上手Autolayout

    Masonry介绍与使用实践:快速上手Autolayout Masonry介绍与使用实践:快速上手Autolayout

  • 软件操作视频如何录制下来?

    网上各种各样的软件都有,有很容易上手的,也有很难上手的,那些很难上手的软件都有操作视频,这些操作视频都是电脑录制的...

  • 线上答题员招募啦,名额有限,赶紧上车

    简单易上手

  • Python-Basic Info

    python上手 python语法入门 python数据分析练习 Conda环境配置:上手实践是王道 c...

网友评论

    本文标题:Kaggle-MNIST上手

    本文链接:https://www.haomeiwen.com/subject/ipxisqtx.html