舒適提示,TensorFlow更新的太快了,有些代碼實現方式可能變了,可是思想仍是沒有變滴,主要仍是理解 原文地址git
介紹github
前面的教程代表,簡單的線性模型具備大約91%的分類準確度,用於識別MNIST數據集中的手寫數字。windows
在本教程中,咱們將在TensorFlow中實現一個簡單的卷積神經網絡,若是您進行一些建議的練習,其分類精度約爲99%或更高。api
卷積網絡經過在輸入圖像上移動小濾鏡來工做。 這意味着過濾器被從新用於識別整個輸入圖像中的模式。 這使得卷積網絡比具備相同數量的變量的徹底鏈接網絡更強大。 這反過來使Convolutional Networks更快地進行訓練。bash
您應該熟悉基本的線性代數,Python和Jupyter Notebook編輯器。 TensorFlow的初學者也可能但願在繼續學習以前學習第一篇教程。網絡
Flowchart 下圖大體顯示了下面實現的卷積神經網絡中數據的流動方式。session
而後在第二卷積層中處理這16個較小的圖像。 咱們須要爲這16個通道中的每一個通道提供濾波器權重,而且咱們須要對該層的每一個輸出通道使用濾波器權重。 有36個輸出通道,所以在第二個卷積層中總共有16 x 36 = 576個濾波器。 生成的圖像再次下采樣到7x7像素。dom
第二卷積層的輸出是每一個7×7像素的36個圖像。 而後將它們展平爲長度爲7×7×36 = 1764的單個矢量,其用做具備128個神經元(或元件)的徹底鏈接層的輸入。 這將進入另外一個具備10個神經元的徹底鏈接的層,每一個類對應一個類,用於肯定圖像的類別,即圖像中描繪的數字。編輯器
卷積濾波器最初是隨機選擇的,所以分類是隨機進行的。 輸入圖像的預測類和真實類之間的偏差被測量爲所謂的交叉熵。 而後,優化器使用區分鏈規則自動將此錯誤傳播回捲積網絡,並更新過濾器權重,以改善分類錯誤。 這反覆進行數千次,直到分類偏差足夠低。ide
這些特定的濾鏡權重和中間圖像是一次優化運行的結果,若是從新運行此Notebook,可能會有所不一樣。
請注意,TensorFlow中的計算其實是在一批圖像而不是單個圖像上完成的,這使得計算更有效。 這意味着當在TensorFlow中實現時,流程圖實際上還有一個數據維度。
Convolutional Layer
下圖顯示了在第一個卷積層中處理圖像的基本思想。 輸入圖像描繪了數字7,此處顯示了四個圖像副本,所以咱們能夠更清楚地看到濾鏡如何移動到圖像的不一樣位置。 對於濾鏡的每一個位置,在濾鏡和濾鏡下的圖像像素之間計算點積,這致使輸出圖像中的單個像素。 所以,在整個輸入圖像上移動濾鏡會致使生成新圖像。
紅色濾鏡權重意味着濾鏡對輸入圖像中的黑色像素具備正反應,而藍色像素意味着濾鏡對黑色像素具備負反應。
在這種狀況下,過濾器能夠識別出7位數的水平線,從輸出圖像中對該線的較強反應能夠看出。
在輸入上移動過濾器的步長稱爲步幅。 水平移動過濾器(x軸)和另外一個垂直移動步幅(y軸)有一個跨度。
在下面的源代碼中,步幅在兩個方向上都設置爲1,這意味着濾鏡從輸入圖像的左上角開始,並在每一個步驟中向右移動1個像素。 當濾鏡到達圖像右側的末尾時,濾鏡將向後移動到圖像的左側和1個像素。 這將一直持續到濾鏡到達輸入圖像的右下角並生成整個輸出圖像。
當濾鏡到達輸入圖像的右側和底部的末端時,能夠用零填充(白色像素)。 這會使輸出圖像與輸入圖像具備徹底相同的尺寸。
此外,卷積的輸出能夠經過所謂的整流線性單元(ReLU),其僅確保輸出爲正,由於負值被設置爲零。 輸出也能夠經過所謂的max-pooling進行下采樣,max-pooling考慮2x2像素的小窗口而且僅保留這些像素中的最大像素。 這使輸入圖像的分辨率減半,例如 從28x28到14x14像素。
注意,第二卷積層更復雜,由於它須要16個輸入通道。 咱們想爲每一個輸入通道分別使用一個過濾器,所以咱們須要16個過濾器而不是一個過濾器。 此外,咱們須要來自第二卷積層的36個輸出通道,所以總共須要16 x 36 = 576個濾波器用於第二個卷積層。 瞭解其工做原理可能有點難度。
Imports
%matplotlib inline
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
from sklearn.metrics import confusion_matrix
import time
from datetime import timedelta
import math
複製代碼
Configuration of Neural Network
爲方便起見,此處定義了卷積神經網絡的配置,所以您能夠輕鬆查找和更改這些數字並從新運行Notebook。
# Convolutional Layer 1.
filter_size1 = 5 # Convolution filters are 5 x 5 pixels.
num_filters1 = 16 # There are 16 of these filters.
# Convolutional Layer 2.
filter_size2 = 5 # Convolution filters are 5 x 5 pixels.
num_filters2 = 36 # There are 36 of these filters.
# Fully-connected layer.
fc_size = 128 # Number of neurons in fully-connected layer.
複製代碼
Load Data
MNIST數據集大約爲12 MB,若是它不在給定路徑中,將自動下載。
from mnist import MNIST
data = MNIST(data_dir="data/MNIST/")
複製代碼
複製代碼MNIST數據集現已加載,由70,000個圖像和圖像的類號組成。 數據集被分紅3個互斥的子集。 咱們將僅使用本教程中的培訓和測試集。
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))
Size of:
- Training-set: 55000
- Validation-set: 5000
- Test-set: 10000
複製代碼
複製代碼爲方便起見,複製一些數據維度。
# 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
# 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
複製代碼
Helper-function for plotting images
用於在3x3網格中繪製9個圖像,並在每一個圖像下面寫入真實和預測類的函數。
def plot_images(images, cls_true, cls_pred=None):
assert len(images) == len(cls_true) == 9
# Create figure with 3x3 sub-plots.
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')
# 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.show()
複製代碼
Plot a few images to see if data is correct
# 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)
複製代碼
TensorFlow Graph
#Helper-functions for creating new variables(輔助函數用於建立新變量)
用於在給定形狀中建立新TensorFlow變量並使用隨機值初始化它們的函數。 請注意,此時實際上並未完成初始化,它僅在TensorFlow圖中定義。
def new_weights(shape):
return tf.Variable(tf.truncated_normal(shape, stddev=0.05))
def new_biases(length):
return tf.Variable(tf.constant(0.05, shape=[length]))
複製代碼
#Helper-function for creating a new Convolutional Layer(輔助功能,用於建立新的卷積層)
此函數在TensorFlow的計算圖中建立一個新的卷積層。 這裏沒有實際計算,咱們只是將數學公式添加到TensorFlow圖。
假設輸入是具備如下尺寸的4維張量:
圖像編號。
每一個圖像的Y軸。
每一個圖像的X軸。
每一個圖像的通道。
複製代碼
注意,輸入通道能夠是顏色通道,或者若是輸入是從先前的卷積層產生的,則它能夠是濾波器通道。
輸出是另外一個4-dim張量,具備如下尺寸:
圖像編號,與輸入相同。
每一個圖像的Y軸。 若是使用2x2池,則輸入圖像的高度和寬度除以2。
每一個圖像的X軸。 同上。
卷積濾波器產生的通道。
複製代碼
def new_conv_layer(input, # The previous layer.
num_input_channels, # Num. channels in prev. layer.
filter_size, # Width and height of each filter.
num_filters, # Number of filters.
use_pooling=True): # Use 2x2 max-pooling.
# Shape of the filter-weights for the convolution.
# This format is determined by the TensorFlow API.
shape = [filter_size, filter_size, num_input_channels, num_filters]
# Create new weights aka. filters with the given shape.
weights = new_weights(shape=shape)
# Create new biases, one for each filter.
biases = new_biases(length=num_filters)
# Create the TensorFlow operation for convolution.
# Note the strides are set to 1 in all dimensions.
# The first and last stride must always be 1,
# because the first is for the image-number and
# the last is for the input-channel.
# But e.g. strides=[1, 2, 2, 1] would mean that the filter
# is moved 2 pixels across the x- and y-axis of the image.
# The padding is set to 'SAME' which means the input image
# is padded with zeroes so the size of the output is the same.
layer = tf.nn.conv2d(input=input,
filter=weights,
strides=[1, 1, 1, 1],
padding='SAME')
# Add the biases to the results of the convolution.
# A bias-value is added to each filter-channel.
layer += biases
# Use pooling to down-sample the image resolution?
if use_pooling:
# This is 2x2 max-pooling, which means that we
# consider 2x2 windows and select the largest value
# in each window. Then we move 2 pixels to the next window.
layer = tf.nn.max_pool(value=layer,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
# Rectified Linear Unit (ReLU).
# It calculates max(x, 0) for each input pixel x.
# This adds some non-linearity to the formula and allows us
# to learn more complicated functions.
layer = tf.nn.relu(layer)
# Note that ReLU is normally executed before the pooling,
# but since relu(max_pool(x)) == max_pool(relu(x)) we can
# save 75% of the relu-operations by max-pooling first.
# We return both the resulting layer and the filter-weights
# because we will plot the weights later.
return layer, weights
複製代碼
#Helper-function for flattening a layer(輔助功能,用於展平圖層)
卷積層產生具備4維的輸出張量。 咱們將在卷積層以後添加徹底鏈接的層,所以咱們須要將4-dim張量減少到2-dim,這能夠用做徹底鏈接層的輸入。
def flatten_layer(layer):
# Get the shape of the input layer.
layer_shape = layer.get_shape()
# The shape of the input layer is assumed to be:
# layer_shape == [num_images, img_height, img_width, num_channels]
# The number of features is: img_height * img_width * num_channels
# We can use a function from TensorFlow to calculate this.
num_features = layer_shape[1:4].num_elements()
# Reshape the layer to [num_images, num_features].
# Note that we just set the size of the second dimension
# to num_features and the size of the first dimension to -1
# which means the size in that dimension is calculated
# so the total size of the tensor is unchanged from the reshaping.
layer_flat = tf.reshape(layer, [-1, num_features])
# The shape of the flattened layer is now:
# [num_images, img_height * img_width * num_channels]
# Return both the flattened layer and the number of features.
return layer_flat, num_features
複製代碼
#Helper-function for creating a new Fully-Connected Layer(輔助功能,用於建立新的全鏈接層)
此函數在TensorFlow的計算圖中建立一個新的徹底鏈接層。 這裏沒有實際計算,咱們只是將數學公式添加到TensorFlow圖。
假設輸入是形狀[di_images,num_inputs]的二維張量。 輸出是2-dim張量的形狀[num_images,num_outputs]。
def new_fc_layer(input, # The previous layer.
num_inputs, # Num. inputs from prev. layer.
num_outputs, # Num. outputs.
use_relu=True): # Use Rectified Linear Unit (ReLU)?
# Create new weights and biases.
weights = new_weights(shape=[num_inputs, num_outputs])
biases = new_biases(length=num_outputs)
# Calculate the layer as the matrix multiplication of
# the input and weights, and then add the bias-values.
layer = tf.matmul(input, weights) + biases
# Use ReLU?
if use_relu:
layer = tf.nn.relu(layer)
return layer
複製代碼
#Placeholder variables(佔位符變量) 佔位符變量用做TensorFlow計算圖的輸入,每次執行圖時咱們均可以更改。 咱們稱之爲佔位符變量,並在下面進一步說明。
首先,咱們爲輸入圖像定義佔位符變量。 這容許咱們更改輸入到TensorFlow圖形的圖像。 這是一個所謂的張量,這意味着它是一個多維向量或矩陣。 數據類型設置爲float32,形狀設置爲[None,img_size_flat],其中None表示張量能夠保持任意數量的圖像,每一個圖像是長度爲img_size_flat的向量。
x = tf.placeholder(tf.float32, shape=[None, img_size_flat], name='x')
複製代碼
卷積層指望x被編碼爲4-dim張量,所以咱們必須對其進行整形,使其形狀爲[num_images,img_height,img_width,num_channels]。 請注意,img_height == img_width == img_size和num_images可使用-1做爲第一個維度的大小自動推斷。 因此重塑操做是:
x_image = tf.reshape(x, [-1, img_size, img_size, num_channels])
複製代碼
接下來,咱們有佔位符變量,用於與佔位符變量x中輸入的圖像相關聯的真實標籤。 此佔位符變量的形狀爲[None,num_classes],這意味着它能夠包含任意數量的標籤,每一個標籤是長度爲num_classes的向量,在這種狀況下爲10。
y_true = tf.placeholder(tf.float32, shape=[None, num_classes], name='y_true')
複製代碼
咱們也能夠爲label設置佔位符變量,但咱們將使用argmax計算它。 請注意,這是一個TensorFlow運算符,所以此時不計算任何內容。
y_true_cls = tf.argmax(y_true, axis=1)
複製代碼
Convolutional Layer 1
建立第一個卷積層。 它將x_image做爲輸入並建立num_filters1個不一樣的過濾器,每一個過濾器的寬度和高度等於filter_size1。 最後,咱們但願經過使用2x2 max-pooling對圖像進行下采樣,使其大小減半。
layer_conv1, weights_conv1 = \
new_conv_layer(input=x_image,
num_input_channels=num_channels,
filter_size=filter_size1,
num_filters=num_filters1,
use_pooling=True)
複製代碼
檢查將由卷積層輸出的張量的形狀。 它是(?,14,14,16),這意味着有任意數量的圖像(這是?),每一個圖像寬14像素,高14像素,有16個不一樣的通道,每一個通道一個通道 過濾器
layer_conv1
<tf.Tensor 'Relu:0' shape=(?, 14, 14, 16) dtype=float32>
複製代碼
Convolutional Layer 2
建立第二個卷積層,它將第一個卷積層的輸出做爲輸入。 輸入通道的數量對應於第一卷積層中的濾波器的數量。
layer_conv2, weights_conv2 = \
new_conv_layer(input=layer_conv1,
num_input_channels=num_filters1,
filter_size=filter_size2,
num_filters=num_filters2,
use_pooling=True)
複製代碼
檢查將今後卷積層輸出的張量的形狀。 形狀是(?,7,7,36)? 再次表示存在任意數量的圖像,每一個圖像的寬度和高度爲7個像素,而且有36個通道,每一個濾波器一個。
layer_conv2
<tf.Tensor 'Relu_1:0' shape=(?, 7, 7, 36) dtype=float32>
複製代碼
Flatten Layer
卷積層輸出4-dim張量。 咱們如今但願在徹底鏈接的網絡中使用這些做爲輸入,這須要將張量從新整形或展平爲2-dim張量。
layer_flat, num_features = flatten_layer(layer_conv2)
複製代碼
檢查張量如今是否具備形狀(?,1764),這意味着有任意數量的圖像已被展平爲每一個長度爲1764的向量。 請注意,1764 = 7 x 7 x 36。
In [23]:layer_flat
Out[23]:<tf.Tensor 'Reshape_1:0' shape=(?, 1764) dtype=float32>
In [24]:num_features
Out[24]:1764
複製代碼
Fully-Connected Layer 1
將徹底鏈接的層添加到網絡中。 輸入是前一卷積的平坦層。 徹底鏈接層中的神經元或節點的數量是fc_size。 使用ReLU,咱們能夠學習非線性關係。
layer_fc1 = new_fc_layer(input=layer_flat,
num_inputs=num_features,
num_outputs=fc_size,
use_relu=True)
複製代碼
檢查徹底鏈接層的輸出是否爲形狀(?,128)的張量? 意味着有任意數量的圖像,fc_size == 128。
In [26]:layer_fc1
Out[26]:<tf.Tensor 'Relu_2:0' shape=(?, 128) dtype=float32>
複製代碼
Fully-Connected Layer 2
添加另外一個徹底鏈接的層,輸出長度爲10的向量,用於肯定輸入圖像屬於哪10個類。 請注意,此層中不使用ReLU。
In [27]:layer_fc2 = new_fc_layer(input=layer_fc1,
num_inputs=fc_size,
num_outputs=num_classes,
use_relu=False)
In [28]:layer_fc2
Out[28]:<tf.Tensor 'add_3:0' shape=(?, 10) dtype=float32>
複製代碼
Predicted Class
第二個徹底鏈接的層估計輸入圖像屬於10個類中的每個的可能性。 然而,這些估計有點粗糙且難以解釋,由於數字可能很是小或很大,所以咱們但願將它們標準化,以便每一個元素限制在0和1之間,10個元素總和爲1。 這是使用所謂的softmax函數計算的,結果存儲在y_pred中。
y_pred = tf.nn.softmax(layer_fc2)
複製代碼
class-number是最大元素的索引。
y_pred_cls = tf.argmax(y_pred, axis=1)
複製代碼
Cost-function to be optimized
爲了使模型更好地分類輸入圖像,咱們必須以某種方式改變全部網絡層的變量。 爲此,咱們首先須要經過將模型y_pred的預測輸出與指望輸出y_true進行比較來了解模型當前的執行狀況。
交叉熵是用於分類的性能度量。 交叉熵是一個始終爲正的連續函數,若是模型的預測輸出與指望輸出徹底匹配,則交叉熵等於零。 所以,優化的目標是最小化交叉熵,使其經過改變網絡層的變量儘量接近零。
TensorFlow具備用於計算交叉熵的內置函數。 請注意,該函數在內部計算softmax,所以咱們必須直接使用layer_fc2的輸出,而不是已經應用了softmax的y_pred。
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=layer_fc2,
labels=y_true)
複製代碼
咱們如今已經計算了每一個圖像分類的交叉熵,所以咱們能夠測量模型對每一個圖像的單獨執行狀況。 可是爲了使用交叉熵來指導模型變量的優化,咱們須要一個標量值,所以咱們只須要對全部圖像分類採用交叉熵的平均值。
cost = tf.reduce_mean(cross_entropy)
複製代碼
Optimization Method 如今咱們有一個必須最小化的成本度量,而後咱們能夠建立一個優化器。 在這種狀況下,它是AdamOptimizer,它是Gradient Descent的高級形式。
請注意,此時不執行優化。 事實上,根本沒有計算任何東西,咱們只需將optimizer-object添加到TensorFlow圖中以便之後執行。
optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost)
複製代碼
Performance Measures
correct_prediction = tf.equal(y_pred_cls, y_true_cls)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
複製代碼
TensorFlow Run
接下來都是訓練、測試、調試啦~ 方式不少,這裏我就只貼代碼了
session = tf.Session()
session.run(tf.global_variables_initializer())
train_batch_size = 64
# Counter for total number of iterations performed so far.
total_iterations = 0
def optimize(num_iterations):
# Ensure we update the global variable rather than a local copy.
global total_iterations
# Start-time used for printing time-usage below.
start_time = time.time()
for i in range(total_iterations,
total_iterations + num_iterations):
# Get a batch of training examples.
# x_batch now holds a batch of images and
# y_true_batch are the true labels for those images.
x_batch, y_true_batch, _ = data.random_batch(batch_size=train_batch_size)
# Put the batch into a dict with the proper names
# for placeholder variables in the TensorFlow graph.
feed_dict_train = {x: x_batch,
y_true: y_true_batch}
# Run the optimizer using this batch of training data.
# TensorFlow assigns the variables in feed_dict_train
# to the placeholder variables and then runs the optimizer.
session.run(optimizer, feed_dict=feed_dict_train)
# Print status every 100 iterations.
if i % 100 == 0:
# Calculate the accuracy on the training-set.
acc = session.run(accuracy, feed_dict=feed_dict_train)
# Message for printing.
msg = "Optimization Iteration: {0:>6}, Training Accuracy: {1:>6.1%}"
# Print it.
print(msg.format(i + 1, acc))
# Update the total number of iterations performed.
total_iterations += num_iterations
# Ending time.
end_time = time.time()
# Difference between start and end-times.
time_dif = end_time - start_time
# Print the time-usage.
print("Time usage: " + str(timedelta(seconds=int(round(time_dif)))))
複製代碼
def plot_example_errors(cls_pred, correct):
# This function is called from print_test_accuracy() below.
# cls_pred is an array of the predicted class-number for
# all images in the test-set.
# correct is a boolean array whether the predicted class
# is equal to the true class for each image in the test-set.
# Negate the boolean array.
incorrect = (correct == False)
# 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])
複製代碼
def plot_confusion_matrix(cls_pred):
# This is called from print_test_accuracy() below.
# cls_pred is an array of the predicted class-number for
# all images in the test-set.
# Get the true classifications for the test-set.
cls_true = data.y_test_cls
# Get the confusion matrix using sklearn.
cm = confusion_matrix(y_true=cls_true,
y_pred=cls_pred)
# Print the confusion matrix as text.
print(cm)
# Plot the confusion matrix as an image.
plt.matshow(cm)
# Make various adjustments to the plot.
plt.colorbar()
tick_marks = np.arange(num_classes)
plt.xticks(tick_marks, range(num_classes))
plt.yticks(tick_marks, range(num_classes))
plt.xlabel('Predicted')
plt.ylabel('True')
# Ensure the plot is shown correctly with multiple plots
# in a single Notebook cell.
plt.show()
複製代碼
# Split the test-set into smaller batches of this size.
test_batch_size = 256
def print_test_accuracy(show_example_errors=False,
show_confusion_matrix=False):
# Number of images in the test-set.
num_test = data.num_test
# Allocate an array for the predicted classes which
# will be calculated in batches and filled into this array.
cls_pred = np.zeros(shape=num_test, dtype=np.int)
# Now calculate the predicted classes for the batches.
# We will just iterate through all the batches.
# There might be a more clever and Pythonic way of doing this.
# The starting index for the next batch is denoted i.
i = 0
while i < num_test:
# The ending index for the next batch is denoted j.
j = min(i + test_batch_size, num_test)
# Get the images from the test-set between index i and j.
images = data.x_test[i:j, :]
# Get the associated labels.
labels = data.y_test[i:j, :]
# Create a feed-dict with these images and labels.
feed_dict = {x: images,
y_true: labels}
# Calculate the predicted class using TensorFlow.
cls_pred[i:j] = session.run(y_pred_cls, feed_dict=feed_dict)
# Set the start-index for the next batch to the
# end-index of the current batch.
i = j
# Convenience variable for the true class-numbers of the test-set.
cls_true = data.y_test_cls
# Create a boolean array whether each image is correctly classified.
correct = (cls_true == cls_pred)
# Calculate the number of correctly classified images.
# When summing a boolean array, False means 0 and True means 1.
correct_sum = correct.sum()
# Classification accuracy is the number of correctly classified
# images divided by the total number of images in the test-set.
acc = float(correct_sum) / num_test
# Print the accuracy.
msg = "Accuracy on Test-Set: {0:.1%} ({1} / {2})"
print(msg.format(acc, correct_sum, num_test))
# Plot some examples of mis-classifications, if desired.
if show_example_errors:
print("Example errors:")
plot_example_errors(cls_pred=cls_pred, correct=correct)
# Plot the confusion matrix, if desired.
if show_confusion_matrix:
print("Confusion Matrix:")
plot_confusion_matrix(cls_pred=cls_pred)
複製代碼
print_test_accuracy()
optimize(num_iterations=900)
print_test_accuracy(show_example_errors=True)
複製代碼