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逐漸減少。