Tensorflow V2.0 相容性小實驗

為了一圓 AI 大夢, 我買了一塊 GTX 3090. 原本在 PCHOME 觀望三分鐘, 嫌貴沒按下去, 後來就再也買不到了!!!  電腦的東西不是應該慢慢降價嗎? “早買早享受, 晚買享折扣" 是大家都知道的定律啊!? 不過這次不一樣, 顯卡價錢還一天比一天高. 最後只好破釜沉舟買了蝦皮最後一張現貨, 而且是散熱貼片品質不好的技嘉. 

卡片到手之後, 先找個 BenchMark 來燒機, 結果老舊的 i7 扯了後腿, 分數還差正常的 3090 一成. 腦筋一賺, 來挖礦吧! 結果以前會動的 guiminer 程式都連不上礦池. 上網一查才知道電腦已經不能挖比特幣了. 不死心的我研究了一下, 得知可以在 Nicehash 挖別的幣換比特幣, 這樣果然就行了. 但是算力全開的話, VRM 瞬間就飆到 110 度. 嚇得死人了. 只敢開溫和模式當背景程式跑.

好了, 言歸正傳. 算 AI 會不會燒 VRM 要試了才知道.  然而, 客戶的事情如雪片般飛來, 我始終不能定下心跑程式. 兩個月過去, 比特幣都挖了 0.005 顆了, 但是正事還沒開工. 好不容易有清明連假, 趕快把電腦環境安裝起來. 有一篇文章跟我以前的軌跡很相似 [1], 於是我就按照這個思路來恢復環境.

不過 Google 排名靠前 – 很多人引用的文章相對都是比較舊的. 前述文章中的 Cuda 9 已經該進版到 Cuda 11.2, Cudnn 由 7.5 進版到 8.1.1, 其他流程都差不多. 按照文章一路破關, 然後在測試環境這邊卡住了. 當我執行 c = tf.matmul(a, b) 會得到:

" failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED"

根據 [2] 所述, 這是分配記憶體的問題. 按照官網 [3] 要下tf.config.experimental.set_visible_devices.

但這個還是只能治標, 不能治本. 晚點還是會遇到

tensorflow.python.framework.errors_impl.InternalError: Blas xGEMM launch failed : a.shape=[1,2,3], b.shape=[1,3,2], m=2, n=2, k=3 [Op:MatMul]

看起來正確解答是這三行 [4]:

import tensorflow as tf
physical_devices = tf.config.list_physical_devices('GPU') 
tf.config.experimental.set_memory_growth(physical_devices[0], True)

但是要在 init 的時候下, 不能臨時抱佛腳. 所以要重來一次.

然後在 tensorflow 2.0, 過去的 tf.Session() 也被淘汰了, 要改用 f.compat.v1.Session(). tf.ConfigProto 也換成  tf.compat.v1.ConfigProto (待確認). 比較嚴重的區別是 tensorflow 2.0 預設開 eager execution. 會遇到

RuntimeError: The Session graph is empty. Add operations to the graph before calling run()

所以有三個方法:

A. 直接設定跟舊版相容 [7]:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

B. 或是關掉 eager execution [6]:

tf.compat.v1.disable_eager_execution()

C. 或者先宣告 session, 而不是等要用的時候才宣告. 例如 [6]:

 # Launch the graph in a session.
 with tf.compat.v1.Session() as ses:

     # Build a graph.
     a = tf.constant(5.0)
     b = tf.constant(6.0)
     c = a * b

     # Evaluate the tensor `c`.
     print(ses.run(c))

重來一次完整的步驟就是. 從 Anaconda 打開 Python 的 terminal.

import tensorflow as tf

physical_devices = tf.config.list_physical_devices('GPU') 
tf.config.experimental.set_memory_growth(physical_devices[0], True)
tf.compat.v1.disable_eager_execution()
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True))
print(sess.run(c))

 

[REF]

  1. https://ithelp.ithome.com.tw/articles/10237846
  2. https://www.itread01.com/content/1545441880.html
  3. https://www.tensorflow.org/guide/gpu
  4. ://stackoverflow.com/questions/43990046/tensorflow-blas-gemm-launch-failed
  5. https://stackoverflow.com/questions/55142951/tensorflow-2-0-attributeerror-module-tensorflow-has-no-attribute-session
  6. https://github.com/OlafenwaMoses/ImageAI/issues/400
  7. https://github.com/tensorflow/tensorflow/issues/25446

 

 

在 Windows 上跑 Facenet 的小筆記

最近想在 Notebook 上建一個 AI 模擬的環境, 其中遇到一些關卡值得記錄下來.

在 Notebook 上建個虛擬機來跑 AI…. 畢竟 Linux 的環境比 Windows 直覺, 所以先做了這件事. Linux 軟體安裝起來相對容易, 重點在權限開對, 路徑設定可以憑直覺.

這樣很快就可以用 CPU 跑 facenet, But, 我是想要用 GPU 來跑啊!? Google 了一下發現虛擬機的 driver 不是 cuda 相容的, 必須要裝雙系統, 有原生的 Ubuntu 才可以跑. 因此又被打回 Windows 10 環境.

在 Windows 10 上面, 當然很直覺要先裝個 Python. 但這不是最佳的選擇. 應該先裝 GPU driver, 然後裝 Anaconda [1]. 原因是 Anaconda 下可以裝很多套不同版本的虛擬 Python 環境,  即使 model 只支持特定 Python 版本, 也不需要重新安裝 Python. 畢竟 Python 2.x 和 Python 3.x 就不相容了, 換來換去很麻煩.

若先裝 Python, 再裝 Anaconda, 後者會問要不要把 Anaconda 設為 Python 的預設程式? 如果選不要, 我發現很多怪現象會發生. 例如 Anaconda Navigator 搞失蹤之類的. 即使把既有的 Python 解除安裝, 在沒有重新開機之前, 純 Python 還是會在背景干擾 Anaconda Python. 所以乾脆反過來只安裝 Anaconda, 把它設為預設程式.

Step 1: 下載並安裝 Anaconda 3. 版本 4 和 5 好像是要錢的企業版.

然後在 Anaconda 底下的 envs 目錄下可以看到多個目錄, 每一個代表一種虛擬的環境. 當然這個要按照 Anaconda 的官網說明去創建, 如果不建立這底下就是空蕩蕩的. 環境做好之後, 會在 Windows 的程式集裡面看到成對的 prompt, Spyder…等等. prompt 就是命令列, Spyder 有 GUI, 而 reset 顧名思義就是把這個虛擬環境清掉重來, 在裝錯軟體的時候很好用.

anaconda

Step 2. 建立 Anaconda 下的虛擬環境, -n 的後面跟著名字, 例如我用 tensorflow-gpu 就可以來來區隔這個環境是跑 GPU 版本的. 但這只是名字而已, 真正的安裝在後面步驟. 但我後來後悔用這麼長的名字, prompt 變得很長. 此處指定了 python 的版本.

c:> conda create -n tensorflow pip python=3.6

Step 3. 啟用這個環境.

C:> activate tensorflow
 (tensorflow)C:>  # Your prompt should change

Step 4. 安裝跑 GPU 版本的 tensorflow. 這邊的 tensorflow-gpu 就是關鍵字不能改了.

(tensorflow)C:> pip install --ignore-installed --upgrade tensorflow-gpu

以上 Step 1~4 參考 Anaconda 官網 [1], 還有教人如何驗證安裝正確與否.

此外, tensorflow-gpu 往下需要 Cuda 和 Dnn 的函式庫. 參考這篇 [2] 即可. 其中, Cuda 要用第九版, CuDnn 應該用 V7 或 V7.1. 至於 GTX 顯卡的 driver 是本來就有的, 如果您是用 AMD 系列的顯卡, 這個我就沒研究.

這裡看起來很簡單, 但是陷阱也很多.  如果裝錯的話, 後續跑 tensorflow-gpu 就會報錯, 說找不到 cudart.lib, cudablas.lib….等等. 原因在於大家可能在安裝 GTX 顯卡的時候, 就在 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64 底下安裝了 cuda 相關的函式庫, 所以優先被執行到.

若安裝正確的話, 應該在指定的目錄 (解開 cudnn-9.0-windows10-x64-v7.zip 後手動放的那個目錄), 看到 cudnn64_7.dll. 然後把這個目錄加入 path. 網路上有很多人求救, 他們可能是把 32 bit / 64 bit 搞錯, 或已經安裝了 cudnn-9.1 但 tensorflow 只支援到 9.0 之類的, 總之痛下殺手把電腦的版本降級配合 tensorflow 就行了.  

搞定 dnn 之後, 就可以按照滿山遍野的網路教學跑 MTCNN + Facenet [3][4]. 但還是要請大家再次釐清一個觀念是: 既然我已經用 Anaconda 做虛擬環境, 一切都要在虛擬環境下執行. 也就是 envs/tensorflow-gpu (舉例)/ 而不是 Anaconda 目錄下 [3].  然後呢…facenet 是一個 module, 必須安裝到 lib/site-packages/ 底下才能執行, 光是下載 facenet copy 進去是沒用的.

Python 中安裝 module 的方法有很多種[5]. 我們只需要用到最簡單的 pip install facenet 即可. 其他的按照 [4] 應該就可以依序執行 MTCNN 和 Facenet. 這邊會踩到的雷是: Windows 系統的字型編碼會造成 facenet error, 這個外國人可能遇不到. 大約在 facenet.py 的 577 行左右, 要把原文改為我下面的這行代碼. 當然最前面要記得 import io.

# with open(rev_info_filename, “w") as text_file:
with io.open(rev_info_filename, “w", encoding="utf-8″) as text_file:

然後, 如果要 traning 自己的 database, 還有一行要改. 在 train_softmax.py 的 95 行左右, 無論換哪個 database, 它都固定去讀 data/pairs.txt, 所以我硬改一個寫死的目錄, 以便可以測 mydata.

# pairs = lfw.read_pairs(os.path.expanduser(args.lfw_pairs))
pairs = lfw.read_pairs(os.path.expanduser(‘mydata/pairs.txt’)) #Cash modified

在跑 MTCNN 的時候, 網路上很多文章都說要執行

python ~/tensorflow/facenet/src/align/align_dataset_mtcnn.py ~/tensorflow/lfw/raw ~/tensorflow/lfw/lfw_mtcnnpy_160 –image_size 160 –margin32 –random_order –gpu_memory_fraction 0.25

最後面 –gpu_memory_fraction 0.25 這個參數, 其實是 facenet 官網 [6] 跑四個 process 的關係, 跑 4 個當然每個人用 1/4 (0.25) 囉. 如果只跑一個 process, 加上這行唯一的好處是記憶體比較不會爆掉.

以上是跑 tensorflow 主線任務的紀錄. 支線上任務則是曾經試圖跑 mxnet + opencv 的版本, 結果第一路打通就沒繼續奮鬥了.

Step 1. 下載 opencv V.3.4.1

https://opencv.org/opencv-3-4-1.html 選 https://github.com/opencv/opencv/tree/3.4.1

Step 2. 解開 opencv 發現要 cmake.

Step 3. 下載 Visual Studio Community 2017

Step 4. 在 Visual studio 的 “工具" 裡面選 “擴充功能與更新", 選 cmake 下載, 安裝.

在 “工具" 選 “取得工具與功能", 選 “工具負載" 裡的 “其他工具組"  的 “使用 c++ 進行 Linux 開發", 選 “Web 與雲端" 的 “Python 開發".

Step 5. 下載 cmake, 在 https://cmake.org/download/  選 cmake-3.12.1-win64-x64.msi

要選產生 GUI 比較方便.

Step 6. 在 Cmake GUI 選 source code 位置, Build binary 位置, 選 Configure, 跑一段時間, 選 Generate 產生 build file. 選 Open Project 帶起 Visual Studio. [7]. 

cmake-1-768x661

Step 7. 在 Visual Studio build 這個 project. 參考 [8]  作一些修改. 但它的版本比較舊, 在我的平台上要把 VC10 改為 VC15, x86 改為 x64. opencv 改為 opencv 和 opencv2.

Step 8. 編成功後, 會在 c:\opencv\build\release\bin\debug (舉例) 看到一堆檔案, 這樣就成功了. 其中 opencv_interactive-calibrationd 跑起來會自動抓 NB 前鏡頭的畫面, 看了會很有感. 上面截圖時, 我把 binary 位置選在 c:\opencv\build, 但裡面本來就有檔案了, 再放自己編出的檔案會糊成一團, 故第二次我把 target 改到 c:\opencv\build\release.

Step 9. 安裝 mxnet

這個網頁可以自訂要下載哪一種 mxnet 的版本, 相當地人性化. 我選了

mxnet-1-768x372

https://mxnet.apache.org/install/index.html?platform=Windows&language=Python&processor=GPU

Step 10. 建議安裝 Anacoda — 請參考前面說的.

Step 11. 升級 mxnet 以支援 GPU

pip install mxnet-cu92

Step 12. 調整路徑

不調整路徑的話, 直接 load mxnet 版本的 facenet 會出現找不到 module 的錯誤. 事實上, 採用 Tensor flow 版本的人也是一直再狂問為何找不到 tensorflow module. 這些都是路徑的問題.

正常安裝完的 module 都會放在 pythonxxx 下面的 Lib/site-packages.

[Note]

  1. https://www.tensorflow.org/install/install_windows
  2. http://blog.nex3z.com/2017/04/18/%E5%9C%A8-windows-%E5%B9%B3%E5%8F%B0%E5%AE%89%E8%A3%85-nvidia-gpu-%E5%8A%A0%E9%80%9F%E7%9A%84-tensorflow/
  3. https://blog.csdn.net/xiangxianghehe/article/details/72809600
  4. https://blog.csdn.net/chzylucky/article/details/79680986
  5. https://packaging.python.org/tutorials/installing-packages/
  6. https://github.com/davidsandberg/facenet/wiki/Classifier-training-of-inception-resnet-v1
  7. http://gclxry.com/use-cmake-on-windows/
  8. http://monkeycoding.com/?p=516

Tesorflow on Windows 10 小筆記

最近想要自己安裝 tensorflow 到 Windows 10 底下, 找了一篇很好的文章來參考 [1].  不過實際動手做的時候, 遇到一些小問題, 所以另外做個筆記紀錄一下.

首先我們要安裝 Python [2], 這點沒有疑慮. 到官網抓下來安裝. 然後手動把路徑加到系統環境即可. 但接下來分岔成兩種作法: A 和 B:

(A) 在 Python 環境下安裝 tensorflow.

pip3 install –upgrade tensorflow-gpu

安裝過程一切順利, 但是在 python 提示號下, 可能會遇到 ctypes.WINDLL 找不到 cudart_dll_XXX 的問題. 理論上安裝完 cuda 就會好.  值得注意的是 cuda 和 cuDNN 的版本要搭配 tensorflow-gpu 的版本. 現在的 python 3.6 要搭 cuda 9.0 和 cuDNN 7.0, 這個組合試過沒問題. 但我也曾經試過 cuda 9.1 搭 DNN 9.1, 結果失敗了. 不敢說這組合一定不行, 但我不打算再試了, 先退版本再說.

安裝完 cuda, 用 “nvcc -V" 可以看 cuda driver 是否正確安裝? 但安裝 driver之前, cuda 安裝程式會說 “找不到相容的顯示卡, 但是沒關係可以先安裝." 這讓我擔心了一下. 難道說有兩張顯卡的話會亂抓? 於是我又另外下載 cuda-Z [3] 來驗證. 實測發現讓 Intel UHD 620 和 GTX-1050 共存, 或是把 620 關掉; cuda-z 都可以正確找到 GTX-1050. 

最後一個提醒點是, 如果在 windows 的 command shell 打 python 出現的  shell 底下無法正常使用 import tensorflow, 但是在 python 安裝時自己產生的 command shell 就沒這個問題. 可見得還是有些小地方設定不同.

網路教學 [1] 說可以用矩陣乘法測試 tensorflow, 但實測起來, 老舊的桌機跑 CPU only 反而比 CPU + GPU 快! 問題出在這個 interpreter 會動態去偵測 CPU 和 GPU, 花了不少時間去優化環境. Your CPU supports …. AVX2, found device…GeForce 1050 … Total Memory 2.00GiB…etc.   

tensorflow-1-768x329

(2B) 用 anaconda3 的環境. 安裝它的好處是不會獨佔 python 的環境, 它可以用 anaconda prompt interpreter, 或者用 IDE (integrated development environment) 來寫程式. 從 anaconda navigator 進去, 然後點選 Spyder, 就可以自己寫 python 程式 compile 來跑.

spyder-1-768x636

安裝 anaconda 時會要求順便安裝 Visual Code, 安裝  Visual Code 和 Visual studio 時又會推薦同時安裝 git. 所以這個家族人數不少.  安裝 Visual Studio 的好處是 cuda 有一些 sample code, 可以跑來看看. 不過這裡面有一大敗筆是 sample code 只支援到 MSC_VER 1911, 最新的 Video studio 2017 已經是 MSC_VER 1912, 我看要改得地方太多, 決定放棄.

[Reference]

  1. http://blog.csdn.net/u010099080/article/details/53418159#%E5%AE%89%E8%A3%85-cudnn
  2. https://www.python.org/downloads/release/python-364/, download 連結在下方.
  3. http://cuda-z.sourceforge.net/