官网实例详解4.33(mnist_tfrecord.py)-keras学习笔记四

TFRecords格式(标准TensorFlow数据格式)的MNIST数据集


Keras实例目录

代码注释

'''MNIST dataset with TFRecords, the standard TensorFlow data format.
TFRecords格式(标准TensorFlow数据格式)的MNIST数据集
TFRecord is a data format supported throughout TensorFlow.
TFRecord是贯穿TensorFlow的数据格式。
This example demonstrates how to load TFRecord data using
Input Tensors. Input Tensors differ from the normal Keras
workflow because instead of fitting to data loaded into a
a numpy array, data is supplied via a special tensor that
reads data from nodes that are wired directly into model
graph with the `Input(tensor=input_tensor)` parameter.
此示例演示如何使用输入张量加载TFRead数据。输入张量不同于正常的CARAS工作流,因为不是通过加载到一个NUMPY数组中的数据,而
是通过一个特殊的张量来提供数据,该张量从直接连接到模型图的节点中读取数据,并带有“Input(tensor=input_tensor)”参数。

There are several advantages to using Input Tensors.
使用输入张量有几个优点。
First, if a dataset is already in TFRecord format you
can load and train on that data directly in Keras.
首先,如果数据集已经在tfLead格式中可以直接在Keras上加载和训练该数据。
Second, extended backend API capabilities such as TensorFlow
data augmentation is easy to integrate directly into your
Keras training scripts via input tensors.
第二,扩展的后端API能力,如TensorFlow数据增强(扩大样本数量等),很容易通过输入张量直接集成到Keras训练脚本中。
Third, TensorFlow implements several data APIs for
TFRecords, some of which provide significantly faster
training performance than numpy arrays can provide because
they run via the C++ backend. Please note that this
example is tailored for brevity and clarity and not
to demonstrate performance or augmentation capabilities.
第三,TensorFlow为TFRecords实现了多个数据API,其中一些提供了比numpy数组提供的更快的训练性能,因为它们通
过C++后端运行。
请注意,本示例是为了简洁明了而量身定制的,而不是演示性能或增强功能。

Input Tensors also have important disadvantages. In
particular, Input Tensors are fixed at model construction
because rewiring networks is not yet supported.
For this reason, changing the data input source means
model weights must be saved and the model rebuilt
from scratch to connect the new input data.
validation cannot currently be performed as training
progresses, and must be performed after training completes.
This example demonstrates how to train with input
tensors, save the model weights, and then evaluate the
model using the numpy based Keras API.
输入张量也有严重的缺点。特别是,输入张量在模型构造中是固定的,因为还没有支持重新构建网络。
出于这个原因,改变数据输入源意味着模型权重必须被保存,并且从头开始重建该模型以连接新的输入数据。
验证目前不能作为训练中进行,并且必须在训练完成后执行。
这个示例演示了如何用输入张量进行训练,保存模型权重,然后使用基于numpy的Keras API.来评估模型。

Gets to ~99.1% test accuracy after 5 epochs
(high variance from run to run: 98.9-99.3).
5个周期,达到99.1%测试准确率
(98.9-99.3较大的变化)
'''
import numpy as np
import os
import tensorflow as tf
import keras
from keras import backend as K
from keras import layers
from keras.callbacks import Callback

from tensorflow.contrib.learn.python.learn.datasets import mnist

if K.backend() != 'tensorflow':
    raise RuntimeError('This example can only run with the '
                       'TensorFlow backend, '
                       'because it requires TFRecords, which '
                       'are not supported on other platforms.')


class EvaluateInputTensor(Callback):
    """ Validate a model which does not expect external numpy data during training.
    在训练期间验证一个不期望外部numpy数据的模型。

    Keras does not expect external numpy data at training time, and thus cannot
    accept numpy arrays for validation when all of a Keras Model's
    `Input(input_tensor)` layers are provided an  `input_tensor` parameter,
    and the call to `Model.compile(target_tensors)` defines all `target_tensors`.
    Instead, create a second model for validation which is also configured
    with input tensors and add it to the `EvaluateInputTensor` callback
    to perform validation.
    Keras在训练时不期望外部numpy数据,因此不能接受numpy数组进行验证,当所有的Keras模型的“Input(input_tensor)”层都
    提供了一个“input_tensor”参数,并且调用“Model.compile(target_tensors)”定义所有的“target_tensors”。相反,创建
    一个验证的第二个模型,该模型也用输入张量配置,并将其添加到“EvaluateInputTensor”回调以执行验证。

    It is recommended that this callback be the first in the list of callbacks
    because it defines the validation variables required by many other callbacks,
    and Callbacks are made in order.
    建议此回调是回调列表中的第一个,因为它定义了许多其他回调所需的验证变量,并且按顺序进行回调。

    # Arguments
    参数
        model: Keras model on which to call model.evaluate().
        model: Keras模型,通过它调用model.evaluate().函数
        steps: Integer or `None`.
            Total number of steps (batches of samples)
            before declaring the evaluation round finished.
            Ignored with the default value of `None`.
            在评估回合结束之前,步骤总数(批样本)被忽略,默认值为“None”。
    """

    def __init__(self, model, steps, metrics_prefix='val', verbose=1):
        # parameter of callbacks passed during initialization
        # pass evalation mode directly
        # 初始化传递模式中的回调参数
        super(EvaluateInputTensor, self).__init__()
        self.val_model = model
        self.num_steps = steps
        self.verbose = verbose
        self.metrics_prefix = metrics_prefix

    def on_epoch_end(self, epoch, logs={}):
        self.val_model.set_weights(self.model.get_weights())
        results = self.val_model.evaluate(None, None, steps=int(self.num_steps),
                                          verbose=self.verbose)
        metrics_str = '\n'
        for result, name in zip(results, self.val_model.metrics_names):
            metric_name = self.metrics_prefix + '_' + name
            logs[metric_name] = result
            if self.verbose > 0:
                metrics_str = metrics_str + metric_name + ': ' + str(result) + ' '

        if self.verbose > 0:
            print(metrics_str)


def cnn_layers(x_train_input):
    x = layers.Conv2D(32, (3, 3),
                      activation='relu', padding='valid')(x_train_input)
    x = layers.MaxPooling2D(pool_size=(2, 2))(x)
    x = layers.Conv2D(64, (3, 3), activation='relu')(x)
    x = layers.MaxPooling2D(pool_size=(2, 2))(x)
    x = layers.Flatten()(x)
    x = layers.Dense(512, activation='relu')(x)
    x = layers.Dropout(0.5)(x)
    x_train_out = layers.Dense(num_classes,
                               activation='softmax',
                               name='x_train_out')(x)
    return x_train_out

sess = K.get_session()

batch_size = 100
batch_shape = (batch_size, 28, 28, 1)
epochs = 5
num_classes = 10

# The capacity variable controls the maximum queue size
# allowed when prefetching data for training.
# 容量变量控制预取数据用于训练时允许的最大队列大小。
capacity = 10000

# min_after_dequeue is the minimum number elements in the queue
# after a dequeue, which ensures sufficient mixing of elements.
# min_after_dequeue是队列中的最小数量元素,确保元素的充分混合。
min_after_dequeue = 3000

# If `enqueue_many` is `False`, `tensors` is assumed to represent a
# single example.  An input tensor with shape `[x, y, z]` will be output
# as a tensor with shape `[batch_size, x, y, z]`.
# 如果'enqueue_many'是“False”,则假定“张量”代表一个例子。具有形状[x,y,z ]的
# 输入张量将被输出为具有形状的张量[batch_size,X,Y,Z]。
#
# If `enqueue_many` is `True`, `tensors` is assumed to represent a
# batch of examples, where the first dimension is indexed by example,
# and all members of `tensors` should have the same size in the
# first dimension.  If an input tensor has shape `[*, x, y, z]`, the
# output will have shape `[batch_size, x, y, z]`.
# 如果'enqueue_many'是“True”,则假设“tensors”代表一批例子,其中第一个维度通过实例来索
# 引,并且“tensors”的所有成员在第一维中都应该具有相同的大小。如果输入张量具有形状[*,x,y,z ],则
# 输出将具有形状[batch_size,X,Y,Z]。
enqueue_many = True

cache_dir = os.path.expanduser(
    os.path.join('~', '.keras', 'datasets', 'MNIST-data'))
data = mnist.read_data_sets(cache_dir, validation_size=0)

x_train_batch, y_train_batch = tf.train.shuffle_batch(
    tensors=[data.train.images, data.train.labels.astype(np.int32)],
    batch_size=batch_size,
    capacity=capacity,
    min_after_dequeue=min_after_dequeue,
    enqueue_many=enqueue_many,
    num_threads=8)

x_train_batch = tf.cast(x_train_batch, tf.float32)
x_train_batch = tf.reshape(x_train_batch, shape=batch_shape)

y_train_batch = tf.cast(y_train_batch, tf.int32)
y_train_batch = tf.one_hot(y_train_batch, num_classes)

x_batch_shape = x_train_batch.get_shape().as_list()
y_batch_shape = y_train_batch.get_shape().as_list()

model_input = layers.Input(tensor=x_train_batch)
model_output = cnn_layers(model_input)
train_model = keras.models.Model(inputs=model_input, outputs=model_output)

# Pass the target tensor `y_train_batch` to `compile`
# via the `target_tensors` keyword argument:
# 将目标张量“Y-y_train_batch”通过“target_tensors”关键字参数“编译”:
train_model.compile(optimizer=keras.optimizers.RMSprop(lr=2e-3, decay=1e-5),
                    loss='categorical_crossentropy',
                    metrics=['accuracy'],
                    target_tensors=[y_train_batch])
train_model.summary()

x_test_batch, y_test_batch = tf.train.batch(
    tensors=[data.test.images, data.test.labels.astype(np.int32)],
    batch_size=batch_size,
    capacity=capacity,
    enqueue_many=enqueue_many,
    num_threads=8)

# Create a separate test model
# to perform validation during training
# 创建一个单独的测试模型在训练中进行验证
x_test_batch = tf.cast(x_test_batch, tf.float32)
x_test_batch = tf.reshape(x_test_batch, shape=batch_shape)

y_test_batch = tf.cast(y_test_batch, tf.int32)
y_test_batch = tf.one_hot(y_test_batch, num_classes)

x_test_batch_shape = x_test_batch.get_shape().as_list()
y_test_batch_shape = y_test_batch.get_shape().as_list()

test_model_input = layers.Input(tensor=x_test_batch)
test_model_output = cnn_layers(test_model_input)
test_model = keras.models.Model(inputs=test_model_input, outputs=test_model_output)

# Pass the target tensor `y_test_batch` to `compile`
# via the `target_tensors` keyword argument:
# 将目标张量'y_test_batch'通过'target_tensors'关键字参数传递到“编译”:
test_model.compile(optimizer=keras.optimizers.RMSprop(lr=2e-3, decay=1e-5),
                   loss='categorical_crossentropy',
                   metrics=['accuracy'],
                   target_tensors=[y_test_batch])

# Fit the model using data from the TFRecord data tensors.
# 使用TFRecord数据张量适配模型
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess, coord)

train_model.fit(epochs=epochs,
                steps_per_epoch=int(np.ceil(data.train.num_examples / float(batch_size))),
                callbacks=[EvaluateInputTensor(test_model, steps=100)])

# Save the model weights.
# 保存模型权重
train_model.save_weights('saved_wt.h5')

# Clean up the TF session.
# 清理TF会话
coord.request_stop()
coord.join(threads)
K.clear_session()

# Second Session to test loading trained model without tensors
# 第二个会话,测试没有张量加载训练模型
x_test = np.reshape(data.test.images, (data.test.images.shape[0], 28, 28, 1))
y_test = data.test.labels
x_test_inp = layers.Input(shape=(x_test.shape[1:]))
test_out = cnn_layers(x_test_inp)
test_model = keras.models.Model(inputs=x_test_inp, outputs=test_out)

test_model.load_weights('saved_wt.h5')
test_model.compile(optimizer='rmsprop',
                   loss='categorical_crossentropy',
                   metrics=['accuracy'])
test_model.summary()

loss, acc = test_model.evaluate(x_test,
                                keras.utils.to_categorical(y_test),
                                batch_size=batch_size)
print('\nTest accuracy: {0}'.format(acc))

代码执行

 

Keras详细介绍

英文:https://keras.io/

中文:http://keras-cn.readthedocs.io/en/latest/

实例下载

https://github.com/keras-team/keras

https://github.com/keras-team/keras/tree/master/examples

完整项目下载

方便没积分童鞋,请加企鹅452205574,共享文件夹。

包括:代码、数据集合(图片)、已生成model、安装库文件等。

猜你喜欢

转载自blog.csdn.net/wyx100/article/details/80851276
今日推荐