2017年1月7日 星期六

深度學習(1)-如何在windows安裝Theano +Keras +Tensorflow並使用GPU加速訓練神經網路


本篇文章介紹如何安裝Theano 及Keras, Tensorflow深度學習的框架在windows環境上,並快速的使用Keras的內建範例來執行人工神經網路的訓練。

     之前也有實作Tensorflow 及caffe在VM+ubuntu16.04環境安裝的經驗,甚至安裝在NVIDIA的Jetson TX1 的慘痛經驗XD(雖然後來也是有安裝成功)。各深度學習的框架各有它的優缺點,有許多文章已做過類似的分析,在此我不會對這部分著墨太多,只會敘述自己之前安裝的一些經驗來提供大家參考,特別如果是要在windows環境上使用,並且具有NVIDIA CUDA支援GPU加速運算的功能。
      雖然也很多人認為應該直接使用Linux環境會比較適合做深度學習框架的使用及學習,原因是使用Linux的人或網路資源比較多,而且Linux對於電腦硬體效能有優化。但對於Linux環境不熟的人,使用windows環境仍然有它方便性存在,而對於Python程式語言來說,其程式碼在Linux環境或windows環境做切換是很容易的,當然Theano ,Keras,Tensorflow也可以安裝在Linux環境上使用。接下來開始正式介紹如何在一般常見的筆電上建構這個環境,在一般的筆電上也可以使用GPU加速訓練人工神經網路的快感。


<圖一>為Keras 的lstm_benchmark.py 範例輸出結果






首先我使用的筆電硬體是:
Intel CPU i7-6700HQ
記憶體DDR3 8GB.
NVIDIA 950M

另一台筆電硬體是:
Intel CPU i5 5200U
記憶體DDR3 8GB.
NVIDIA 940M

使用GPU加速及CUDA ,NVIDIA 的顯卡仍然是必備,但是實際上測試最一般般常見
的940M ,950M顯卡也可以使用,並且實測上其執行效能仍然快過單單使用CPU快很多
,底下安裝好後我們會使用Theano提供的程式來做測試及比較。

接下來是軟體環境的建構,大部分步驟其實是沒有先後順序之分的,例如先安裝python
或是VS2015 ,只有少數步驟有先後順序上的建議。底下是我的安裝步驟。

1.安裝Python 環境:
    選擇Anaconda或是Winpython都可以,實際上我都試過,而最後我是在Winpython上安裝成功,這並不代表Anacona不行,只是剛好在Winpython上裝成功就沒再花心思在Anaconda上做Debug。重點是要使用x64 python 勿使用x86版本,原因是CUDA 的CUBLAS.lib只適用於x64版本,如果使用x86版本會遇到CUBLAS.lib 的相關error.

Winpython下載路徑:https://winpython.github.io/
在此我是選擇安裝:WinPython-64bit-3.5.2.3Qt5.exe
3.5.2版帶有Qt5的,因為平時也有用到Qt5,所以就一起安裝這並不影響後續安裝。

2.安裝VS2015 update 3:
     現在VS2015已有免費的社群版,然而我安裝的另外從網路上下載的VS2015 pro update3 英文版。這邊建議要安裝英文版勿安裝中文版,原因是先前遇過vs2015在編譯CUDA時候遇到Unicode編碼的問題,所以就乾脆安裝英文版。而如果直接安裝社群版,MS會根據你的OS 環境語系自動選擇則中文版。在windows環境裡,VS2015會是用來編譯CUDA的工具。
我安裝的Windows環境是Windows 10,並且它自己已經明目張膽,大搖大擺,無視你的存在的更新到10.0.14393.0了(XD)。

安裝後須將底下路徑加入系統的環境變數path ,這樣在命令視窗才找得到cl.exe。
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

3.安裝GCC:

在windows 要安裝GCC 可以使用MSYS2,有關MSYS2的安裝請看底下連結:
寫得非常清楚了,也不難安裝,在此選擇x86_x64版本可以安裝的指定的D:\或預設C:\下。
https://shaochien.gitbooks.io/how-to-use-gcc-to-develop-c-cpp-on-windows/content/shell-select-and-install-gcc.html

安裝後須將底下路徑加入系統的環境變數path ,這樣在命令視窗才找得到gcc或g++。
D:\msys64\mingw64\bin
D:\msys64\mingw64\lib


4.安裝CUDA 及CuDNN:

CUDA 下載網址:https://developer.nvidia.com/cuda-downloads
選擇CUDA 8.0 for Win 10 x64版本

CuDNN 下載網址:https://developer.nvidia.com/cudnn
請選擇對應到CUDA 8.0的版本。
需註冊(免費)才能下載CuDNN,非必要但是CuDNN並不難安裝,只需要解壓縮CuDNN檔案
然後將裡面bin/lib/include/的檔案都copy到CUDA安裝後對應的bin/lib/include/資料夾即可。
CUDA 0 安裝成功預設路徑應如同底下(請勿自行更改路徑)
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0

安裝好後將底下路徑也加入系統的環境變數path ,這樣在命令視窗才找得到nvcc。
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\libnvvp


5.安裝Theano 及Keras:
   實際上當安裝好Winpython時已經同時包含Theano 及Keras了。可以不用再安裝。
預設Theano 版本是0.8.2,Keras 是1.1.1。
如果需update theano,或 keras到最新版1.2.0
可以執行以下指令
pip install --upgrade Theano
pip install --upgrade keras
注意:一但你執行上述指令它會自動
Uninstalling numpy-1.11.2+mkl:
原因是pip自動搜尋到更新的
numpy-1.11.3-cp35-none-win_amd64.whl版本
但是這numpy版本並不帶mkl涵式庫,但這對Theano ,keras是必要的。
所以可以到底下連結重新下載新的numpy-1.12.0rc2+mkl-cp35-cp35m-win_amd64.whl
然後在你的winpython的環境下執行底下重新安裝即可
pip install numpy-1.12.0rc2+mkl-cp35-cp35m-win_amd64.whl

請注意選擇你所需要的版本。numpy-1.12.0rc2是目前最新的。
cp35 for python 3.5.2版
win_amd64 for x64


6.更改.theanorc.txt 及keras.json:

A.更改keras.json:
以上安裝好之後,你可以先試著在winpython環境裡打上python
>>import keras
應該會出現以下error,
{
  File "D:\WinPython-64bit-3.5.2.3Qt5\python-3.5.2.amd64\lib\site-packages\keras\backend\tensorflow_backend.py", line 1, in <module>
    import tensorflow as tf
ImportError: No module named 'tensorflow'
...
}
原因是Keras可以用tensorflow 或theano 當backend,預設是tensorflow
這時我需將它改成使用theano 當backend。請到你winpython安裝目錄下的setting裡
經過上述的執行應該會產生一個keras.json檔在
D:\WinPython-64bit-3.5.2.3Qt5\settings\.keras

請將底下原本tensorflow改成theano,即可完成轉換backend到theano。

##=======keras.json
{
    "epsilon": 1e-07,
    "image_dim_ordering": "tf",
    "floatx": "float32",
-   "backend": "Tensorflow"
+  "backend": "theano"
}

P.S
*.1 -號為移除該行,+號為增加該行,-,+號都不該出現在實際檔案裡。
*.2 我的winpython 預設安裝路徑為D:\WinPython-64bit-3.5.2.3Qt5
*.3 對於winpython 環境而言的/Home目錄是預設在
D:\WinPython-64bit-3.5.2.3Qt5\settings
並非C:\Users\使用者名稱xxxx
這點請注意,所以接下來對於theano的設定檔.theanorc.txt
也應放置於D:\WinPython-64bit-3.5.2.3Qt5\settings 目錄下


B.更改.theanorc.txt:

請參考底下.theanorc.txt更改
device = gpu  #指的是預設切換到使用GPU
floatX = float32   #for GPU 都是float32   ,for CPU 可以有float64
##===.theanorc.txt檔for GPU
[global]
openmp=False
device = gpu
optimizer_including=cudnn
floatX = float32
allow_input_downcast=True
[lib]
cnmem = 0.8
[blas]
ldflags=
[gcc]
cxxflags = -D_hypot=hypot
[nvcc]
fastmath = True
--flags=-LD:\WinPython-64bit-3.5.2.3Qt5\python-3.5.2.amd64\libs
--compiler_bindir=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

可能Error 1:
接著試著在winpython環境裡打上python
>>import theano
如果有跑出一大串行號及C++ code 就表示有error發生,如果發生底下error
{
C:\Users\shing\AppData\Local\Theano\compiledir_Windows-10-10.0.10586-SP0-Intel64_Family_6_Model_94_Stepping_3_GenuineIntel-3.5.2-64\lazylinker_ext\mod.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
 #include <Python.h>
 ^
...
}
可以試著下面解法:
開啟在你winpython 目錄下的D:\WinPython-64bit-3.5.2.3Qt5\scripts\env.bat
修改底下path 設定紅色部分,也就是加入G++ x64的環境設定
實際上Vs2015/Nvcc 的路徑也都可以直接改在如下
這樣你的winpython環境也都是認得到。


#=====env.bat=============
if %ERRORLEVEL% NEQ 0 set PATH=D:\msys64\mingw64\lib;D:\msys64\mingw64\bin;%WINPYDIR%\Lib\site-packages\PyQt5;%WINPYDIR%\Lib\site-packages\PyQt4;%WINPYDIR%\;%WINPYDIR%\DLLs;%WINPYDIR%\Scripts;%WINPYDIR%\..\tools;%WINPYDIR%\..\tools\mingw32\bin;%WINPYDIR%\..\tools\R\bin\x64;%WINPYDIR%\..\tools\Julia\bin;%PATH%;
#}

可能Error 2:
如果出現以下error
{
 64_Family_6_Model_94_Stepping_3_GenuineIntel-3.5.2-64\lazylinker_ext\mod.cpp:1:
D:/msys64/mingw64/include/c++/6.2.0/cmath:1133:11: error: '::hypot' has not been declared
   using ::hypot;
}         ^~~~~
請檢查.theanorc.txt裡有無底下宣告
[gcc]
cxxflags = -D_hypot=hypot

可能Error 3:
接著試著在winpython環境裡再打上python
>>import theano
如果出現以下error
{
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\crtdefs.h(10): 
fatal error C1083: Cannot open include file: 'corecrt.h': No such file or directory
}    

必須新增底下到系統的環境變數裡,原因是他會用到Windows Kits裡的函式,不只VS2015
所也必須宣告進去。
INCLUDE=C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\ucrt
LIB=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64

可能Error 4: 接著如果出現以下error
{
mod.cu(803): warning C4311: 'type cast': pointer truncation from 'CudaNdarray *' to 'long'
mod.cu(3374): warning C4312: 'type cast': conversion from 'long' to 'float *' of greater size
LINK : fatal error LNK1104: cannot open file 'uuid.lib'
}

增加底下到系統的環境變數path裡。
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\um\x64
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\ucrt\x64

注意:有更改到系統環境變數都須重新登入或是重開機才會生效


最後再執行一次
在winpython環境裡再打上python
>>import theano
如果最後出現底下DEBUG字串,恭喜!代表安裝Theano run with GPU成功了
{
DEBUG: nvcc STDOUT mod.cu Creating library C:/Users/shing/AppData/Local/Theano/compiledir_Windows-10-10.0.10586-SP0-Intel64_Family_6_Model_94_Stepping_3_GenuineIntel-3.5.2-64/tmp1qux40n6/md9b7b5ef5d727b2e8e3d2cc34bb9d0eb.lib and object C:/Users/shing/AppData/Local/Theano/compiledir_Windows-10-10.0.10586-SP0-Intel64_Family_6_Model_94_Stepping_3_GenuineIntel-3.5.2-64/tmp1qux40n6/md9b7b5ef5d727b2e8e3d2cc34bb9d0eb.exp
}

接著再打上python
>>> import keras
Using Theano backend.

以上也代表Keras也可以正常的工作,並且可以Base on Theano run with GPU。

接下來我們可以跑一些sample code來實際測試效能。

Theano實際測試:

首先我們在Theano的官網上可以發現有兩個測試GPU的sample code
http://deeplearning.net/software/theano/tutorial/using_gpu.html

我們就來實際跑看看使用CPU及GPU的差別。
如果在winpython想切回使用CPU跑,可以將.theanorc.txt 換成底下
##===.theanorc.txt for CPU
[global]
openmp=True
device = cpu
floatX = float64
allow_input_downcast=True
[gcc]
cxxflags = -D_hypot=hypot


第一個程式theano1.py

a.使用Intel CPU i7-6700HQ ,約2.488sec


 b.使用GPU 950M 約0.4176 sec  ,快了大約6倍。使用940M約0.9秒




 第二個程式theano_gpu.py

a.使用Intel CPU i7-6700HQ ,約3.019 sec



 b.使用GPU 950M 只需0.012 sec  ,快了大約250倍。使用940M約0.015秒。



第二支程式與第一支程式的差異在於,第一個程式是函數將直接其結果作為NumPy ndarray返回,為了方便,該函數已從設備複製到主機。而第二個程式是將輸入從主機複製到GPU,並且優化exp()function的執行。
f = function([], sandbox.cuda.basic_ops.gpu_from_host(T.exp(x)))


Keras實際測試:

首先我們先download keras 的examples.
直接使用git clone 的方式在命令視窗下執行,前提是已經有安裝了git tool.

git clone https://github.com/fchollet/keras.git
切到keras的examples 目錄
cd keras/examples/

該目錄下有很多已建好的範例可以直接使用,並且都是python 的程式
Keras優點是其模塊本身都可以使用Python程式語法自由組建,與caffe不同
使用caffe必須使用它定義類似Json的文檔去建構網路架構。這會讓你感覺不像是在寫
python的程式。

首先直接先執行底下MLP網路範例試看看
python mnist_mlp.py

執行後一開始會出現很多底下DEBUG信息,這並不是錯誤,暫時可以不用管它,他會繼續跑。

[2017/01/14更新] 用以下指令更新Theano 就不會出現DEBUG 信息了
pip install --upgrade --no-deps git+git://github.com/Theano/Theano.git




執行過程及結果如下:60000筆訓練資料及10000筆測試資料,Epoch 20,得到accuracy 0.9843
這個使用950M跑的過程不到10分鐘,之前用純CPU跑約1個多小時應該有。


接下來再來跑一個大一點的範例試看看
python lstm_benchmark.py

一開始都會自動先下載data,這範例的data量很明顯比剛剛大多了,到此可以先去喝杯咖啡~


經過多久沒仔細計算,底下是跑出來的結果


如果有興趣安裝Pycuda ,也只要執行以下指令即可安裝成功及使用,因為
CUDA在之前都已經安裝成功了

pip install pycuda


[2017/01/14更新] Tensorflow 已可安裝在Windows 上並可使用GPU運算加速

如果上述步驟都安裝成功,那麼額外再安裝Tensorflow 只要按照官網以下的指令即可安裝
Tensorflow 成功,並使用GPU運算
pip install --upgrade https://storage.googleapis.com/tensorflow/windows/gpu/tensorflow_gpu-0.12.1-cp35-cp35m-win_amd64.whl

[2017/01/15更新] 如果遇到以下錯誤
"can not opened CUDA library cupti64_80.dll locally"
試著將以下路徑加入系統環境變數PATH
 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\extras\CUPTI\libx64



因此Keras 也可以改成Tensorflow 當backend。下圖即是用keras 的範例用Tensorflow當backend
來驗證安裝是否成功。從下圖也可以看出可以成功的使用GPU CUDA




[2017/03/23更新]
更新至Tensorflow R1.0 ,只須執行下列指令
pip3 install --upgrade tensorflow-gpu

必須下載及更新Numpy+mlk,否則上述指令會讓Numpy會失去MLK。
http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy

更新Kears2.0 :
先用pip uninstall keras  卸載舊的keras
再到底下網址直接下載Keras-2.0.2.tar.gz (md5)
https://pypi.python.org/pypi/Keras
解壓縮檔案後:
在解壓縮的資料夾裡執行:
python setup.py install

測試Tensorflow 及keras version。





加入阿布拉機的3D列印與機器人的FB專頁
https://www.facebook.com/arbu00/


<其他有關文章>

機器學習(2)--使用OPENCV SVM實作手寫辨識
機器學習(1)--使用OPENCV KNN實作手寫辨識
OPENCV(11)--contours and convex hull(輪廓與凸包)
OPENCV(10)--Canny Edge Detection(Canny邊緣檢測)
OPENCV(9)--Image Gradients(圖像梯度)
OPENCV(8)--Histogram & Histograms Equalization(長條圖與長條圖均衡化)
OPENCV(7)--2D Convolution ,Image Filtering and Blurring (旋積,濾波與模糊)
OPENCV(6)--Trackbar(軌道桿)
OPENCV(5)--Drawing
OPENCV(4)--Grayscale,Binarization,Threshole(灰階化,二值化,閥值)
OPENCV(3)--Matplotlib pyplot bassic function
OPENCV(2)--Capture Video from Camera
OPENCV(1 )--How to install OPENCV in Python

人工神經網路(2)--使用Python實作後向傳遞神經網路演算法(Backprogation artificial neature network)
人工神經網路(1)--使用Python實作perceptron(感知器)