MNIST代码总结

  • Post author:
  • Post category:其他


import matplotlib.pyplot as plt

import tensorflow as tf

import numpy as np

import math

# from tf.keras.models import Sequential  # This does not work!

from tensorflow.python.keras.models import Sequential

from tensorflow.python.keras.layers import InputLayer, Input

from tensorflow.python.keras.layers import Reshape, MaxPooling2D

from tensorflow.python.keras.layers import Conv2D, Dense, Flatten

from mnist import MNIST

data = MNIST(data_dir=”data/MNIST/”)

print(“Size of:”)

print(“- Training-set:\t\t{}”.format(data.num_train))

print(“- Validation-set:\t{}”.format(data.num_val))

print(“- Test-set:\t\t{}”.format(data.num_test))


# The number of pixels in each dimension of an image.

img_size = data.img_size

# The images are stored in one-dimensional arrays of this length.

img_size_flat = data.img_size_flat

# Tuple with height and width of images used to reshape arrays.

img_shape = data.img_shape

# Tuple with height, width and depth used to reshape arrays.

# This is used for reshaping in Keras.

img_shape_full = data.img_shape_full

# Number of classes, one class for each of 10 digits.

num_classes = data.num_classes

# Number of colour channels for the images: 1 channel for gray-scale.

num_channels = data.num_channels

def plot_images(images, cls_true, cls_pred=None):

assert len(images) == len(cls_true) == 9   # 判断输入参数是否符合要求,cls_true是true classes

# Create figure with 3×3 sub-plots.

#轴域(Axes)的感念确实可以先理解成一些轴(Axis)的集合,当然这个集合还有很多轴(Axis)的属性,标注等等

fig, axes = plt.subplots(3, 3)

fig.subplots_adjust(hspace=0.3, wspace=0.3)


for i, ax in enumerate(axes.flat):

# Plot image.

ax.imshow(images[i].reshape(img_shape), cmap=’binary’) #Map,计算机语言函数,作用是映射的关键码。

# Show true and predicted classes.

if cls_pred is None:

xlabel = “True: {0}”.format(cls_true[i])

else:

xlabel = “True: {0}, Pred: {1}”.format(cls_true[i], cls_pred[i])

# Show the classes as the label on the x-axis.

ax.set_xlabel(xlabel)

# Remove ticks from the plot.

ax.set_xticks([])

ax.set_yticks([])

# Ensure the plot is shown correctly with multiple plots

# in a single Notebook cell.

#plt.imshow()函数负责对图像进行处理,并显示其格式,而plt.show()则是将plt.imshow()处理后的函数显示出来

plt.show()

# Get the first images from the test-set.

images = data.x_test[0:9]

# Get the true classes for those images.

cls_true = data.y_test_cls[0:9]

# Plot the images and labels using our helper-function above.

plot_images(images=images, cls_true=cls_true)

# Helper-function to plot example errors

def plot_example_errors(cls_pred):

# cls_pred is an array of the predicted class-number for

# all images in the test-set.

# Boolean array whether the predicted class is incorrect.

incorrect = (cls_pred != data.y_test_cls)

# Get the images from the test-set that have been

# incorrectly classified.

images = data.x_test[incorrect]

# Get the predicted classes for those images.

cls_pred = cls_pred[incorrect]

# Get the true classes for those images.

cls_true = data.y_test_cls[incorrect]

# Plot the first 9 images.

plot_images(images=images[0:9],

cls_true=cls_true[0:9],

cls_pred=cls_pred[0:9])


#Sequential Model

#The Keras API has two modes of constructing Neural Networks. The simplest is the Sequential Model which only allows for the layers to be added in sequence.

# Start construction of the Keras Sequential model.

model = Sequential()

# Add an input layer which is similar to a feed_dict in TensorFlow.

# Note that the input-shape must be a tuple containing the image-size.

model.add(InputLayer(input_shape=(img_size_flat,)))

# The input is a flattened array with 784 elements,

# but the convolutional layers expect images with shape (28, 28, 1)

model.add(Reshape(img_shape_full))

# First convolutional layer with ReLU-activation and max-pooling.

#如果padding设置为SAME,则说明输入图片大小和输出图片大小是一致的

model.add(Conv2D(kernel_size=5, strides=1, filters=16, padding=’same’,

activation=’relu’, name=’layer_conv1′))

model.add(MaxPooling2D(pool_size=2, strides=2))

# Second convolutional layer with ReLU-activation and max-pooling.

model.add(Conv2D(kernel_size=5, strides=1, filters=36, padding=’same’,

activation=’relu’, name=’layer_conv2′))

model.add(MaxPooling2D(pool_size=2, strides=2))

# Flatten the 4-rank output of the convolutional layers

# to 2-rank that can be input to a fully-connected / dense layer.

model.add(Flatten())

# First fully-connected / dense layer with ReLU-activation.

model.add(Dense(128, activation=’relu’))

# Last fully-connected / dense layer with softmax-activation

# for use in classification.

model.add(Dense(num_classes, activation=’softmax’))

# Model Compilation

# The Neural Network has now been defined and must be finalized by adding a loss-function, optimizer and performance metrics. This is called model “compilation” in Keras.

# We can either define the optimizer using a string, or if we want more control of its parameters then we need to instantiate an object. For example, we can set the learning-rate.

from tensorflow.python.keras.optimizers import Adam

#Adam这个算法是另一种计算每个参数的自适应学习率的方法

optimizer = Adam(lr=1e-3)

#For a classification-problem such as MNIST which has 10 possible classes, we need to use the loss-function called categorical_crossentropy. The performance metric we are interested in is the classification accuracy.

model.compile(optimizer=optimizer,

loss=’categorical_crossentropy’,

metrics=[‘accuracy’])


#Training

#Now that the model has been fully defined with loss-function and optimizer, we can train it. This function takes numpy-arrays and performs the given number of training epochs using the given batch-size. An epoch is one full use of the entire training-set. So for 10 epochs we would iterate randomly over the entire training-set 10 times.

model.fit(x=data.x_train,

y=data.y_train,

epochs=1, batch_size=128)

# Evaluation

result = model.evaluate(x=data.x_test,

y=data.y_test)

# We can print all the performance metrics for the test-set

# for a,b in zip(A,B)  ,这道题里面A是rang(1,len(L)+1),B是L,这样赋值的时候就一一对应,A赋值给a,B赋值给b。

for name, value in zip(model.metrics_names, result):

print(name, value)

# Or we can just print the classification accuracy.

print(“{0}: {1:.2%}”.format(model.metrics_names[1], result[1]))

# Prediction

# We can also predict the classification for new images. We will just use some images from the test-set but you could load your own images into numpy arrays and use those instead.

images = data.x_test[0:9]

#These are the true class-number for those images. This is only used when plotting the images.

cls_true = data.y_test_cls[0:9]

# Get the predicted classes as One-Hot encoded arrays.

y_pred = model.predict(x=images)

# Get the predicted classes as integers.将预测的类别由独热编码转换成整数形式

cls_pred = np.argmax(y_pred, axis=1)

plot_images(images=images,

cls_true=cls_true,

cls_pred=cls_pred)

# Examples of Mis-Classified Images

# We can plot some examples of mis-classified images from the test-set.

# First we get the predicted classes for all the images in the test-set:

y_pred = model.predict(x=data.x_test)

# Then we convert the predicted class-numbers from One-Hot encoded arrays to integers.

# numpy.argmax(a, axis=None, out=None),Returns the indices of the maximum values along an axis.

cls_pred = np.argmax(y_pred, axis=1)

# Plot some of the mis-classified images

plot_example_errors(cls_pred)

# Functional Model

# The Keras API can also be used to construct more complicated networks using the Functional Model. This may look a little confusing at first, because each call to the Keras API will create and return an instance that is itself callable. It is not clear whether it is a function or an object – but we can call it as if it is a function. This allows us to build computational graphs that are more complex than the Sequential Model allows.

# Create an input layer which is similar to a feed_dict in TensorFlow.

# Note that the input-shape must be a tuple containing the image-size.

inputs = Input(shape=(img_size_flat,))

# Variable used for building the Neural Network.

net = inputs

# The input is an image as a flattened array with 784 elements.

# But the convolutional layers expect images with shape (28, 28, 1)

net = Reshape(img_shape_full)(net)

# First convolutional layer with ReLU-activation and max-pooling.

net = Conv2D(kernel_size=5, strides=1, filters=16, padding=’same’,

activation=’relu’, name=’layer_conv1′)(net)

net = MaxPooling2D(pool_size=2, strides=2)(net)

# Second convolutional layer with ReLU-activation and max-pooling.

net = Conv2D(kernel_size=5, strides=1, filters=36, padding=’same’,

activation=’relu’, name=’layer_conv2′)(net)

net = MaxPooling2D(pool_size=2, strides=2)(net)

# Flatten the output of the conv-layer from 4-dim to 2-dim.

net = Flatten()(net)

# First fully-connected / dense layer with ReLU-activation.

net = Dense(128, activation=’relu’)(net)

# Last fully-connected / dense layer with softmax-activation

# so it can be used for classification.

net = Dense(num_classes, activation=’softmax’)(net)

# Output of the Neural Network.

outputs = net

# Model Compilation

# We have now defined the architecture of the model with its input and output. We now have to create a Keras model and compile it with a loss-function and optimizer, so it is ready for training.

from tensorflow.python.keras.models import Model

# Create a new instance of the Keras Functional Model. We give it the inputs and outputs of the Convolutional Neural Network that we constructed above.

model2 = Model(inputs=inputs, outputs=outputs)

# Compile the Keras model using the RMSprop optimizer and with a loss-function for multiple categories. The only performance metric we are interested in is the classification accuracy, but you could use a list of metrics here.

model2.compile(optimizer=’rmsprop’,

loss=’categorical_crossentropy’,

metrics=[‘accuracy’])

# Training

# The model has now been defined and compiled so it can be trained using the same fit() function as used in the Sequential Model above. This also takes numpy-arrays as input.

model2.fit(x=data.x_train,

y=data.y_train,

epochs=1, batch_size=128)

#Evaluation

#Once the model has been trained we can evaluate its performance on the test-set. This is the same syntax as for the Sequential Model.

result = model2.evaluate(x=data.x_test,

y=data.y_test)

#The result is a list of values, containing the loss-value and all the metrics we defined when we compiled the model. Note that ‘accuracy’ is now called ‘acc’ which is a small inconsistency.

for name, value in zip(model2.metrics_names, result):

print(name, value)

#We can also print the classification accuracy as a percentage:

print(“{0}: {1:.2%}”.format(model2.metrics_names[1], result[1]))

#Examples of Mis-Classified Images

#We can plot some examples of mis-classified images from the test-set.

#First we get the predicted classes for all the images in the test-set:

y_pred = model2.predict(x=data.x_test)

#Then we convert the predicted class-numbers from One-Hot encoded arrays to integers.

cls_pred = np.argmax(y_pred, axis=1)

#Plot some of the mis-classified images.

plot_example_errors(cls_pred)

#Save & Load Model

#NOTE: You need to install h5py for this to work!

#Tutorial #04 was about saving and restoring the weights of a model using native TensorFlow code. It was an absolutely horrible API! Fortunately, Keras makes this very easy.

#This is the file-path where we want to save the Keras model.

path_model = ‘model.keras’

#Saving a Keras model with the trained weights is then just a single function call, as it should be.

model2.save(path_model)

#Delete the model from memory so we are sure it is no longer used.

del model2

#We need to import this Keras function for loading the model.

from tensorflow.python.keras.models import load_model

#Loading the model is then just a single function-call, as it should be.

model3 = load_model(path_model)

#We can then use the model again e.g. to make predictions. We get the first 9 images from the test-set and their true class-numbers.

images = data.x_test[0:9]

cls_true = data.y_test_cls[0:9]

#We then use the restored model to predict the class-numbers for those images.

y_pred = model3.predict(x=images)

#Get the class-numbers as integers.

cls_pred = np.argmax(y_pred, axis=1)

#Plot the images with their true and predicted class-numbers.

plot_images(images=images,

cls_pred=cls_pred,

cls_true=cls_true)

# Visualization of Layer Weights and Outputs

def plot_conv_weights(weights, input_channel=0):

# Get the lowest and highest values for the weights.

# This is used to correct the colour intensity across

# the images so they can be compared with each other.

w_min = np.min(weights)

w_max = np.max(weights)

# Number of filters used in the conv. layer.

num_filters = weights.shape[3]

# Number of grids to plot.

# Rounded-up, square-root of the number of filters.

num_grids = math.ceil(math.sqrt(num_filters))

# Create figure with a grid of sub-plots.

fig, axes = plt.subplots(num_grids, num_grids)

# Plot all the filter-weights.

for i, ax in enumerate(axes.flat):

# Only plot the valid filter-weights.

if i<num_filters:

# Get the weights for the i’th filter of the input channel.

# See new_conv_layer() for details on the format

# of this 4-dim tensor.

img = weights[:, :, input_channel, i]

# Plot image.

ax.imshow(img, vmin=w_min, vmax=w_max,

interpolation=’nearest’, cmap=’seismic’)

# Remove ticks from the plot.

ax.set_xticks([])

ax.set_yticks([])

# Ensure the plot is shown correctly with multiple plots

# in a single Notebook cell.

plt.show()

#Get Layers

#Keras has a simple way of listing the layers in the model.

model3.summary()

# We count the indices to get the layers we want.

# The input-layer has index 0.

layer_input = model3.layers[0]

#The first convolutional layer has index 2.

layer_conv1 = model3.layers[2]

layer_conv1

#The second convolutional layer has index 4.

layer_conv2 = model3.layers[4]

# Convolutional Weights

# Now that we have the layers we can easily get their weights.

weights_conv1 = layer_conv1.get_weights()[0]

# This gives us a 4-rank tensor.

weights_conv1.shape

#Plot the weights using the helper-function from above.

plot_conv_weights(weights=weights_conv1, input_channel=0)

#We can also get the weights for the second convolutional layer and plot them.

weights_conv2 = layer_conv2.get_weights()[0]

plot_conv_weights(weights=weights_conv2, input_channel=0)

#Helper-function for plotting the output of a convolutional layer

def plot_conv_output(values):

# Number of filters used in the conv. layer.

num_filters = values.shape[3]

# Number of grids to plot.

# Rounded-up, square-root of the number of filters.

num_grids = math.ceil(math.sqrt(num_filters))

# Create figure with a grid of sub-plots.

fig, axes = plt.subplots(num_grids, num_grids)

# Plot the output images of all the filters.

for i, ax in enumerate(axes.flat):

# Only plot the images for valid filters.

if i<num_filters:

# Get the output image of using the i’th filter.

img = values[0, :, :, i]

# Plot image.

ax.imshow(img, interpolation=’nearest’, cmap=’binary’)

# Remove ticks from the plot.

ax.set_xticks([])

ax.set_yticks([])

# Ensure the plot is shown correctly with multiple plots

# in a single Notebook cell.

plt.show()

# Input Image

# Helper-function for plotting a single image.

def plot_image(image):

plt.imshow(image.reshape(img_shape),

interpolation=’nearest’,

cmap=’binary’)

plt.show()

# Plot an image from the test-set which will be used as an example below.

image1 = data.x_test[0]

plot_image(image1)

# Output of Convolutional Layer – Method 2

#Keras also has another method for getting the output of a layer inside the model. This creates another Functional Model using the same input as the original model, but the output is now taken from the convolutional layer that we are interested in.

output_conv2 = Model(inputs=layer_input.input,

outputs=layer_conv2.output)

#This creates a new model-object where we can call the typical Keras functions. To get the output of the convoloutional layer we call the predict() function with the input image.

layer_output2 = output_conv2.predict(np.array([image1]))

layer_output2.shape

# We can then plot the images for all 36 channels.

plot_conv_output(values=layer_output2)


#Conclusion

#This tutorial showed how to use the so-called Keras API for easily building Convolutional Neural Networks in TensorFlow. Keras is by far the most complete and best designed API for TensorFlow.

#This tutorial also showed how to use Keras to save and load a model, as well as getting the weights and outputs of convolutional layers.

#It seems likely that Keras will be the standard API for TensorFlow in the future, for the simple reason that is already very good and it is constantly being improved. So it is recommended that you use Keras.

参考:

https://github.com/Hvass-Labs/TensorFlow-Tutorials/blob/master/03C_Keras_API.ipy



版权声明:本文为wzhrsh原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。