SPIN_LOCK 小註解

最近看到一個 Kernel config 叫做 CONFIG_UNINLINE_SPIN_UNLOCK, 這 un 又 un, 真的是讓人看得眼花. 雖然說現在人強調 “減法" 的思維, 看這個名詞還是得用 “加法".

STEP 1: SPIN_LOCK [1], 多處理器共用一個資源時, 透過 SPIN_LOCK 去鎖住不讓其他人用. 自己用完後, 設為 unlock, 別人就可以用. 怎麼知道可不可以用呢? 要透過 trylock() 來判斷是否拿到資源. 如果拿不到回直接回傳 busy, 除非一直 try 否則也不會浪費資源. 真的 try 不停就要看演算了 [2].

STEP 2: INLINE_SPIN_LOCK. inline 是指會將 spin_lock() 插入程式之中. 但它也不只是當作巨集處理而已, 參考 [3] 這段話, 它會把 spin_lock() 這個函式的內容優化之後才代入. 

The point of making a function inline is to hint to the compiler that it is worth making some form of extra effort to call the function faster than it would otherwise – generally by substituting the code of the function into its caller. As well as eliminating the need for a call and return sequence, it might allow the compiler to perform certain optimizations between the bodies of both functions.

STEP 3:  INLINE_SPIN_UNLOCK. 有鎖的動作就有解鎖. 使用之前, kernel config 要先打開. 追溯到 2012 年, 當初只有 CONFIG_INLINE_SPIN_UNLOCK [4].

STEP 4:  Linus Torvalds 自己建議把原本預設開 CONFIG_INLINE_SPIN_UNLOCK, 改為預設 CONFIG_UNINLINE_SPIN_UNLOCK 未定義 [4].

-CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_UNINLINE_SPIN_UNLOCK is not set

想要 debug inline spin unlock 的人如果想要加 debug code, 開這個 config 就不會因為 inline 的作用, 使自己的 code 和原本 inline 的函式融為一體, 以致於無法正確地 debug.

預期的路人心得:  不能因為負負得正, 就把 CONFIG_UNINLINE_SPIN_UNLOCK 想成 CONFIG_INLINE_SPIN_LOCK. 哈!

[Ref]

  1. https://blog.csdn.net/u010144805/article/details/80354679
  2. https://locklessinc.com/articles/locks/
  3. http://www.greenend.org.uk/rjk/tech/inline.html
  4. http://lkml.iu.edu/hypermail/linux/kernel/1203.2/03015.html

在 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

CSS 上下標小修改

剛剛發布那篇 “只買好公司" 的心得之後, 發現上下標還是沒起作用.這樣公式都會變得很難看懂.無奈只好動手修理,不然以後都只好貼圖了.

由於現代人已經不熱衷寫 HTML, 相關的訊息不好 Google. 根據我捕風捉影的結果, TinyMCE Editor 有乖乖做事, <sub><sup> 標籤都有加. 但是 HTML 被畫出來的時候, 上下標的字體沒變, 而且沒有正確地對齊. 所以看起來才會跟沒上下標的結果一樣.

幸好前人 [1] 有給提示, 只要把 CSS 裡面加上正確的描述就可以了. 但是怎麼做呢? 方法一就是換主題, 搞不好下一個主題就沒有這個 bug. 但我喜歡現在的主題, 它比較乾進清爽, 而且一時之間又不知道要換哪個好? 所以這招暫且不用.

第二個方法是主題不動, 但修改 CSS. CSS 的位置放在 wordpress\wp-content\themes\zbench (<- 這是我的主題) 下面, 或者從控制台進去也可以改 (外觀 -> 編輯 CSS). 但它會提示別亂改, 要改請改在 “附加的 CSS". 所以我當然就 “先" 從善如流啦! 如果不 work, 就別怪我從惡如流氓了!

根據 editor-style.css 的語法, 前面是定義關鍵字, 後面是一個括號, 所以我把 [1] 裡面的東西抄一半過來. 首先把 font size 變小 70%. 然後把上標依據 super 做垂直對齊, sub 依據 sub(note) 做垂直對齊. 然後按發表就可以搞定了.

運氣不錯, 很快 debug 完問題! 當然還是要感謝前人的筆記. 所謂聞君一席話, 勝賭十年輸. 最近電視一直在廣告賭世足運彩可以賺大錢, 小心十年輸, 輸十年啊!

another-css

[Note]

  1. http://magicjackting.pixnet.net/blog/post/173686861-css:-%E4%B8%8A%E4%B8%8B%E6%A8%99%E5%AD%97-(%3Csub%3E,-%3Csup%3E)-%E7%9A%84%E7%9B%B8%E9%97%9C%E8%A8%AD%E5%AE%9A

Apple email 亂碼小註解

我本來用 Apple 的 Macbook AIR 收信, 最近改成 Surface Book 2. 原本收到其他同仁用 Apple Macbook 寄出來的加密信件, 在 Apple 上直接用 Apple Mail 加上插件就可以看到解密後的郵件, 相當地方便! 但換到 Windows 底下就變亂碼了, 這件事有點麻煩, 所以花了點時間解決.

首先 Kleopatra 解密軟體是無辜的, 它只是忠實地解開 PGP key. 編輯器也是無辜的, 這並不是 UTF-8 誤設成 Big 5 這類的問題. 不然用 Word 裡面選擇編碼的功能就能挑出對的那個編碼方式.

我這次遇到的是郵件變成了有很多等於符號的亂碼, 例如 =8E=BB=E5=A6=82=E6=9E=9C…, 這該怎麼辦呢? 這種很多 “等於" 的亂碼是 Quoted-printable (QP) 編碼, 中文是 “可打印字符引用編碼". 也就是可以把任何編碼的文字變成可以印出來的 ASCII 字元. 解密完的 mail 中也可以看到這些字樣:

Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8

Apple 的電腦預設都是用 UTF-8 編碼寄出, 但是後續又被 quoted-printable 轉了一次. 解密軟體只負責解到 quoted-printable, 加上 Outlook 不像 Apple Mail 多了一道解 QP 的動作, 因此才會出現亂碼.

解決之道, 可以自己寫一個解 QP 的程式, 例如這位勇者仁兄 [1], 或者是到善心人士的網站上去轉 [2]. 這個網站還提供了很多轉來轉去的工具, 有需要的人可以做成書籤來備用. 另外有一個網站 [3] 提示了幾種亂碼的類型, 看到不同的亂碼就知道這是哪一類的問題. 基本上 unicode 就是 &# 開頭, 因此文件中一定會有很多 &#. 
random-character-1-620x200

幸虧有這些亂碼終結者, 我們才能有效率地解決網路上怪怪的相容性問題. 在此也感謝他們的貢獻!

[Note]

  1. https://social.msdn.microsoft.com/Forums/zh-TW/d1ff3e3f-bca2-4220-a970-e3557f623e90/-quotedprintable-?forum=233
  2. http://web.chacuo.net/charsetquotedprintable
  3. https://www.uni-ulm.de/acssu/ime/email_decoder_tc.php

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/