利用keras进行分类

Classifier

做classifier的时候,本来是按照莫烦的教程一步一步做的,但是总是在mnist.load_data这部分出错,说是无法链接到https://s3.amazonaws.com/img-datasets/mnist.npz,我上网也找了一些解决方案都不行。然后我看到程序上有说明:

第一次运行的时候,会在https://s3.amazonaws.com/img-datasets/mnist.npz下载数据集到~/.keras/datasets,而第二次运行的时候直接就开始执行,不会再下载一次。

于是,我就打算直接在https://s3.amazonaws.com/img-datasets/mnist.npz网址上下好,放到datasets文件夹下不就好了。

果然,这个方法是可行的。但是,运行莫烦教程上给出的程序时,准确率只有0.4,这实在不科学。然后我就想找出问题。悲剧发生了……我不知道动了哪里,就一直numpy这个包import不了,,,好气哦。没办法,只好卸载重装,好在只是keras有问题。

pip uninstall keras
pip install keras

重装过后,果然好了,然后又出现一个this file is not a zipfile的一个bug,我就又无奈了。。。找了一通也没找到解决方案,于是我就重新到https://s3.amazonaws.com/img-datasets/mnist.npz下载了数据集,然后也换了一套代码,用的是官方文档给的mnist_mlp的例子重新训练https://github.com/fchollet/keras/blob/master/examples/mnist_mlp.py

终于可以运行了,结果可以达到98.38%

附上代码

#!/usr/bin/python
# -*- coding:utf8 -*-
'''
Trains a simple deep NN on the MNIST dataset.
Gets to 98.40% test accuracy after 20 epochs
(there is *a lot* of margin for parameter tuning).
2 seconds per epoch on a K520 GPU.
'''



from __future__ import print_function  #使python2.7可以使用print函数形式

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop


batch_size = 128
num_classes = 10
epochs = 20

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255  #输入的 x 变成 60,000*784 的数据,然后除以 255 进行标准化,因为每个像素都是在 0 到 255 之间的,标准化之后就变成了 0 到 1 之间
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes) #把 y 变成了 one-hot 的形式,即之前 y 是一个数值, 在 0-9 之间,现在是一个大小为 10 的向量,它属于哪个数字,就在哪个位置为 1,其他位置都是 0
y_test = keras.utils.to_categorical(y_test, num_classes)


# build the neural net
model = Sequential()  #序贯式模型
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2)) #防止过拟合,每次更新参数时随机断开一定百分比(rate)的输入神经元
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))

model.summary() #打印出模型概况


# compile the model
model.compile(loss='categorical_crossentropy', # 对数损失
              optimizer=RMSprop(),
              metrics=['accuracy'])


# train the model
history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1, #日志显示
                    validation_data=(x_test, y_test))   #fit将模型训练epochs轮


# test the model
score = model.evaluate(x_test, y_test, verbose=0) #evaluate函数按batch计算在某些输入数据上模型的误差
print('Test loss:', score[0])
print('Test accuracy:', score[1])

利用keras进行分类_第1张图片

这里写图片描述

转载一些基础知识

符号计算

Keras的底层库使用Theano或TensorFlow,这两个库也称为Keras的后端,无论事Theano还是TensorFlow,都是一个符号主义的库。
关于符号主义,可以一般概括为这种说法:符号主义的计算首先定义各种变量,然后建立一个“计算图”,计算图规定了各个变量之间的计算关系。建立好的计算图需要编译已确定其内部细节,然而,此时的计算图还是一个“空壳子”,里面没有任何实际的数据,只有当你把需要运算的输入放进去后,才能在整个模型中形成数据流,从而形成输出值。
Keras的模型搭建形式就是这种方法,在你搭建Keras模型完毕后,你的模型就是一个空壳子,只有实际生成可调用的函数后(K.function),输入数据,才会形成真正的数据流。
使用计算图的语言,如Theano,以难以调试而闻名,当Keras的Debug进入Theano这个层次时,往往也令人头痛。没有经验的开发者很难直观的感受到计算图到底在干些什么。尽管很让人头痛,但大多数的深度学习框架使用的都是符号计算这一套方法,因为符号计算能够提供关键的计算优化、自动求导等功能。

张量

前面的概念中提到并解释了这个词,该词本身还是兼具多个学科的,而这里的用到的相对来说较简单一些。
张量,或tensor,是本文档会经常出现的一个词汇,在此稍作解释。
使用这个词汇的目的是为了表述统一,张量可以看作是向量、矩阵的自然推广,我们用张量来表示广泛的数据类型。
规模最小的张量是0阶张量,即标量,也就是一个数。
当我们把一些数有序的排列起来,就形成了1阶张量,也就是一个向量
如果我们继续把一组向量有序的排列起来,就形成了2阶张量,也就是一个矩阵
把矩阵摞起来,就是3阶张量,我们可以称为一个立方体,具有3个颜色通道的彩色图片就是一个这样的立方体
把矩阵摞起来,好吧这次我们真的没有给它起别名了,就叫4阶张量了,不要去试图想像4阶张量是什么样子,它就是个数学上的概念。

‘th’与’tf

‘th’模式,也即Theano模式会把100张RGB三通道的16×32(高为16宽为32)彩色图表示为下面这种形式(100,3,16,32),Caffe采取的也是这种方式。第0个维度是样本维,代表样本的数目,第1个维度是通道维,代表颜色通道数。后面两个就是高和宽了。
而TensorFlow,即‘tf’模式的表达形式是(100,16,32,3),即把通道维放在了最后。这两个表达方法本质上没有什么区别。

泛型模型

在原本的Keras版本中,模型其实有两种,一种叫Sequential,称为序贯模型,也就是单输入单输出,一条路通到底,层与层之间只有相邻关系,跨层连接统统没有。这种模型编译速度快,操作上也比较简单。第二种模型称为Graph,即图模型,这个模型支持多输入多输出,层与层之间想怎么连怎么连,但是编译速度慢。可以看到,Sequential其实是Graph的一个特殊情况。
在现在这版Keras中,图模型被移除,而增加了了“functional model API”,这个东西,更加强调了Sequential是特殊情况这一点。一般的模型就称为Model,然后如果你要用简单的Sequential,OK,那还有一个快捷方式Sequential。
由于functional model API表达的是“一般的模型”这个概念,我们将其译为泛型模型,即只要这个东西接收一个或一些张量作为输入,然后输出的也是一个或一些张,不管它是什么鬼。统统都称作“模型”。

Batch

其实我之前看到这个参数设置的时候,一直没搞懂,今天来整理一下吧。
这词设计到训练过程中如何优化,嘿嘿,那就提到了深度学习的优化算法,说白了就是梯度下降。每次的参数更新有两种方式。
第一种,遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的所有样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为Batch gradient descent,批梯度下降。
另一种,每看一个数据就算一下损失函数,然后求梯度更新参数,这个称为随机梯度下降,stochastic gradient descent。这个方法速度比较快,但是收敛性能不太好,可能在最优点附近晃来晃去,hit不到最优点。两次参数的更新也有可能互相抵消掉,造成目标函数震荡的比较剧烈。
为了克服两种方法的缺点,现在一般采用的是一种折中手段,mini-batch gradient decent,小批的梯度下降,这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。另一方面因为批的样本数与整个数据集相比小了很多,计算量也不是很大。
基本上现在的梯度下降都是基于mini-batch的,所以Keras的模块中经常会出现batch_size,就是指这个。
顺便说一句,Keras中用的优化器SGD是stochastic gradient descent的缩写,但不代表是一个样本就更新一回,还是基于mini-batch的。

转载来源:http://blog.csdn.net/u011437229/article/details/53464213

你可能感兴趣的:(机器学习)