Tensorflow_08B_Keras 的 Function 模型与训练结果的储存方法

Brief 概述

从上一章节的范例中我们成功使用 Keras 搭建全联接神经网络和卷积神经网络,并分别使用此二网络对最基础的两个数据集 MNIST 与 CIFAR10 做分类,旨在让大家了解到使用 Keras 搭建神经网络的简洁性和人性化的一面。

Keras 从本来独立发展的第三方模块,到后来被 Tensorflow 认可后在随后的 tf 升级版本中被纳入 tf 的高级 API 行列中,确实证明了其设计理念的合理性和必要性,让建构神经网络的知识门槛降低,更多人将能够通过此 API 入手亲自搭建神经网络。

继续上节的介绍,完整了解了 Sequential 的搭建方式之后,接下来将要使用第二种搭建方式 Functional 方法,他们的功能一模一样,为什么要学两种的理由将在模型的储存中跟大家说明。

p.s. 点击此 进入 keras 官网,点击此 进入 keras 的 GitHub 源代码。

 

Import Data 导入数据

构建神经网络之前,最重要的还是数据本身,而这里将继续沿用前面面几个章节中所使用的两个模型 MNIST 与 CIFAR10,和与其对应的函数代码,并简单打印出引入数据集图像对应标签的结果。

import gzip
from Code_Session.TF_04 import mnist as M
import pickle
from Code_Session.TF_05 import cifar2cnn as cc

MNIST Dataset

path_mnist = '/Users/kcl/Documents/Python_Projects/01_AI_Tutorials/_2_Image_Datasets/MNIST_data'
mnist = M.MNIST(val_ratio=0.0, data_dir=path_mnist)
print(mnist.img_train.shape)
(60000, 784)
mnist_img_train = M.format_images(mnist.img_train)
mnist_lab_train = mnist.lab_train
mnist_cls_name = [i for i in range(10)]
cc.plot_images(mnist_img_train, mnist.lab_train, mnist_cls_name, size=[3, 4])

 

CIFAR10 Dataset

path_cifar = '/Users/kcl/Documents/Python_Projects/cifar-10-batches-py'
img_train = cc.merge_batches('data', file_dir=path_cifar)
print(img_train.shape)
(50000, 3072)
file_dir = path_cifar + '/' + 'batches.meta'
def get_class_name(file_dir=file_dir):
    with open(file_dir, 'rb') as file:
        dic = pickle.load(file, encoding='bytes')
    return [w.decode('utf-8') for w in dic[b'label_names']]
cifar_img_train = cc.format_images(img_train)
cifar_lab_train = cc.merge_batches('labels', file_dir=path_cifar)
cc.plot_images(cifar_img_train, cifar_lab_train, 
               get_class_name(), size=[3, 4])

 

p.s. 如果对其中的代码有任何不熟悉,请详见前面几回合的内容。

接下来就可以从 Tensorflow 模块中呼叫 keras 搭建一个非常迅捷且轻便的神经网络模型。类似 keras 的 API 模块也有 PrettyTensor 与 layers,不过从 Tensorflow 官网的态度来看,它很可能将在未来被删减,而主推 keras,同时很多更新的功能 keras 也持续同步着,是一个相对稳健的高级 API,故值得一探究竟。

 

2. Functional Model

跟 Sequential 模式比起来,Functional 模式在建构神经网络上的意思也是相近的,不过差别在于它的构建方式如同函数呼叫一般的使用,首先引入需要用到的模块:

import numpy as np
import tensorflow as tf
import tensorflow.keras as K

mnist_img_size = 28
cifar_img_size = 32

2-1. Model Construction

每层用来构建神经网络的函数,在 Keras 中在还没有被指向一个对象之前,都可以作为一个新的函数本身,让其后面加上一对 () 传入参数至其中,直接开始新一轮的计算,代码如下:

### When taking MNIST as input, define the shape of (28, 28, 1)
inputs = K.layers.Input(shape=(mnist_img_size, mnist_img_size, 1))

### When taking CIFAR as input, define the shape of (32, 32, 3)
# inputs = K.layers.Input(shape=(cifar_img_size, cifar_img_size, 3))

# ----------------------------------------------------------------------

# Construct the structure using Functionnal Model from now
net = inputs

net = K.layers.Conv2D(kernel_size=5, strides=1, filters=16, padding='same',
                      activation='relu', name='layer1')(net)
net = K.layers.MaxPooling2D(pool_size=2, strides=2)(net)
net = K.layers.BatchNormalization()(net)

net = K.layers.Conv2D(kernel_size=5, strides=1, filters=36, padding='same',
                      activation='relu', name='layer2')(net)
net = K.layers.MaxPooling2D(pool_size=2, strides=2)(net)
net = K.layers.BatchNormalization()(net)

# Fully connected part
net = K.layers.Flatten()(net)
net = K.layers.Dense(units=128, activation='relu')(net)
net = K.layers.Dense(units=10, activation='softmax')(net)

outputs = net

# ----------------------------------------------------------------------

# Compile the structure into a Model
func_model = K.models.Model(inputs=inputs, outputs=outputs)
func_model.compile(optimizer='rmsprop',
                   loss='categorical_crossentropy',
                   metrics=['accuracy'])

2-2. Train Model

与 Sequential 的操作流程一般,根据需要使用的函数模型来执行代码,其他的标注起来不启动。

### Train the model using MNIST:
func_model.fit(x=mnist_img_train.reshape([-1, 28, 28, 1]),
               y=cc.one_hot(mnist.lab_train),
               epochs=2, batch_size=128)

### Train the model using CIFAR10:
# func_model.fit(x=cifar_img_train, 
#                y=cc.one_hot(cifar_lab_train),
#                epochs=3, batch_size=128)
Epoch 1/2
60000/60000 [==============================] - 83s 1ms/step - loss: 0.1151 - acc: 0.9657
Epoch 2/2
60000/60000 [==============================] - 79s 1ms/step - loss: 0.0371 - acc: 0.9891

2-3. Evaluate Model

训练完的模型,使用下面的方法开启测试集,测试结果。

### Evaluate Model using MNIST:
mnist_loss, mnist_acc = func_model.evaluate(mnist.img_test.reshape([-1, 28, 28, 1]), 
                                            cc.one_hot(mnist.lab_test))
print('The loss value: {}'.format(mnist_loss))
print('The accuracy: {}'.format(mnist_acc))

# ----------------------------------------------------------------------

### Evaluate Model using CIFAR10:
# cifar_img_test = cc.format_images(cc.load_binary_data(
#     'test_batch', 'data', file_dir=path_cifar) / 255.0)
# cifar_lab_test = cc.one_hot(cc.load_binary_data(
#     'test_batch', 'labels', file_dir=path_cifar).astype(np.int))

# cifar_loss, cifar_acc = func_model.evaluate(cifar_img_test, cifar_lab_test)
# print('The loss value: {}'.format(cifar_loss))
# print('The accuracy: {}'.format(cifar_acc))
10000/10000 [==============================] - 6s 634us/step
The loss value: 0.03831068623477895
The accuracy: 0.9879

 

Save and Restore Training Results

储存的记录点是我们在做事情的时候非常重要的辅助工具,训练模型的过程当然也需要这项功能。然而如果回顾前面使用 Tensorflow 储存成 checkpoint 与重新呼叫储存参数的方式,非得有几次函数调用的过程才能够完成存档,设计的逻辑并不怎么人性化,是一个比较繁琐的过程。

而 Keras 的储存方式被设计得非常人性化,容易理解之外也容易操作,然而一个深度学习框架有两个部分组成,分别是运算结构与被运算的参数,因此也衍生出两种主要的思路用来储存训练结果: 

  1. 整体储存整体载入
  2. 分开储存分开载入

Crutial Note:

ValueError: You are trying to load a weight file containing N layers into a model with M layers. 是一个版本更新的问题,普遍出现在 Keras 2.X 的版本中,如果使用了此系列版本的人想避开这个问题的话,换成 Functional Model 来搭建自己的神经网络框架之后则能够解决问题。

有些 Keras 版本里面,只有 Functional Model 可以顺利把储存好的模型和训练参数重新呼叫回模型内,因此 Functional Model 在储存这点上是比 Sequential 设计来的完备的。

 

1. Save and Load The Model as One Piece 整体储存与载入

储存与载入的过程一共各一行代码即完成所有的工作,储存方式如下:

func_model.save('save.h5')

# In order to save the RAM space, we can delete the useless object
del func_model

重新载入回整个框架与参数的方式如下:

new_model = K.models.load_model('save.h5')

执行完毕后, new_model 对象即附有完整的神经网络框架功能,并执行预测等计算。

 

2. Save and Load The Model Separately 分开储存与载入

在 Keras 中,框架的保存使用 json 形式完成,数据的保存使用 save_weights() 函数实现,保存方式如下代码:

func_model.save_weights('save_weights.h5')

model_json = func_model.to_json()
# print(model_json)

with open('model.json', 'w') as file:
    file.write(model_json)

重新唤回模型之后,就可以使用 load_weights() 函数把参数完整叫回来,继续上次训练结果开始预估新的数据。

with open('model.json', 'r') as file:
    json_string = file.read()
    
# print(json_string)
new_model = K.models.model_from_json(json_string)
new_model.load_weights('save_weights.h5')

接着还有一段续集,将主要描述如何使用 Keras 开启可视化好帮手 "Tensorboard",与如何使用数据增强,适当且简单的改变图片的性质。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值