用tensorflow搭建全鏈接神經網絡實現mnist數據集的識別

  I 前向傳播網絡搭建python

  在mnist_forward.py中搭建兩層全鏈接網絡,這裏面就是定義層數,節點數,激活函數這些。git

  輸入節點數目就是mnist數據集的圖片28*28大小,用784行的向量做爲輸入。網絡

  第一層y1=relu(x*w1+b1 )其中y1爲500行的向量。那麼w1裏面就有784*500個變量啦~~b1是500個變量。而後通過一個relu激活函數。app

  第二層就是從500節點變換到10個節點的輸出,輸出爲標籤,表示0-9手寫數字出現的機率。y=y1*w2+b2。w2就是500*10的矩陣。b2是10行的向量。沒有激活函數。ide

  這裏面w1 b1 w2 b2就是要訓練的參數函數

  採用了正則化學習

  正則化就是在損失函數中給每一個參數w加上權重,引入模型複雜度指標,從而抑制模型噪聲,減小過擬合。這裏使用的是L2正則化,即w的L2範數也是loss的一部分,也就是說在求解最優w的過程當中,要使得w的值儘可能在0附近。spa

  

在這裏插入圖片描述


  import tensorflow as tform

  INPUT_NODE = 784blog

  OUTPUT_NODE = 10

  LAYER1_NODE = 500

  def get_weight(shape,regularizer):

  w = tf.Variable(tf.truncated_normal(shape,stddev=0.1))

  # 截斷正態分佈

  if regularizer != None: tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))

  # 使用正則化 L2範數 將每一個參數的正則化損失加到總損失中

  return w

  def get_bias(shape):

  b = tf.Variable(tf.zeros(shape))

  return b

  def forward(x,regularizer):

  w1 = get_weight([INPUT_NODE,LAYER1_NODE],regularizer)

  b1 = get_bias([LAYER1_NODE])

  y1 = tf.nn.relu(tf.matmul(x,w1) + b1)

  w2 = get_weight([LAYER1_NODE,OUTPUT_NODE],regularizer)

  b2 = get_bias([OUTPUT_NODE])

  y = tf.matmul(y1,w2) + b2

  return y

  II偏差反向傳播

  在mnist_backward.py中讀入mnist數據集,計算偏差,進行偏差反向傳播,實現模型的訓練,獲得網絡參數並保存在模型中

  2.1 loss

  loss的計算先用softmax把輸出的10行向量變成機率分佈,再與真實的輸出標籤進行對比,求交叉熵。cross entropy 能夠看做是兩個機率分佈函數之間的距離。距離越小,說明預測越準確,loss越小。

  2.2 學習率

  學習率是每次沿着梯度降低方向進行參數更新的步長,步長過大會致使在最優勢震盪,步長太小會致使學習速度太慢。這裏採用了指數衰減的步長。在訓練初始階段,步長較大,較快收斂,在最優勢附近,步長較小,可以獲得較精確的最優解。

  2.3 滑動平均

  記錄一段時間內模型中全部參數w和b的各自的平均值。用於加強模型的泛化能力。

  import tensorflow as tf

  import mnist_forward

  import os無錫婦科醫院 http://www.bhnnk120.com/

  os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

  from tensorflow.examples.tutorials.mnist import input_data

  BATCH_SIZE = 200 #每次輸入的圖片數

  LEARNING_RATE_BASE = 0.1 #初始學習率

  LEARNING_RATE_DECAY = 0.99 #學習率衰減率

  REGULARIZER = 0.0001 #正則化係數

  STEPS = 10000 #訓練輪數

  MOVING_AVERAGE_DECAY = 0.99

  MODEL_SAVE_PATH="./model/"

  MODEL_NAME = "mnist_model"

  def backward(mnist):

  x = tf.placeholder(tf.float32,[None,mnist_forward.INPUT_NODE])

  y_ = tf.placeholder(tf.float32,[None,mnist_forward.OUTPUT_NODE])

  y = mnist_forward.forward(x,REGULARIZER)

  global_step = tf.Variable(0,trainable = False)

  # step計數 不可訓練的參數

  ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = y, labels = tf.argmax(y_,1))

  cem = tf.reduce_mean(ce)

  loss = cem + tf.add_n(tf.get_collection('losses'))

  learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY,staircase=True)

  train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step = global_step)

  ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)

  ema_op = ema.apply(tf.trainable_variables())

  # ema.apply()對括號內參數求滑動平均

  # tf.trainable_variables() 將全部能夠被訓練的參數彙總爲list 也就是[w1 b1 w2 b2]

  with tf.control_dependencies([train_step, ema_op]):

  train_op = tf.no_op(name='train')

  # 該函數實現將滑動平均和訓練過程同步運行。

  saver = tf.train.Saver()

  with tf.Session() as sess:

  init_op = tf.global_variables_initializer()

  sess.run(init_op)

  for i in range(STEPS):

  xs,ys = mnist.train.next_batch(BATCH_SIZE)

  _, loss_value, step = sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys})

  if i%1000 == 0:

  print("After %d training steps, loss on training batch is %g." %(step,loss_value))

  saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step=global_step)

  if __name__ == '__main__':

  mnist = input_data.read_data_sets('./data/',one_hot=True)

  backward(mnist)

  III 運行代碼

  在Terminal裏面激活tensorflow,運行python mnist_backward.py

  就能夠輸出訓練過程的loss,每1000步打印一次loss。從下圖能夠看出,loss逐漸減少。

相關文章
相關標籤/搜索