一、前述
ANN人工神經網路有兩個或兩個以上隱藏層,稱為DNN
只有一個隱藏層是多層感知機
沒有隱藏層是感知機
二、反向傳播應用舉例
舉例:
正向傳播,反向傳播是一次迭代,
正向傳播:在開始的每一層上都有一個引數值w,初始的時候是隨機的,前向帶入的是每一個樣本值。
反向傳播:然後反過來求所有的梯度值。如果是BGD則再根據公式wt=wt-1-ag進行調整所有w值。
然後再正向傳播,迭代,以此類推。
softmax通常用於最後一層的啟用函式
前面層用relu函式
三、啟用函式之Relu
公式:
解釋:
Rectified Linear Units
ReLU計算線性函式為非線性,如果大於0就是結果,否則就是0
生物神經元的反應看起來其實很像Sigmoid啟用函式,所有專家在Sigmoid上卡了很長時間,但是後
來發現ReLU才更適合人工神經網路,這是一個模擬生物的誤解
如果w為0,反過來梯度下降求導的時候每根線上的梯度都一樣。
程式碼:
import tensorflow as tf def relu(X): w_shape = (int(X.get_shape()[1]), 1) w = tf.Variable(tf.random_uniform(w_shape), name='weights') b = tf.Variable(0.0, name='bias') z = tf.add(tf.matmul(X, w), b, name='z') return tf.maximum(z, 0., name='relu') n_features = 3 X = tf.placeholder(tf.float32, shape=(None, n_features), name='X') relus = [relu(X) for i in range(5)]#list生成器 output = tf.add_n(relus, name='output')#將集合中的元素加和在一起 init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) result = output.eval(feed_dict={X: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]})#把裡面placehoder的值傳進來 print(result)
四、啟用函式和導數
五、DNN程式碼
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import numpy as np from tensorflow.contrib.layers import fully_connected # 構建圖階段 n_inputs = 28*28#輸入節點 n_hidden1 = 300#第一個隱藏層300個節點 對第一個隱藏層前面有784*300跟線去算 n_hidden2 = 100#第二個隱藏層100個節點 對第二個隱藏層300*300根線 n_outputs = 10#輸出節點 X = tf.placeholder(tf.float32, shape=(None, n_inputs), name='X') y = tf.placeholder(tf.int64, shape=(None), name='y') #自己手寫的實現邏輯 # 構建神經網路層,我們這裡兩個隱藏層,基本一樣,除了輸入inputs到每個神經元的連線不同 # 和神經元個數不同 # 輸出層也非常相似,只是啟用函式從ReLU變成了Softmax而已 # def neuron_layer(X, n_neurons, name, activation=None):# X是輸入,n_neurons是這一層神經元個數,當前隱藏層名稱,最後一個引數是加不加啟用函式 # # 包含所有計算節點對於這一層,name_scope可寫可不寫 # with tf.name_scope(name):#with讓程式碼看起來更加優雅一些 # # 取輸入矩陣的維度作為層的輸入連線個數 # n_inputs = int(X.get_shape()[1]) # stddev = 2 / np.sqrt(n_inputs)#求標準方差 # # 這層裡面的w可以看成是二維陣列,每個神經元對於一組w引數 # # truncated normal distribution(調整後的正態分佈) 比 regular normal distribution(正態分佈)的值小 # # 不會出現任何大的權重值,確保慢慢的穩健的訓練 # # 使用這種標準方差會讓收斂快 # # w引數需要隨機,不能為0,否則輸出為0,最後調整都是一個幅度沒意義 # init = tf.truncated_normal((n_inputs, n_neurons), stddev=stddev)#把初始引數隨機出來,比較小,不會出現大的權重值 # w = tf.Variable(init, name='weights') # b = tf.Variable(tf.zeros([n_neurons]), name='biases')#b可以全為0 # # 向量表達的使用比一條一條加和要高效 # z = tf.matmul(X, w) + b # if activation == "relu": # return tf.nn.relu(z) # else: # return z #自己手寫的實現邏輯 ''' with tf.name_scope("dnn"): hidden1 = neuron_layer(X, n_hidden1, "hidden1", activation="relu") hidden2 = neuron_layer(hidden1, n_hidden2, "hidden2", activation="relu") # 進入到softmax之前的結果 logits = neuron_layer(hidden2, n_outputs, "outputs") ''' #用Tensorflow封裝的函式 with tf.name_scope("dnn"): # tensorflow使用這個函式幫助我們使用合適的初始化w和b的策略,預設使用ReLU啟用函式 hidden1 = fully_connected(X, n_hidden1, scope="hidden1")#構建第一層隱藏層 全連線 hidden2 = fully_connected(hidden1, n_hidden2, scope="hidden2")#構建第二層隱藏層 全連線 logits = fully_connected(hidden2, n_outputs, scope="outputs", activation_fn=None)#構建輸出層 #注意輸出層啟用函式不需要 with tf.name_scope("loss"): # 定義交叉熵損失函式,並且求個樣本平均 # 函式等價於先使用softmax損失函式,再接著計算交叉熵,並且更有效率 # 類似的softmax_cross_entropy_with_logits只會給one-hot編碼,我們使用的會給0-9分類號 xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)#封裝好了損失函式 #把真實的Y值做onehot編碼 loss = tf.reduce_mean(xentropy, name="loss")#求平均 learning_rate = 0.01 with tf.name_scope("train"): optimizer = tf.train.GradientDescentOptimizer(learning_rate)#建立梯度下降的優化器 training_op = optimizer.minimize(loss)#最小化損失 with tf.name_scope("eval"):#評估 # 獲取logits裡面最大的那1位和y比較類別好是否相同,返回True或者False一組值 correct = tf.nn.in_top_k(logits, y, 1)#logits返回是類別號 y也是類別號 accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))#轉成1.0 0.0 init = tf.global_variables_initializer() saver = tf.train.Saver() # 計算圖階段 mnist = input_data.read_data_sets("MNIST_data_bak/") n_epochs = 400 #執行400次 batch_size = 50 #每一批次執行50個 with tf.Session() as sess: init.run() for epoch in range(n_epochs): for iterationo in range(mnist.train.num_examples//batch_size):#總共多少條/批次大小 X_batch, y_batch = mnist.train.next_batch(batch_size)#每次傳取一小批次資料 sess.run(training_op, feed_dict={X: X_batch, y: y_batch})#傳遞引數 acc_train = accuracy.eval(feed_dict={X: X_batch, y: y_batch})#每執行一次 看訓練集準確率 acc_test = accuracy.eval(feed_dict={X: mnist.test.images,#每執行一次 看測試集準確率 y: mnist.test.labels}) print(epoch, "Train accuracy:", acc_train, "Test accuracy:", acc_test) save_path = saver.save(sess, "./my_dnn_model_final.ckpt") # 使用模型預測 with tf.Session as sess: saver.restore(sess, "./my_dnn_model_final.ckpt") X_new_scaled = [...] Z = logits.eval(feed_dict={X: X_new_scaled}) y_pred = np.argmax(Z, axis=1) # 檢視最大的類別是哪個