2016年10月9日 星期日

AI - Ch16.5 類神經網路實作 - TensorFlow 介紹與入門教學

 

實作類神經網路對於了解類神經網路的架構是很有幫助的,不過使用框架也省略了很多數學的細節和證明,理論和實作還是缺一不可阿!

常見的NN框架有下面這些:

  • Torch
  • Caffe
  • Theano (Keras, Lasagne)
  • CuDNN
  • Tensorflow
  • Mxnet

這篇是選用 TensorFlow 當練習! 下面是一些類神經網路框架比較的小八卦,大家可以參考一下~  準備好就要開始上工囉XD






一、安裝


安裝前先安裝 pip 和 virtualenv,分別是套件管理程式和虛擬環境模擬器。
詳見:Python的模組與套件

輸入以下指令就輕鬆裝好囉!

# Ubuntu/Linux 64-bit, CPU only, Python 3.5
$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.11.0rc0-cp34-cp34m-linux_x86_64.whl

# 有CUDA的話可改裝下面GPU版來加速(但沒有CUDA的話會報錯)
# Ubuntu/Linux 64-bit, GPU enabled, Python 3.5
# Requires CUDA toolkit 7.5 and CuDNN v5. For other versions, see "Install from sources" below.
$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.11.0rc0-cp35-cp35m-linux_x86_64.whl

# Python 3
$ sudo pip3 install --upgrade $TF_BINARY_URL


安裝成功會印出安裝成功的訊息,並可用 python 交互模式印出版本訊息:

Successfully installed numpy-1.11.2 setuptools-28.2.0 tensorflow-0.11.0rc0

>>> import tensorflow as tf
>>> tf.__version__  
'0.11.0rc0'
>>> 


[註1] ubuntu用戶可能會缺少tk包導致執行失敗,補安裝即可解決^^

sudo apt-get install python3-tk


其他細節詳見官方安裝文件:Download and Setup





二、TensorFlow 中的基本運算


Numpy 和 TensorFlow 都使用n-維數據,大抵使用非常相似,需要注意的是 TensorFlow 中的 tensor 要在 session 執行中才會有真正的數值。






三、TensorFlow 架構


一個 TensorFlow graph 描述了計算的過程。

graph 在 session 中啟動並將 graph 的 op. (operation) 分發到 CPU 或 GPU 設備上。執行後將產生的 tensor 回傳。(Python 返回的 tensor 是類似 numpy ndarray 的結構)

基本名詞:

  • graph : 表示一整個計算任務
  • op. : graph 中的節點,也就是對資料的操作
  • Session : 在 Session 中才會執行 graph
  • tensor : 表示數據資料,a multidimensional array of numbers
  • variable : 表示變數資料,負責維護狀態
  • feed 和 fetch : 賦值或者從其中獲取數據

TensorFlow 簡易流程:

  1. 製作 Graph:宣告 op. 表示資料操作(常數、運算子等等)
  2. 宣告 Variable:用變數儲存狀態
  3. 初始化 Variable
  4. 開啟 Session 執行 Graph


[範例1] 基本運算程式


用最簡單的 TensorFlow 結構印出矩陣計數器的值和亂數;理解這些結構後,用來實作一般的矩陣運算任務也是很容易的。

# 1.






matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.], [2.]])
matrix3 = tf.ones((2,2))
matrix4 = tf.random_normal((2,2))

product = tf.matmul(matrix1, matrix2)
add = tf.assign_add(matrix_buf, matrix3)
assign = tf.assign(matrix_buf, matrix4)


# 2.
matrix_buf = tf.Variable(tf.zeros((2,2)))
# 3.
init = tf.initialize_all_variables()

# 4.
with tf.Session() as sess: sess.run(init) print(product.eval(),"\n") #.eval() 是 sess.run() 的語法糖 for _ in range(3): sess.run(add) print(matrix_buf.eval()) sess.run(assign) print("\n",matrix_buf.eval(),"\n")


[範例1] 執行結果






四、第一支類神經網路程式



[範例2] 類神經網路程式 : 簡單迴歸


這是一個用類神經網路做 regression 的程式。整體程式結構是:

  1. 模擬一些要學習的資料點
  2. 用 placeholder 傳入值 (後面用 feed_dict 餵資料) 
  3. 用 add_layer 畫 Graph
  4. 設定要用 Gradient Descent 的 loss function
  5. 初始化變數
  6. 開啟 Session 執行 Graph

Gradient Descent 在 TensorFlow 已經封裝好可以直接用,所以 Graph 中的 Weights 和 Bias 不用自己更新值。

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

def add_layer(inputs, in_size, out_size, activation_function=None):
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
    Wx_plus_b = tf.matmul(inputs, Weights) + biases #matrix multiply

    if activation_function is None:
        outputs = Wx_plus_b
    else:
        outputs = activation_function(Wx_plus_b)

    return outputs

### Create Data : poly. + noise
x_data = np.linspace(-2,2,600)[:,np.newaxis]
noise = np.random.normal(0,0.8,x_data.shape)
# y_data_ori = 1.5*np.power(x_data,3) + 2*np.power(x_data,2) + 1
y_data_ori = 2*x_data + 2 * np.sin(x_data/0.5)
y_data = y_data_ori + noise

xs = tf.placeholder(tf.float32,[None,1])
ys = tf.placeholder(tf.float32,[None,1])

### Create NN graph
l1 = add_layer(xs, 1,  10, activation_function=tf.nn.relu)
prediction = add_layer(l1 , 10 , 1 , activation_function=None)

# Set Learning Parameter
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_data - prediction),reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

# initial tensorflow variables
init = tf.initialize_all_variables()

# initial graph
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data, y_data)
plt.ion()
plt.show()

with tf.Session() as sess:
    sess.run(init)

    for i in range(1500):
        sess.run(train_step, feed_dict={xs:x_data, ys:y_data})

        # predict and plot the result
        if i % 50 ==0:
            print(sess.run(loss,feed_dict={xs:x_data, ys:y_data}))
            try:
                ax.lines.remove(lines[0])
            except Exception:
                pass

            prediction_value = sess.run(prediction, feed_dict={xs: x_data})
            # plot the prediction
            lines = ax.plot(x_data, prediction_value, 'r-', lw=5)
            plt.pause(0.2)

    lines = ax.plot(x_data, y_data_ori,'g-', lw=3)
    plt.pause(30)


[範例2] 執行結果 (執行時是動畫喔!)

要注意的是,並不是每次訓練都會成功,可能因一開始的隨機權重而使結果不同。

  • 藍點:訓練資料(目標函式+白雜訊)
  • 紅線:類神經網路訓練結果
  • 綠線:目標函式


terminals 會印出每次更新後 loss 的值 :



[debug] 印出來全是 NAN?:極有可能是 sum 太大時的bug,可以減少 neuron 或縮小初始 weights standard distribution






五、小結:可視化工具 TensorBoard 與 NN play ground


TensorFlow 提供一個很好玩的網站可以視覺化簡單的類神經網路,介面非常漂亮~ 讓懶得寫code的人也可以一飽眼福!

TensorFlow play ground
http://playground.tensorflow.org/

TensorFlow 裡也附帶了強大的視覺化工具 TensorBoard 做報告、概覽程式結構、debug都非常好用。

想深入研究的人可以參考references裡的資料,網路上資源很豐富,TensorFlow官方文檔寫的也非常簡潔,TensorFlow 真的是一個很友善的類神經網路實作工具^^








References


莫煩python教學 - Tensorflow tutorial Python (Eng Sub)
https://www.youtube.com/playlist?list=PLXO45tsB95cKI5AIlf5TxxFPzb-0zeVZ8

courses_MLSD
http://speech.ee.ntu.edu.tw/~tlkagk/courses_MLSD15_2.html

tensorflow.org
https://www.tensorflow.org/versions/r0.11/get_started/index.html

aymericdamien/TensorFlow-Examples
https://github.com/aymericdamien/TensorFlow-Examples

MorvanZhou/tutorials
https://github.com/MorvanZhou/tutorials/tree/master/tensorflowTUT

nivwusquorum/tensorflow-deepq
https://github.com/nivwusquorum/tensorflow-deepq

TensorFlow 官方文档中文版
http://wiki.jikexueyuan.com/project/tensorflow-zh/






技術提供:Blogger.