Keras学习(一)MNIST 识别---DNN 实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hoho1151191150/article/details/79850452

【本系列博文是学习 Keras 的笔记,Keras 版本为2.1.5,主要的参考资料为:Keras中文文档
我们直接从一个简单的 DNN MNIST 的例子开始学习,程序代码来自于 Keras 的 examples 中的 mnist_mlp.py

这个例子非常简单,我们只实现一个具有 Dropout 层的 DNN。

网络的建立和训练

首先载入模块相关的模块:Sequential,用以生成我们的 model, 我们只要向这个 model 中 add 不同的层就可以构建我们的网络;Dense,全连接层;Dropout,Dropout 层;optimizers是优化器。

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
import numpy as np

现在准备载入数据,如果第一次运行需下载 MNIST 数据:

from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

mnist.load_data会将数据缓存起来,为了多次使用定义如下函数:

def load_mnist_data(path):
    f = np.load(path)
    x_train, y_train = f['x_train'], f['y_train']
    x_test, y_test = f['x_test'], f['y_test']
    f.close()
    return (x_train, y_train), (x_test, y_test)

然后加载数据

(x_train, y_train), (x_test, y_test) = load_mnist_data(path = 'mnist.npz')

数据加载后,需要对数据进行一点处理,原始数据是 unit8 格式的,并且 label 是标量值,我们需要将其转换为 one-hot 的编码格式

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

#将标量的标签转换为 one-hot 编码
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

下面建立网络,该模型有两个全连接层,均含有512个神经元,激活函数为ReLU,全连接层后有池化层

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))   # 0.2是神经元舍弃比
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation = 'softmax'))

model.summary()

summary()显示网络层次
这里写图片描述
上面仅仅是网络的定义,定义了各个变量、层之间的计算关系。建立好的计算图需要编译以确定其内部细节,然而,此时的计算图还是一个“空壳子”,里面没有任何实际的数据,只有当你把需要运算的输入放进去后,才能在整个模型中形成数据流,从而形成输出值。下面是计算图的编译

model.compile(loss = 'categorical_crossentropy',
              optimizer = RMSprop(),
              metrics = ['accuracy'])

compile()有两个必须参数,loss 和 optimizer。loss 为损失函数,或称为目标函数,可以通过传递预定义的目标函数名称确定 loss 的形式,可用的损失函数有:

  • mean_squard_error 或 mse
  • mean_absolute_error 或 mae
  • mean_absolute_percentage_error 或 mape
  • mean_squard_logarithmic_error 或 msle
  • binary_crossentropy 对数损失函数
  • categorical_crossentropy, 多类的对数损失函数,注意,使用该函数时,需要将标签转换为形如(samples,class)的二值序列,标签是 one-hot 编码模式,标量值可用 to_categorical() 函数转换
  • … …

loss也可以是指定的目标函数,比如 loss = keras.losses.categorical_crossentropy()

loss 参数也可以传递一个 Theano/TensorFlow 的符号函数作为目标函数,该函数对每个数据应只返回一个标量值,并以下列两个参数名为参数:y_true(第一参数)和 y_pred(第二参数)

optimizer 也是 compile() 必须的参数。同样的,optimizer 可以接受预定义的函数名称或者是函数,比如 optimizer = ’sgd’, 或者 optimizer = keras.optimizer.RMSprop()。optimizer 的种类详见Keras中文文档。接下来,我们就可以训练这个网络了,Keras 训练网络非常简单,

history = model.fit(x_train, y_train,
                    batch_size = batch_size,
                    epochs = epochs,
                    #0,不显示,1,进度条,2,文字
                    verbose = 1, 
                    validation_data = (x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

网络的训练利用 fit 函数实现,这个网络的在 20 个 epoch 的识别率在 98.3% 左右。

网络的保存和载入

网络的保存和载入十分简单。我们可以使用 model.save(filepath) 将 Keras 模型和权重保存在一个HDF5文件中,该文件将包含:

  • 模型的结构,以便重构该模型
  • 模型的权重
  • 训练配置(损失函数,优化器等)
  • 优化器的状态,以便于从上次训练中断的地方开始

使用 keras.models.load_model(filepath) 来重新实例化你的模型,如果文件中存储了训练配置的话,该函数还会同时完成模型的编译。如果你只是希望保存模型的结构,而不包含其权重或配置信息,可以使用:

# save as JSON
json_string = model.to_json()

# save as YAML
yaml_string = model.to_yaml()

这项操作将把模型序列化为 json 或 yaml 文件,如果需要的话我们甚至可以手动打开这些文件并进行编辑。当然,我们也可以从保存好的 json 文件或 yaml 文件中载入模型:

# model reconstruction from JSON:
from keras.models import model_from_json
model = model_from_json(json_string)

# model reconstruction from YAML
model = model_from_yaml(yaml_string)

我们也可以只保存模型的权重,可通过下面的代码利用 HDF5 进行保存。注意,在使用前需要确保你已安装了 HDF5 和其 Python 库 h5py

model.save_weights('my_model_weights.h5')
model.load_weights('my_model_weights.h5')

网络结构绘制

网络结构绘制,需要使用 keras.utils 中的 plot_model 函数,plot_model 依赖 pydot(或者pydot_ng, plot_model 的源文件将 pydot_ng 作为首先) 和 graphviz 两个包。但是即使安装了这两个包,仍然会出现’ Failed to import pydot. You must install pydot and graphviz for pydotprint to work.'的提示,原因是在 plot_model 中有一步 try…except… 的语句去测试 pydot。

实际的错误应该是'GraphViz's executables not found'。那么我们需要安装GraphViz,博主下载的是 GraphViz2.38.msi, 安装完成后,添加了PATH环境变量,但是还是出错了。

无奈只能对 pydot_ng 的源文件进行修改,打开 YOURPATH\Lib\site-packages\pydot_ng 中的 init.py, 找到 find_graphviz() 函数,这个函数会尝试几种搜寻方式寻找 GraphViz,最容易修改的是第三种方式,直接将 Method3 中 if…else… 段设置为 path = r”C:\Program Files (x86)\Graphviz2.38\bin”,后面是我安装的 Graphviz 的路径。然后就OK了。

from keras.utils import plot_model
plot_model(model,'MNIST_MLP_TB.png',show_shapes =True,rankdir = 'TB')
plot_model(model,'MNIST_MLP_LR.png',show_shapes =True,rankdir = 'LR')

‘TB’模式的网络结果图,vertical plot


这里写图片描述

‘LR’模式的网络结果图,horizontal plot


这里写图片描述

猜你喜欢

转载自blog.csdn.net/hoho1151191150/article/details/79850452
今日推荐