1. 程式人生 > >python實現多層前饋神經網路(手寫體識別)

python實現多層前饋神經網路(手寫體識別)

前饋神經網路的圖例及推導過程見https://blog.csdn.net/u010089444/article/details/52555567,接下來我們用python語言實現多層前饋神經網路。本例使用的是MINST資料集,由輸入層,兩個隱藏層,輸出層. MNIST資料集中圖片的大小為28*28,即每張圖片可用一個28*28=784的向量表示.網路輸入層的維度是784, 第一層隱藏層包含625個啟用單元,第二層隱藏層包含500個啟用單元,因此輸入層到第一層隱藏層的權重矩陣維度是625*784,第一層到第二層隱藏層的權重矩陣維度是500*625,第二層隱藏層到輸出層的權重矩陣維度是10*500,即網路最後輸出一個10維向量,表示模型對圖片中數字的預測結果.具體程式碼如下:

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
#資料讀取
data_sets = input_data.read_data_sets("MNIST_data/", one_hot=True)
trX, trY, teX, teY = data_sets.train.images, data_sets.train.labels, data_sets.test.images, data_sets.test.labels
#佔位符
images_placeholder = tf.placeholder("float"
, [None, 784]) labels_placeholder = tf.placeholder("float", [None, 10]) #每一層都創建於一個唯一的tf.name_scope之下,創建於該作用域之下的所有元素都將帶有其字首 with tf.name_scope('hidden1') as scope1: weights1 = tf.Variable(tf.truncated_normal([784, 625], stddev=0.01), name='weights') #偏置變數維度大小,與weights中的[a,b]中的b相同 biases = tf.Variable(tf.zeros([625
]), name='biases') #第一層隱藏層 hidden1 = tf.nn.relu(tf.matmul(images_placeholder, weights1) + biases) with tf.name_scope('hidden2') as scope2: weights2 = tf.Variable(tf.truncated_normal([625, 500], stddev=0.01), name='weights') biases = tf.Variable(tf.zeros([500]), name='biases') #第二層隱藏層 hidden2 = tf.nn.relu(tf.matmul(hidden1, weights2) + biases) #輸出層,多少隱藏層可以自己定義,自己寫,多寫幾個scope with tf.name_scope('logits') as scope3: weights3 = tf.Variable(tf.truncated_normal([500, 10], stddev=0.01), name='weights') biases = tf.Variable(tf.zeros([10]), name='biases') logits = tf.matmul(hidden2, weights3) + biases #損失函式,格式需要寫出(logits='',lavels='',....) cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels_placeholder)) #採用梯度下降法,步長為0.05 train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost) #返回py_x中值最大的index作為預測結果 predict_op = tf.argmax(logits, 1) with tf.Session() as sess: sess.run(tf.initialize_all_variables()) for i in range(100):#計算100for start, end in zip(range(0, len(trX), 128), range(128, len(trX) + 1, 128)): sess.run(train_op,feed_dict={images_placeholder: trX[start:end], labels_placeholder: trY[start:end]}) #輸出準確率 print(i, np.mean(np.argmax(teY, axis=1) ==sess.run(predict_op, feed_dict={images_placeholder: teX, labels_placeholder: teY})))

迴圈訓練部分程式碼借鑑了https://blog.csdn.net/u010089444/article/details/52563514,前饋神經網路隱藏層的數量可以自己定義,自己編寫程式碼,還可以更改啟用函式,調整其他引數進行實驗,本次迴圈訓練100次,結果如下,準確率達到97.95%:

80 0.9793
81 0.9794
82 0.9794
83 0.9793
84 0.9793
85 0.9793
86 0.9793
87 0.9794
88 0.9793
89 0.9793
90 0.9793
91 0.9792
92 0.9793
93 0.9793
94 0.9794
95 0.9794
96 0.9794
97 0.9794
98 0.9794
99 0.9795