TensorFlow系列 #003

TensorFlow入門——神經網絡結構、前向傳播算法實現

一、神經網絡的實現

1、TensorFlow Playground


數據點

  • 二維平面的數據集中,每一個小點代表一個樣例,點的顏色代表了樣例的標籤,點的顏色有兩種,因此構成一個二分類的問題。
  • 黃色的點表示合格的零件,藍色的點表示不合格的零件。判斷一個零件是否合格的問題就轉變成區分點的顏色的問題。
  • 零件的特徵提取:用零件的長度和質量來描述一個零件,,將一個物理意義上的零件轉化成長度和質量兩個數字。
  • 在機器學習中,所有用於描述實體的數字的組合就是一個實體的特徵向量(feature vector)。通過特徵提取,可以將實際問題中的實體轉化爲空間中的點。
  • 舉例:FEATURES對應特徵向量,x1代表零件的長度,x2代表零件的質量。

輸入輸出

  • 特徵向量是神經網絡的輸入
  • 第一層是輸入層,代表特徵向量中每一個特徵的取值,如x1 = 0.5表示一個零件的長度爲0.5。
  • 在二分類問題中,如判斷零件是否合格,神經網絡的輸出層往往只包含一個節點,這個節點輸出一個實數值,通過這個輸出值和一個事先設定的閾值,可以得到最後的分類結果。
  • 舉例:判斷零件是否合格時,當輸出的數值大於0時,給出的判斷結果是零件合格,反之零件不合格,一般認爲當輸出值離閾值越遠時得到的答案越可靠。

隱藏層

  • 輸入和輸出層之間的神經網絡叫做隱藏層,一個神經網絡的隱藏層越多,這個神經網絡越深,深度學習中的深度和神經網絡的深度密切相關。
  • 支持修改的參數:
    • 隱藏層的數量 hidden layer
    • 學習率 learning rate
    • 激活函數 activation
    • 正則化 regularization

訓練結果

  • 一個小格子代表神經網絡中的一個節點!
  • 邊代表節點之間的連接,每一條邊代表盛景網絡中的一個參數,可以是任意實數。
  • 神經網絡通過對參數的合理設置來解決分類或者回歸問題。邊上的顏色體現了這個參數的取值,邊的顏色越深,這個參數取值的絕對值越大;邊的顏色接近白色時,參數的取值接近於0.
  • 每一個節點上的顏色代表了這個節點的區分平面。如果把這個平面當成一個笛卡爾座標系,這個平面上的每一個點就代表了(x1,x2)的一種取值。點的顏色就體現了x1,x2在這種取值下這個節點的輸出值。節點的輸出值的絕對值越大時,顏色越深。
  • 舉例:**輸入層x1代表的節點的區分平面就是y軸。(理解?)**因爲這個節點的輸出就是x1本身的值,所以當x1小於零時,這個節點的輸出就是負數,而x1大於0時,輸出的就是正數。於是y軸的左側都爲黃色,右側都爲藍色

總結:使用神經網絡解決分類問題的步驟

  1. 提取問題中實體的特徵向量作爲神經網絡的輸入。不同的實體可以提取不同的特徵向量。
  2. 定義神經網絡的結構,並定義如何從神經網絡的輸入得到輸出。這個過程就是神經網絡的錢箱傳播算法。
  3. 通過訓練數據來調整神經網絡中參數的取值,這就是訓練神經網絡的過程。
  4. 使用訓練好的神經網絡來預測未知的數據。

二、前向傳播算法——全連接網絡

1、神經元結構

  • 神經元是構成一個神經網絡的最小單元
  • 一個神經元有多個輸入和一個輸出。每個神經元的輸入既可以是其他神經元的輸出,也可以是整個神經網絡的輸入。神經網絡的結構就是指不同神經元之間的連接結構。
  • 一個最簡單的神經元結構的輸出就是所有輸入的加權和,不同輸入的權重就是神經元的參數。
  • 神經網絡的優化過程就是優化神經元中參數取值的過程。
  • 舉例:一個簡單的判斷零件是否合格的三層全連接網絡。全連接神經網絡是指相鄰兩層之間任意兩個節點之間都有連接。
  • 全連接神經網絡結構與卷積層,LSTM結構相區別。

2、前向傳播過程

  • 前向傳播過程解析[BOOK]
  • 計算神經網絡的前向傳播需要三部分信息:
    1. 神經網絡的輸入
    2. 神經網絡的連接結構
    3. 每個神經元的參數
  • 用矩陣乘法表示前向傳播算法中的加權和
  • 舉例:xW(1)a(1)W(2)y
    • a(1) = x*W(1)
    • y = a(1)*W(2)
  • Tensorflow實現:
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
  • 總結tf.matmul可以實現矩陣乘法的功能
  • 其他支持的神經網絡:
    • 更加複雜的神經元結構:偏置(bias)、激活函數(activation function)
    • 更加複雜的神經網絡:卷積神經網絡、LSTM結構

3、神經網絡參數與TensorFlow變量

  • 變量(tf.Variable)的作用是保存和更新神經網絡中的參數
  • 使用隨機數給TensorFlow中的變量初始化:
    weights = tf.Variable(tf.random_normal([2,3],stddev=2))
    # tf.random_normal[2,3],stddev=2)產生一個2×3矩陣,元素是均值爲0,標準差爲2的隨機數
    # tf.random_normal函數可以通過參數mean來指定平均值,在沒有指定時默認爲0
    
  • 總結:通過滿足正態分佈的隨機數來初始化神經網絡中的參數是一個非常常用的方法
  • 其他隨機數生成器:
函數名稱 隨機數分佈 主要參數
tf.random_normal 正態分佈 平均值、標準差、取值類型
if.truncted_normal 正態分佈,但如果隨機出來的值偏離平均值超過2個標準差,那麼這個數將會被重新隨機 平均值、標準差、取值類型
tf.random_uniform 平均分佈 最小、最大取值,取值類型
tf.random_gamma Gamma分佈 形狀參數alpha、尺寸參數beta、取值類型
  • 常量聲明方法
函數名稱 功能 樣例
tf.zeros 產生全0的數組 tf.zeros([2,3],int32)->[[0,0,0],[0,0,0]]
tf.ones 產生全1的數組 tf.omes([2,3],int32)->[[1,1,1],[1,1,1]]
tf.fill 產生一個全部爲給定數字的數組 tf.fill([2,3],9)->[[9,9,9],[9,9,9]
tf.constant 產生一個給定值的常量 if.comstant([1,2,3])->[1,2,3]
  • 偏置項通常會使用常數來設置初始值
biases = tf.Variable(tf.zeros([3]))
# 生成一個初始值全部爲0且長度爲3的變量
  • 使用其他變量的初始值來初始化新的變量
w2 = tf.Variable(weights.initialized_value())
w3 = tf.Variable(weights.initialized_value()*2.0)
# w2的初始值設置成與weights變量相同,w3的初始值設置成wieghts初始值的兩倍
  • 實現神經網絡前向傳播過程【重要案例】
import tensorflow as tf
# 聲明w1、w2兩個變量。通過seed參數設定隨機種子(僞隨機數)
# 這樣可以保證每次運行得到的結果是一樣的。
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variale(tf.random_normal([3,1],stddev=1,seed=1))
# 暫時將輸入的特徵向量定義爲一個常量。注意這裏x是一個1*2的矩陣。
x = tf.constant([[0.7,0.9]]) # ??? 爲什麼有兩層括號
# 構建前向傳播算法的神經網絡全連接結構
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

sess = tf.Session()
# 這裏不能直接通過sess.run(y)來獲取y的取值,
# 因爲w1和w2都還沒有運行初始化過程。下面的兩行分別初始化了w1和w2兩個變量。
sess.run(w1.initializer) # 初始化w1
sess.run(w2.initializer) # 初始化w2
# 輸出[[3.95757794]]
print(sess.run(y))
sess.close()
  • 分析:以上程序直接調用每個變量的初始化過程是一個可行的方案,但是當變量數目增多,或者變量之間存在依賴關係時,單個調用的方案就比較麻煩。TensorFlow提供了一種更加快捷的方式倆完成變量初始化過程。 tf.initialize_all_variavles函數實現所有變量的初始化。
init_op = tf.initialize_all_variables()
sess.run(init_op)
  • 變量和張量的關係:
    TensorFlow的核心概念是張量(tensor),所有的數據都是通過張量的形式來組織的。變量聲明函數tf.Variable是一個運算,則個運算的輸出結果就是一個張量,這個張量就是之前提到的變量。所以變量只是一種特殊的張量。

  • tf.Variable操作在TF中的底層實現,總結

    • w1是一個Variable運算
    • 初始化變量w1的操作是通過Assign操作完成的
    • Assign節點的輸入爲隨機數生成函數的輸出,輸出賦值給了變量w1
    • w1通過一個read操作將值提供給了一個MatMul乘法運算tf.matmul(x,w1)
  • TensorFlow中所有的變量會被自動的加入GraphKeys.VARIAVLES集合。通過tf.all_variables函數可以拿到當前計算圖上所有的變量。拿到計算圖上所有的變量有助於持久化整個計算圖的運行狀態**(不理解!…)**。

  • 構建機器學習模型時,比如神經網絡,可以通過變量聲明函數中的trainable參數來區分需要優化的參數(比如神經網中的參數)和其他參數(比如迭代的輪數)。如果聲明變量時參數trainable爲True,那麼這個變量將會被加入GraphKeys.TRAINABLE_VARIABLES集合。

  • 通過tf.trainable_variables函數得到所有需要優化的參數。TensorFlow中提供的神經網絡優化算法會將GraphKeys.TRAINABLE_VARIABLES集合中的變量作爲默認的優化對象。

  • 類似張量,維度(shape)和類型也是變量最重要的兩個屬性。一個變量在構建之後,變量的類型是不可改變的。兩個不同類型的變量賦值會報出類型不匹配的錯誤。

  • 示例代碼:

w1 = tf.Variable(tf.random_normal([2,3],stddev=1),name = 'w1')
w2 = tf.Variable(tf.random_normal([2,3],dtype=tf.float64,stddev=1),name="w1")
w1.assign(w2)

# 程序報錯: 
# TypeError:Input 'value' of 'Assign' Op has type float64 that does not match type float32 of argument 'ref'.
  • TensorFlow支持更改變量的維度,通過設置參數validete_shape=False,但該用法在實踐中比較罕見
  • 示例代碼:
w1 = tf.Varialble(tf.random_normal([2,3],stddev=1),name="w1")
w2 = tf.Varialble(tf.random_normal([2,2],stddev=1),name="w2")
# tf.assign(w1,w2)
# 維度不匹配報錯,ValueError:Shapes(2,3)and (2,2) are not compatible
# 應改爲下面的語句
tf.assign(w1,w2,validate_shape=False)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章