1. 程式人生 > >【深度學習】3:BP神經網路與MNIST資料集實現手寫數字識別

【深度學習】3:BP神經網路與MNIST資料集實現手寫數字識別

前言:這是一篇基於tensorflow框架,建立的只有一層隱藏層的BP神經網路,做的圖片識別,內容也比較簡單,全當是自己的學習筆記了。

—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-

1、載入MNIST資料集

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data'
, one_hot=True)

mnist是一個輕量級的類。它以Numpy陣列的形式儲存著訓練、校驗和測試資料集,也是Google做圖片識別的經典資料集。MNIST資料集下載連結: https://pan.baidu.com/s/1d9ty82 密碼: jcam

2、執行TensorFlow框架

import tensorflow as tf

sess = tf.InteractiveSession()
init = tf.global_variables_initializer()
sess.run(init)

TensorFlow框架與後端的連線叫做session,也就是說我們用session啟動TensorFlow框架(詳情就要自己深入瞭解了)

3、預定義輸入值X,真實值Y

X = tf.placeholder(tf.float32, shape=[None, 784])
Y = tf.placeholder(tf.float32, shape=[None, 10])
  • X,Y現由佔位符表示,可以在TensorFlow執行某一計算時,根據該佔位符輸入的具體的值而進行計算;
  • tf.float32 是儲存的型別;shape=[None, 784]是資料維度大小——因為MNIST資料集中每一張圖片大小都是28*28的,計算時候是將28*28的二維資料轉換成一個一維的、長度為784的新向量。None表示其值大小不定,意即選中的X、Y的數量暫時不定

4、建立BP神經網路

"""
用隨機數列生成的方式,建立含一個隱藏層的神經網路。(784,300,10)
"""
#truncated_normal:選取位於正態分佈均值=0.1附近的隨機值
w1 = tf.Variable(tf.truncated_normal([784,300],stddev=0.1))
w2 = tf.Variable(tf.zeros([300,10]))
b1 = tf.Variable(tf.zeros([300]))
b2 = tf.Variable(tf.zeros([10]))
#relu、softmax都為啟用函式
L1 = tf.nn.relu(tf.matmul(X,w1)+b1)
y = tf.nn.softmax(tf.matmul(L1,w2)+b2)

BP神經網路輸入層有784個神經元、隱藏層300個神經元、輸出層10個神經元。初始化各級權重w1、w2;各級偏置值b1、b2——都是採用隨機數列生成的方式。定義隱藏層、輸出層的計算方式以及各自的啟用函式。

5、計算誤差並用梯度下降法優化權重

#二次代價函式:計算預測值y與真實值Y之間的誤差
loss = tf.reduce_mean(tf.square(Y - y))
#梯度下降法:選用GradientDescentOptimizer優化器,學習率為0.5
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

誤差也叫損失函式、代價函式。TensorFlow中有大量內建的優化演算法,這裡我們選用最簡單的GradientDescentOptimizer優化器讓交叉熵下降,步長為定為0.5

6、計算準確率

#結果存放在一個布林型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(Y,1))
#求準確率
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
  • tf.argmax()函式:是返回物件在某一維上的其資料最大值所對應的索引值,由於這裡的標籤向量都是由0,1組成,因此最大值1所在的索引位置就是對應的類別標籤
  • tf.argmax(y,1)返回的是對於任一輸入x預測到的標籤值,tf.argmax(Y,1)代表正確的標籤值
  • correct_prediction 這裡是返回一個布林陣列。為了計算我們分類的準確率,我們將布林值轉換為浮點數來代表對與錯,然後取平均值。例如:[True, False, True, True]變為[1,0,1,1],計算出準確率就為0.75

7、其他說明

batch_xs,batch_ys = mnist.train.next_batch(batch_size)
        sess.run(train_step,feed_dict=({X:batch_xs,Y:batch_ys}))
        acc = sess.run(accuracy,feed_dict={X:mnist.test.images,Y:mnist.test.labels})
  • batch_xs與batch_ys:是從MNIST資料集中按批次數取得的:資料項與標籤項
  • feed_dict=({X:batch_xs,Y:batch_ys}語句:是將batch_xs、batch_ys代表的值傳入X、Y

原始碼與效果展示

# -*- coding:utf-8 -*-
# -*- author:zzZ_CMing
# -*- 2018/01/23;21:49
# -*- python3.5

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#讀取MNIST資料集
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
#設定每個批次的大小
batch_size = 500
#計算一共有多少個批次(地板除)
n_batch = mnist.train.num_examples//batch_size
#預定義輸入值X、輸出真實值Y    placeholder為佔位符
X = tf.placeholder(tf.float32,[None,784])
Y = tf.placeholder(tf.float32,[None,10])



"""
用隨機數列生成的方式,建立含一個隱藏層的神經網路。(784,300,10)
"""
#truncated_normal:選取位於正態分佈均值=0.1附近的隨機值
w1 = tf.Variable(tf.truncated_normal([784,300],stddev=0.1))
w2 = tf.Variable(tf.zeros([300,10]))
b1 = tf.Variable(tf.zeros([300]))
b2 = tf.Variable(tf.zeros([10]))
#relu、softmax都為啟用函式
L1 = tf.nn.relu(tf.matmul(X,w1)+b1)
y = tf.nn.softmax(tf.matmul(L1,w2)+b2)
#二次代價函式:預測值與真實值的誤差
loss = tf.reduce_mean(tf.square(Y - y))
#梯度下降法:選用GradientDescentOptimizer優化器,學習率為0.5
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
#結果存放在一個布林型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(Y,1))
#求準確率
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))


#初始化變數,啟用tf框架
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for i in range(21):
    for batch in range(n_batch):
        batch_xs,batch_ys = mnist.train.next_batch(batch_size)
        sess.run(train_step,feed_dict=({X:batch_xs,Y:batch_ys}))
        acc = sess.run(accuracy,feed_dict={X:mnist.test.images,Y:mnist.test.labels})
    print("Iter " + str(i)+",Testing Accuracy "+str(acc))

效果展示:
這裡寫圖片描述

  • 迭代10次的準確率就已經到90.85%,對於現在的技術來說,這個準確率還是比較低的。CNN卷積神經網路對於更為複雜的圖片識別準確率都已經能達到98%以上,所以自己的學習之路還得百尺竿頭更進一步
  • 程式執行起來比較慢,大家全當學習了

—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-

系列推薦:

相關推薦

no