mnist機器入門進階代碼

不囉嗦了,直接上代碼和運行結果吧。

代碼和運行結果

import tensorflow as tf
import input_data #可以自己下載這個py文件放在當前目錄下
import os
import time 
os.environ['TF_CPP_MIN_LOG_LEVEL']='2' #不加這個,macOS系統會有好幾個警告,但是不影響程序運行

start_time = time.time()
print('開始時間: ',time.strftime("%Y-%m-%d  %H:%M:%S",time.localtime()))

mnist = input_data.read_data_sets('MNIST_data',one_hot=True)

batch_size = 100 #可以自己定義此值
n_batch = 55000//batch_size #train文件有55000張圖片

x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])

def Weight_variable(shape):
    initial = tf.truncated_normal(shape=shape,mean=0,stddev=0.1)#這個叫截斷的正太分佈,只取正負兩倍的標準差中間的值
    return tf.Variable(initial)

def biases_variable(shape):
    #給偏置一個正數是因爲後面會用到relu神經元,防止relu神經元掉入0梯度區域壞死
    initial = tf.constant(0.1,shape=shape)
    return tf.Variable(initial)

def conv2d(x,W):
    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')

def max_pooling(x):
    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")


#第一層卷積,32個5x5大小的卷積核

#卷積層的輸入
x_image = tf.reshape(x,[-1,28,28,1])
#卷積層的參數
W_conv1 = Weight_variable(shape=[5,5,1,32]) #輸入通道爲1,輸出通道爲32,具體表現爲‘圖片’變厚了
b_conv1 = biases_variable(shape=[32])
#卷積層的輸出
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1) + b_conv1)
#卷積層後面連接一個池化層
h_pool1 = max_pooling(h_conv1)

#第二層卷積,只用了兩個卷積核
W_conv2 = Weight_variable(shape=[5,5,32,64])
b_conv2 = biases_variable(shape=[64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2)
h_pool2 = max_pooling(h_conv2)
h_pool2_out = tf.reshape(h_pool2,shape=[-1,7*7*64])#reshape一下,方便後面使用

#全連接層
W_fullconnection1 = Weight_variable(shape=[7*7*64,1024])
b_fullconnection1 = biases_variable(shape=[1024])
h_fullconnection1 = tf.nn.relu(tf.matmul(h_pool2_out,W_fullconnection1)+b_fullconnection1)

#dropout,防止過擬合
keep_prop = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fullconnection1,keep_prop)

#全連接輸出層
W_fullconnection2 = Weight_variable([1024,10])
b_fullconnection2 = biases_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fullconnection2)+b_fullconnection2)

cross_entropy = -tf.reduce_sum(y*tf.log(prediction)) #交叉熵損失函數
#這裏用AdamOptimizer的結果和GradientDescentOptimizer差不多。見最後一張圖。
train_step = tf.train.GradientDescentOptimizer(1e-3).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y,axis=1),tf.argmax(prediction,axis=1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,dtype=tf.float32))#將bool值轉化成數字

init = tf.global_variables_initializer() 

saver = tf.train.Saver()#添加一個對象用來保存我們的模型

with tf.Session() as sess:
    sess.run(init)  
    for step in range(1,30):  #迭代29輪
        for batch in range(n_batch):
            x_data,y_label = mnist.train.next_batch(batch_size) #每次訓練100張圖片
            sess.run(train_step,feed_dict={x:x_data,y:y_label,keep_prop:0.5})
        acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prop:1.0})
        print('Iter'+ str(step) + ' ,Accuracy = ' + str(acc))
    saver.save(sess,"model.ckpt") #保存到當前目錄
    print('保存成功')

end_time = time.time()
print('結束時間: ',time.strftime("%Y-%m-%d  %H:%M:%S",time.localtime()))
print('總耗時:',end_time - start_time,' 秒')

可以看到大概運行了96分鐘,對於這樣一個輸入層,兩個卷積層,兩個池化層,和兩個全連接層的五層神經網絡(一個卷積層加一個池化層常常被認爲是一層)來說,運行速度並不算太慢。當然也主要是由於輸入圖片很小,只有28*28,而且還是單通道的灰度圖。總的來說,99.24%的準確率雖然不是太高,但是也並不讓人失望。
這裏寫圖片描述

最後上兩個圖大家感受下對比下cpu使用情況和耗電排行。
這裏寫圖片描述
這裏寫圖片描述
sublime text和python的cpu佔用情況和能耗遠遠超過其他應用,表面上風平浪靜,實際上cpu在底下呼哧呼哧的全力跑着呢。
可惜電腦不能GPU加速,聽說GPU加速用起來爽翻了,大家要是有可以用GPU加速跑程序的可以跑完告訴我一下運行時間。

其他的提高準確率的方法

1.擴展訓練數據

訓練數據其實是很昂貴的數據資源,想要增加有效的訓練數據並不簡單。但是還是有一些方法的,可以通過旋轉,扭曲原圖像得到新的圖像來增加訓練數據。還可以通過增加一些小的背景噪聲來生成新的數據。

2.組合網絡

也就是說,我們可以訓練多個神經網絡,雖然每個的準確率都差不多,比如說有5個神經網絡的準確率都是99.2%,也就是10000個數據中有80個數據分類錯誤,但是可能每個神經網絡錯誤的80個數據都不一樣,A神經網絡分類識別某個數爲9,但其他四個神經網絡有三個或者四個都識別爲8,那麼很可能這個數就是8了。就跟大家平時抄作業一樣,每個人可能都有不會的,但是抄着抄着大家都會了。

3.其他

用AdamOptimizer的結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章