我們將要搭建一個(gè)簡(jiǎn)單的卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)去提高手寫(xiě)數(shù)字的預(yù)測(cè)結(jié)果精度。
# Introductory CNN Model: MNIST Digits
# In this example, we will download the MNIST?handwritten
# digits and create a simple CNN network to predict the
# digit category (0-9)
主要分為以下幾個(gè)步驟:導(dǎo)入數(shù)據(jù)潦匈;創(chuàng)建模型的變量玩裙;搭建模型惫叛;采用批量化訓(xùn)練網(wǎng)絡(luò)昌阿;可視化loss殖告,accuracy等結(jié)果烘挫。
1.導(dǎo)入必要的庫(kù)和開(kāi)始一個(gè)圖譜會(huì)話
import tensorflow as tf
import numpy as np
import matplotlib as plt
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
sess = tf.Session()
2.導(dǎo)入數(shù)據(jù)集和將圖片裝換為28 * 28大小的矩陣
data_dir = 'temp'?? #數(shù)據(jù)集存放的文件夾
mnist = read_data_sets(data_dir)????? #讀取數(shù)據(jù)集
#將訓(xùn)練和測(cè)試數(shù)據(jù)集圖片歸一化為28*28大小
train_xdata = np.array([np.reshape(x, (28,28)) for x in mnist.train.images])
test_xdata = np.array([np.reshape(x, (28,28)) for x in mnist.test.images])
train_labels = mnist.train.labels??? #訓(xùn)練數(shù)據(jù)集標(biāo)簽
test_labels = mnist.test.labels?????? #測(cè)試數(shù)據(jù)集標(biāo)簽
3.定義模型參數(shù)
batch_size = 100?????? #一個(gè)批量的圖片數(shù)量
learning_rate = 0.005?????????? #學(xué)習(xí)率
evaluation_size = 500????????? #模型驗(yàn)證數(shù)據(jù)集一個(gè)批量的數(shù)量
image_width = train_xdata[0].shape[0]????? #圖片的長(zhǎng) 28
image_height = train_xdata[0].shape[1]???? #圖片的寬 28
target_size = max(train_labels)+1??? #輸出類(lèi)別的個(gè)數(shù) 10
num_channels = 1???????????????????????????? # 通道數(shù)為1
generations = 500????????????????????????????? #迭代代數(shù)
eval_every = 5 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#每次5個(gè)generation
conv1_features = 25????????????????????????? #卷積核的個(gè)數(shù)
conv2_features = 50????????????????????????? #卷積核的個(gè)數(shù)
max_pool_size1 = 2????????????????????????? #池化層窗口大小
max_pool_size2 = 2????????????????????????? #池化層窗口大小
fully_connected_size1 = 100??????????? #全連接層大小
4.定義數(shù)據(jù)集的占位符
#輸入數(shù)據(jù)的張量大小
x_input_shape = (batch_size, image_width, image_height, num_channels)
#創(chuàng)建輸入訓(xùn)練數(shù)據(jù)的占位符
x_input = tf.placeholder(tf.float32, shape=x_input_shape)? ? ? ? ?
#創(chuàng)建一個(gè)批量訓(xùn)練結(jié)果的占位符
y_target = tf.placeholder(tf.int32, shape=batch_size)? ? ? ? ?
#驗(yàn)證圖片輸入張量
eval_input_shape = (evaluation_size, image_width, image_height,num_channels)
#創(chuàng)建輸入驗(yàn)證數(shù)據(jù)的占位符
eval_input = tf.placeholder(tf.float32, shape=eval_input_shape)? ??
#創(chuàng)建一個(gè)批量驗(yàn)證結(jié)果的占位符
eval_target = tf.placeholder(tf.int32, shape= evaluation_size )??
5.定義訓(xùn)練權(quán)重和偏置的變量
#定義第一個(gè)卷積核的參數(shù)诀艰,其中用tf.truncated_normal生成正太分布的數(shù)據(jù),#stddev(正態(tài)分布標(biāo)準(zhǔn)差)為0.1
conv1_weight = tf.Variable(tf.truncated_normal([4, 4, num_channels, conv1_features], stddev=0.1, dtype = tf.float32))
#定義第一個(gè)卷積核對(duì)應(yīng)的偏置
conv1_bias = tf.Variable(tf.zeros([conv1_features], dtype=tf.float32))
#定義第二個(gè)卷積核的參數(shù)饮六,其中用tf.truncated_normal生成正太分布的數(shù)據(jù)其垄,#stddev(正態(tài)分布標(biāo)準(zhǔn)差)為0.1
conv2_weight = tf.Variable(tf.truncated_normal([4, 4, num_channels, conv2_features], stddev=0.1, dtype = tf.float32))
#定義第二個(gè)卷積核對(duì)應(yīng)的偏置
conv2_bias = tf.Variable(tf.zeros([conv2_features], dtype=tf.float32))
6.定義全連接層的權(quán)重和偏置
#輸出卷積特征圖的大小
resulting_width = image_width // (max_pool_size1 * max_pool_size2)
resulting_height = image_height // (max_pool_size1 * max_pool_size2)
#將卷積層特征圖拉成一維向量
full1_input_size = resulting_width * resulting_height * conv2_features
#創(chuàng)建第一個(gè)全連接層權(quán)重和偏置
full1_weight =tf.Variable(tf.truncated_normal([full1_input_size,fully_connected_size1],
?????????????????????????????????????????????? stddev=0.1, dtype=tf.float32))
full1_bias = tf.Variable(tf.truncated_normal([fully_connected_size1], stddev=0.1,
?????????????????????????????????????????????? dtype=tf.float32))
#創(chuàng)建第二個(gè)全連接層權(quán)重和偏置
full2_weight = tf.Variable(tf.truncated_normal([fully_connected_size1,target_size],
?????????????????????????????????????????????? stddev=0.1, dtype=tf.float32))
full2_bias = tf.Variable(tf.truncated_normal([target_size], stddev=0.1,
?????????????????????????????????????????????? dtype=tf.float32))
7.定義網(wǎng)絡(luò)模型
def my_conv_net(input_data):
??? #First Conv-relu-maxpool layer
??? conv1 = tf.nn.conv2d(input_data, conv1_weight, strides=[1, 1, 1, 1], padding='SAME')
??? relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_bias))
??? max_pool1 = tf.nn.max_pool(relu1, ksize=[1, max_pool_size1, max_pool_size1, 1],? strides=[1, max_pool_size1, max_pool_size1, 1], padding='SAME')
??? # Second Conv-relu-maxpool layer
??? conv2 = tf.nn.conv2d(max_pool1, conv2_weight, strides=[1, 1, 1, 1], padding='SAME')
??? relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_bias))
??? max_pool2 = tf.nn.max_pool(relu2, ksize=[1, max_pool_size1, max_pool_size1, 1],? strides=[1, max_pool_size2, max_pool_size2, 1], padding='SAME')
??? #將輸出轉(zhuǎn)換為一個(gè)[1xN],為下一個(gè)全連接層輸入做準(zhǔn)備
??? final_conv_shape = max_pool2.get_shape().as_list()
??? final_shape = final_conv_shape[1] * final_conv_shape[2] * final_conv_shape[3]
??? flat_output = tf.reshape(max_pool2, [final_conv_shape[0], final_shape])
??? #First fully-connected layer
??? fully_connected1 = tf.nn.relu(tf.add(tf.add(tf.matmul(flat_output,full1_weight), full1_bias)))
?? ?# Second fully-connected layer
??? final_model_output = tf.add(tf.matmul(fully_connected1, full2_weight), full2_bias)
??? return (final_model_output)
8.定義網(wǎng)絡(luò)的訓(xùn)練數(shù)據(jù)和測(cè)數(shù)據(jù)
model_output = my_conv_net(x_input)
test_model_output = my_conv_net(eval_input)
9.使用Softmax函數(shù)作為loss function
loss = loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=model_output, labels=y_target))
10.接下來(lái)創(chuàng)建一個(gè)訓(xùn)練和測(cè)試的函數(shù)
prediction = tf.nn.softmax(model_output)
test_prediction = tf.nn.softmax(test_model_output)
# Create accuracy function
def get_accuracy(logits, targets):
? ? batch_predictions = np.argmax(logits, axis=1)
? ? num_correct = np.sum(np.equal(batch_predictions, targets))
return(100. * num_correct/batch_predictions.shape[0])
11.創(chuàng)建一個(gè)optimizer function
my_optimizer = tf.train.MomentumOptimizer(learning_rate, 0.9)
train_step = my_optimizer.minimize(loss)
# Initialize Variables
init = tf.initialize_all_variables()
sess.run(init)
12.開(kāi)始訓(xùn)練模型
train_loss = [ ]
train_acc = [ ]
test_acc = [ ]
for i in range(generations):
? ? rand_index = np.random.choice(len(train_xdata), size=batch_size)
? ? rand_x = train_xdata[rand_index]
? ? rand_x = np.expand_dims(rand_x, 3)
? ? rand_y = train_labels[rand_index]
? ? train_dict = {x_input: rand_x, y_target: rand_y}
? ? sess.run(train_step, feed_dict=train_dict)
? ? temp_train_loss, temp_train_preds = sess.run([loss,?prediction], feed_dict=train_dict)
? ? temp_train_acc = get_accuracy(temp_train_preds, rand_y)
? ? if (i+1) % eval_every == 0:
? ? ? ? eval_index = np.random.choice(len(test_xdata),?size=evaluation_size)
? ? ? ? eval_x = test_xdata[eval_index]
? ? ? ? eval_x = np.expand_dims(eval_x, 3)
? ? ? ? eval_y = test_labels[eval_index]
? ? ? ? test_dict = {eval_input: eval_x, eval_target: eval_y}
? ? ? ? test_preds = sess.run(test_prediction, feed_dict=test_dict)
? ? ? ? temp_test_acc = get_accuracy(test_preds, eval_y)
? ? ? ? # Record and print results
? ? ? ? train_loss.append(temp_train_loss)
? ? ? ? train_acc.append(temp_train_acc)
? ? ? ? test_acc.append(temp_test_acc)
? ? ? ? acc_and_loss = [(i+1), temp_train_loss, temp_train_acc,?temp_test_acc]
? ? ? ? acc_and_loss = [np.round(x,2) for x in acc_and_loss]
13.輸出結(jié)果
print('Generation # {}. Train Loss: {:.2f}. Train Acc (Test Acc):?{:.2f} ({:.2f})'.format(*acc_and_loss))
14.使用matplotlib顯示loss-accuracies曲線
eval_indices = range(0, generations, eval_every)
# Plot loss over time
plt.plot(eval_indices, train_loss, 'k-')
plt.title('Softmax Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('Softmax Loss')
plt.show()
# Plot train and test accuracy
plt.plot(eval_indices, train_acc, 'k-', label='Train Set Accuracy')
plt.plot(eval_indices, test_acc, 'r--', label='Test Set Accuracy')
plt.title('Train and Test Accuracy')
plt.xlabel('Generation')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()
15.顯示最新一個(gè)批量的預(yù)測(cè)結(jié)果
# Plot the 6 of the last batch results:
actuals = rand_y[0:6]
predictions = np.argmax(temp_train_preds,axis=1)[0:6]
images = np.squeeze(rand_x[0:6])
Nrows = 2
Ncols = 3
for i in range(6):
? ? plt.subplot(Nrows, Ncols, i+1)
? ? plt.imshow(np.reshape(images[i], [28,28]), cmap='Greys_r')
? ? plt.title('Actual: ' + str(actuals[i]) + ' Pred: ' + str(predi
? ? ctions[i]),fontsize=10)
? ? frame = plt.gca()
? ? frame.axes.get_xaxis().set_visible(False)
? ? frame.axes.get_yaxis().set_visible(False)