當然在學習本課程之前,我們需要明白在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
最後謝謝大家。