使用tensorflow開源框架構建一個手寫數字識別項目的代碼詳解(1)——前向傳播

當然在學習本課程之前,我們需要明白在TensorFlow的世界裏,變量的定義和初始化是分開的,所有關於圖變量的賦值和計算都要通過tf.Session的run來進行。想要將所有圖變量進行集體初始化時應該使用tf.global_variables_initializer。而我們這篇文章進行的工作是定義前向傳播。

mnist_forward.py文件詳情:

import tensorflow as tf

INPUT_NODE = 784
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))
    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

接下來是對代碼的詳解:

(1)第一步我們需要明白我們構建的神經網絡的節點數。

INPUT_NODE是輸入數據的維數,也就是28*28個。

OUTPUT_NODE是輸出數據的維數,因爲最後輸出的結果是一組一行10列的數組,其值是代表出現某一個數字的概率,所以維數爲10。

LAYER1_NODE是中間隱藏層的節點數,共有500個節點。

現在我們明白了我們構建的是一個簡單的雙層全連接神經網絡。

(2)我們注意到我們的權重和偏置都是使用的Variable()函數產生,所以我們來細講一下這個函數。

tf.Variable.init(initial_value, trainable=True, collections=None, validate_shape=True, name=None)

參數名稱 參數類型 含義
initial_value 所以可以轉化爲tensor類型 變量的初始值
trainable bool 如果爲True,會把它加入到GraphKeys.TRAINABLE_VARIABLES,才能對它使用Optimizer
collections list 指定該圖變量的類型、默認爲[GraphKeys.GLOBAL_VARIABLES]
validate_shape bool 如果爲False,則不進行類型和維度檢查。
name string 變量的名稱,如果沒有指定則系統會自動分配一個唯一的值

當然還有其他的參數,如果想了解更多可以去官網。

關於兩個常用的initial_value(tf.truncated_normal()和tf.random_normal())的區別可以通過以下鏈接學習。

https://blog.csdn.net/u014687582/article/details/78027061

 

(3)到這裏我們已經將神經網絡的節點和其中的參數設置完成了,最後我們需要把這些節點連接起來,以構成一幅完整的計算圖。

我們使用tf.matmul()函數對兩個tensor進行運算(這裏類似於高等代數裏面兩個矩陣相乘),之後使用激活函數tf.nn.relu()將偏置數b加上去。

之後我們注意到我們的權重w的shape是[INPUT_NODE,LEARY1_NODE],根據矩陣相乘的算法,[INPUT_NODE] * [INPUT_NODE, LAYER1_NODE] = [LAYER1_NODE] (第一個隱藏的節點數的值),[LAYER1_NODE] * [LAYER1_NODE, OUTPUT_NODE] = [OUTPUT_NODE]。

tf.nn.relu()激活函數的講解:

tf.nn.relu()函數是將大於0的數保持不變,小於0的數置爲0。


import tensorflow as tf

 

a = tf.constant([[-2,-4],[4,-2]])

with tf.Session() as sess:

 	print(sess.run(tf.nn.relu(a)))

 

輸出的結果爲:


[[0 0]

 [4 0]]

 

 


(4)最後我們注意還有一個regularizer參數沒有解釋,這個是正則化的超參數。

正則化緩解過擬合

正則化的損失函數中引入模型複雜度指標,利用給W加權值,弱化了訓練數據的噪聲(一般不正則化b)

                loss = loss(y與y_)  + REGULARIZER * loss(w)

loss(y與y_)是指模型中所有參數的損失函數,如:交叉熵,均方誤差

REGULARIZER是用超參數REGULARIZER給出參數w在總loss中的比例,即正則化的權重

loss(w)是 指需要正則化的參數

其中loss(w)的代碼爲以下兩種:

loss(w) = tf.contrib.layers.l1_regularier(REGULARIZER)(w) 

loss(w) = tf.contrib.layers.l2_regularier(REGULARIZER)(w) 

這裏還涉及到add_to_collection()函數的使用,可以參考這個鏈接:https://blog.csdn.net/nini_coded/article/details/80528466

最後謝謝大家。

 

 

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