2017年8月23日 星期三

Weight initial for neural network

        正確的Weight initial 對Deep network 非常重要。只有1~2層時,weights 的初始化並不是太大問題,高斯分佈的標準差不要太大造成training 無法收斂就行。但當層數再四層以上,就不是這麼回事了,原因是每一層的運算,都會讓輸出值的分佈放大或是縮小(相對於輸入),所以愈到後面層,分佈範圍就會被放大愈多或是縮小愈多。下面為公式推導:X 為輸入,W為weights,S為輸出,n 為輸入層的neurons 個數

























這邊是假設輸入以及weight 都以0為平均,所以第3步的E(wi) 及 E(xi) 都是0 。可以看到輸出的分佈除了會被輸入的分佈影響外,還會被neurons 個數跟 weights 分佈影響。nVar(w) 過大,隨著層數會多,越發散。反之就愈來愈趨近於0 。

2017年7月6日 星期四

Backpropagation

      在training neural network 時,需要將 cost function 對每個變數作微分。因為network 很龐大的情況下,cost function 非常複雜,直接對每個變數做微分相當複雜且耗費資源。所以引進了 backpropagation  (BP)來完成這件事。BP 的原理其實就是利用微分的chain rule,先對每個local function 微分後,再從尾巴往前乘起來,結果就是cost function 對變數的微分。

        如下示意圖。變數X,Y 經過F function作用後再經過 G 的作用輸出。如果想計算G對X,Y的微分,先將每個local function 作微分 ( dG/dF , dF/dX, dF/dY) 。再從尾巴往前相乘,其結果就是G對X,Y的微分。這方法的好處是不管function 多複雜 ,只要把function 一步步用流程圖做拆解,對每個小部份做微分後(前題是可微分),從後往前乘就可以得到結果。因為與計算cost-function 計算是往前傳後不同,微分是由後往前計算,所以稱為back-propagation。
黑色為一般計算,由左往右。紅色微分由後往前傳












2017年6月8日 星期四

Tensorflow 使用筆記

Input 數據種類

tf.Variable 

通常用在model 中需要不斷更新的變數,像是需要training 的weights 或是在LSTM中不用training 但需更新的memory。

Creation :

宣告範例如下:
w = tf.Variable(<value>, name=<optional-name>)
name是變數的名稱,可加可不加
value 為要輸入的數據,格式為tensor。
以上只是宣告,但數據還沒有初始化。



初始化:

開始run data 前,必須先初始variable 裡的data。初始的方法我用過兩個,其中一個就是呼tensorflow 內建的 function " tf.global_variables_initializer() " 直接初始化。
ex:
with tf.Session() as session:
     tf.global_variables_initializer().run()
     ........

另一個方法是讀取之前儲存的model 參數:
ex:
saver = tf.train.Saver()
saved_file_path = "...saved model path..."
with tf.Session() as sess:
  # Restore variables from disk.
  ckpt = tf.train.get_checkpoint_state(saved_file_path)
  if ckpt and ckpt.model_checkpoint_path:
      saver.restore(sess,ckpt.model_checkpoint_path)


2017年5月27日 星期六

LSTM network introduction

RNN (recurrent neural network)

         LSTM (long short term memory) 是一種RNN network。RNN是一種可以記憶的神經網路,一般傳統的神經網路或是CNN( convolution neural network),神經元的資訊完全由當下輸入data貢獻,但某些問題像是語音辨識、語言翻譯,除了當下輸入的data,之前的data 也同樣重要。例如"I grew up in France…I speak fluent French ",假設後一個字"French"未知,我們可從前面"speak" 推測是某種語言,又從前文"grew up in France" 可推測為"French",因此前文的資訊是非常重要的。
          為了讓神經元保有前面的記憶,RNN神經元除了與當下輸入的data 連接,還跟過去的神經元連接,如下圖所示
出處:https://read01.com/N6n3Ba.html
Xt 是時間 t 輸入,A為神經網路,ht 為時間t 輸出。可以看到,網路A除了X貢獻,還從過去的網路貢獻,以此達到記憶的功能。

LSTM (long short term memory) 

       然而傳統的RNN 當連接的網路愈久遠,backpropagation 時的gradient 愈小,學習效果愈差(gradient vanish),也就是太久之前的記憶傳統RNN 很難學習。LSTM 就是來解決這個問題。傳統的RNN如下,與過去神經元連接只有一個tanh層運算
出處:https://read01.com/N6n3Ba.html


2017年4月28日 星期五

Python 畫圖工具整理

   在理解maching learning 時,發覺將data 可視化是非常重要的,整理目前python 畫圖工具及範例。

Matplotlib 畫圖工具

figure and subplot

所有的圖資訊都是在figure 物件中,figure 就像是畫布一樣,因此畫圖前必須先呼叫。subplot 是在figure 上定義有幾張圖表,如果沒有呼叫subplot,就是只有一張圖:

figure 範例:

from matplotlib import pylab as plt
plt.figure(figsize=(6,6))
plt.title('test')
plt.show()




















2017年4月27日 星期四

Word2Vec model Introduction (skip-gram & CBOW)

   在Udacity 的課程" Deep learning" 有學到如何處理文字數據,在此做個筆記,以免未來忘記
以下文字內容是我理解後整理的筆記,但codes 來自課程作業,不是我原創。Deep learning API為 tensorflow
課程網址:https://classroom.udacity.com/courses/ud730

Word2Vec

     要讓機器能夠學習,要學習事物必須定義其特徵,才有辦法學。像是腫瘤,如果要讓機器學會判定是良性或惡性,特徵可以定義為"腫瘤大小、密度、基因有無突變" 等等,然後將良性及惡性腫瘤特徵餵給機器學習。而Word2Vec就是一個將單一文字變成特徵向量的演算法

    文字跟圖像資料不同,圖像的理解主要跟自己圖內的pixel 排列組合有關,所以其特徵跟自身有關,但文字的理解由前後文的關係來決定。兩個不同的字例如 cat 跟 kitty ,如果再文章中出現時,前後文都一樣,就可判斷兩個是一樣意思的文字,特徵就要長一樣。而Word2Vec作法就是輸入文字,輸出預測其前後文字。model 是兩層全連接 neural network model (1 hidden layers) 。

假設data base 有N個vocabulary,model 示意圖如下:















Input layer

Input layer 是one-hot encoding ,Size 等於N.  Input layer 中每一個element 都對應一個vocabulary 中的words,0表示沒輸入,1表示輸入該word.

2017年4月7日 星期五

Installation of Nvidia driver/Cuda 8.0/Cudnn 5.1 on Ubuntu


系統&硬體配備

GPU: GTX1060 6G
OS system: Ubuntu 16.04.02

Driver 安裝 (版本 375.xx)



Step1: 禁用可能导致问题的开源驱动,编辑 /etc/modprobe.d/blacklist.conf

sudo vim /etc/modprobe.d/blacklist.conf
添加以下内容:

blacklist amd76x_edac
blacklist vga16fb
blacklist nouveau
blacklist nvidiafb
blacklist rivatv

Step2: 卸载干净所有安装过的nvidia驱动

sudo apt-get remove --purge nvidia-*

执行以下命令添加驱动源

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update

Step3:以下步骤建议 Ctrl+Alt+F1 切换到 tty1 执行

sudo service lightdm stop sudo apt-get install nvidia-375 nvidia-settings nvidia-prime sudo apt-get install mesa-common-dev (不確定用處,照網路上指示安裝) sudo apt-get install freeglut3-dev (不確定用處,照網路上指示安裝) sudo nvidia-xconfig (不確定用處,照網路上指示) sudo update-initramfs -u (實寄執行 出現問題) sudo reboot (重開機)

Step4: 輸入指令 "nvidia-smi"確認安裝成功
















2017年4月5日 星期三

找中位數 [C++]

在一維的float array1 中,找出中位數 (不包含等於0的數字)
我是另外建立一個同樣大小的array2, 初始值為0。 然後把array1 中的元素由小到大從左到右放入array2 中 再找出中位數。
////code////
float array1[10]={12.3 , 13.5 , 22.6 , 65.4 , 0 , 0 , 0 , 4.4 , 0 , 21};
float array2[10]={0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0};

/// 將 array1 由小排到大放到 array2 中 
int non_O_count=0;
int max_index=-1;
float median_num=0;
for (int i=0; i<10 0="" array1="" array2="" element="" for="" i="" if="" int="" j="" k="" max_index="" non_o_count="">j ; k--) array2[k]=array2[k-1];//較大的element 往右平移
            array2[j]=array1[i];
            max_index++;
            break;
         } 
      }
      if (j > max_index) array2[++max_index]=array1[i];//比現存所有element大,從最右插入
    } 
}

/// 計算中位數 ///
if (non_O_count != 0)
   if (non_O_count%2 != 0)
     median_num=array2[(int)(non_O_count/2.0+0.5)-1];
   else
     median_num=(array2[non_O_count/2-1] + array2[non_O_count/2] ) / 2;

結果如下