在 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 顧名思義就是把這個虛擬環境清掉重來, 在裝錯軟體的時候很好用.

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]. 

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 的版本, 相當地人性化. 我選了

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

我讀 «證券分析» 第六版 – 融資成本與管理成本

第 47 章講管理成本與融資成本, 分別對應到一家新創公司的管理層和資金兩種資產.

我們可以從三個面向來觀察資金的去向:

  1. 投資人付出股價大於管理層實際拿到資金, 這中間的差距付給了股票承銷商.
  2. 購買認股權證的同時, 攤薄了普通股的價值.
  3. 付給管理階層的薪資和成立公司導致的額外稅收.

因此投資人所買到的股票雖然表彰了擁有公司的一部分, 但可能付出 25%~30% 到公司營利活動以外的項目之中 (P. 740). 這些錢付給管理階層還可以說是為了買他們經營管理的技術, 但付給投資銀行的部分 (融資成本), 作者可就大大不滿意了. 這一整章後面都在批評投資銀行應該只收取適當的費用.

作者認為投資銀行 (投行) 應該站在投資者這一方, 避免以過高的掛牌價向社會大眾推薦一支股票. 更不應該和公司管理層合謀分贓, 只求賣出股票而把投資人當冤大頭. 例如台灣有些 F 股 (現在改稱 KY 股) 可以開出很高的承銷價給大家認購或抽籤, 等到大家繳錢之後股價就狂跌.

即使作者勉勵投行要提高道德標準, 不過投行本來就要靠公司 IPO 賺錢, 總不會胳臂往外彎, 有錢不賺, 卻去維護不認識的散戶的權益.

對於管理階層圖利自己這部分 (管理成本), 本書希望股東能夠一起來把關, 阻止管理層收取過高的報酬. 1933-1934 年美國已立法在年報中要揭露管理階層的報酬, 台灣在 2016 年終於稍微跟上國際進度, 規定要揭露董監事與副總以上主管的薪酬. 不過目前只揭露級距: 共分成200萬以下、200~500萬元、500~1,000萬元、1,000~1,500萬元、1,500~3,000萬元、3,000~5,000萬元、5,000萬元~1億元,以及1億元以上 [1]。進度差不多落後美國 100 年吧!

本書第 50 章 “同領域公司的比較分析” 算是一個比較發散的議題, 主要在於分析公司的資本結構對於公司表現 (反映在股價) 有何種影響? 基本上本書分析的結果是: 如果普通股比例高, 公司沒弄一大堆優先股, 抵押債券之類的, 那麼對於景氣好壞的抵抗力較好. 如果公司的槓桿很大, 就可能會大起大落 (P. 762).

書上仍然是把公司分為鐵路公司、公用事業公司、和工業公司三大類. 前兩者被視為可以使用相同的經驗法則, P. 757~P.759 列出了一大堆財務指標 [2]. 書上說無法基於某一項統計值就說 A 公司比 B 公司好 (P. 763).

對於工業公司, 書上 P.763~P.765 也列出許多財務指標, 比鐵路、公用事業還要多 (40 項對 32 項).  其中作者比較關注的還是第 18 項指標 EPS (普通股每股收益與市場價格比率) – P.766, 以及普通股與資本總額的比例 (也就是普通股倍稀釋的程度) – P. 767.

P. 767~P.768 舉了兩家普通股比例分別為 48.3 % 和 80% 的企業做比較, 結論是大蕭條的時候, 保守的後者比較有優勢. 但蕭條結束後兩家公司成績又反轉. 既然分析鐵路公司、公用事業、或者工業公司都得到一樣的結論. 換言之, 我們可以說這項指標和公司是否賺錢沒有關係.

P. 769~P. 771 重複講述我們無法判斷投資 A 公司會比投資 B 公司好. 除非這項指標已經明顯到有 50% 的差異, 分析師才應該勸投資人換股操作 (P. 770). 畢竟股價受到大環境和人氣的影響, 有時會偏離內在價值, 即使市場價格遲早會反映公司的盈利能力 (P. 769). 

另外就是兩家公司的性質可能有差異, 同質性高還可以 PK 指標的數字, 但異質性高時, 我們應該更看重定性的比較, 而不是定量的比較.我想這就是作者得不出通用型結論時所能做的一個註腳.時至今日, 應該也沒有人能說投資台積電一定比投資鴻海好, 但可以說投資台積電比投資聯電好, 我想作者大概就是這個意思.

[Note]

  1. http://www.chinatimes.com/newspapers/20160916000055-260202
  2. P. 757, 資本結構指標第二項的有效債務 (固定費用 x 22) 應該是錯的, 應該是指 x 上第 22 項的 “七年平均淨扣減保障倍數”, 而不會是一個固定值 22 倍.

 

我讀 «證券分析» 第六版 – 認股權證

本書的第 46 章主講認股權證, 分為簡介、投機工具、財務結構三個面向來討論. 我假設大家都知道認股權證是什麼? 即使不知道也很容易查得到,所以這部分就跳過.P.730~P732 說明發行認股權證的目的可以有很多種:

A. 依附於優先證券 (優先股). 增加優先證券的吸引力.
B. 作為給承銷商的報酬.
C. 作為推銷商和管理者的報酬.
D. 依附於普通股, 增加普通股的吸引力
E. 單獨出售以獲取現金.

作為投機工具的意義在於: 購買認股權證等於購買公司發展的潛力 (定性的因素). 至於何種價錢可以買就是定量的因素. 我們很難斷定買 A 公司的認股權證比買 B 公司的好, 而投機者可以從自己觀點來做出選擇.

一般而言, 認股權證一定是低價買進, 價格低、期限長、認購價接近股票市價. P. 735 列出一些具有代表性的認股權證. 舉例來說, 1939 年底美國與國外電力公司股價是 1又7/8 元, 認股權證市價 3/8 元, 認購價是 25 元, 期限是無限長. 其他兩點沒問題, 但這個認購價未免也太高了.

本書又認為, 某公司的技術好不見得未來的業績就會比較好. 因此要賭股價有一天漲 10 倍確實太拚了. 因此這樣就不是好的投機標的.

認股權證從資本結構來看, 是對於股權的稀釋. 然而普通股的股東對於認股權證的發行並沒有那麼敏感. 因此這也就變成了管理階層和券商牟利的工具. 更嚴重者, 認股權證還可以提供控股公司武器, 以金字塔的方式放大控制權, 卻只擁有不對稱的少數股權. 這點會在第 48 章說明. 因此我先跳到這章, 再回頭看第 47 章.

第 48 章提到公司金字塔結構的相關內容. 這裡不是指管理階層的金字塔, 而是資本結構的金字塔 – 畢竟這是葛拉漢的書而不是彼得杜拉克的. 

透過控股公司, 甚至於沒有控股公司而是發行大量的優先股和抵押債券都可以達到以少數股權控制公司的目的. P. 750 列出很多實質上只擁有公司 10% 不到的股份, 卻擁有 50% 以上 (甚至 100%) 的投票 (控制) 權的例子. 

例如美國與國外電力公司在 1929 年時總共發行 1,600,00 股的普通股, 和以 25 元可以認購的 7,100,000 股 (第二優先股). 如果大家都去買認股權證並執行買權, 則股本應該要膨脹到 1.6 M + 7.1 M = 8.7 M, 超過原本 1.6 M 的五倍.  但這些額外的股票是第二優先股, 所以普通股還是 1.6 M, 獲利都以此為計算基準.

此時公司派只要稍微拉抬普通股的股價, 股民就會跳進來買認股權證. 當認股權證賣出, 公司就有收入, 純益上升, 每股獲利 (EPS) 看起來更好, 本益比也隨之增加.

該公司股價曾滾雪球般地來到 199.25 元, 認股權證也漲到 174 元 (因為還要花 25 元買股票, 174+25 = 199). EPS 虛胖到 4.01 元, 因為是 “好公司”, “本益比” 達 50 倍 (199.25/4.01). 

這種炒作的手法, 在 1935 年開始已經被美國國會所禁止. 所以大家還記得的話, 本文最前面提到 1939 年這家公司股價是 1又 7/8 元. 認股權證的價格也崩盤了.

近來台灣的銀行熱衷發行特別股, 例如快要上市的國泰金乙特. 發行金額 70 億, 加上甲特 的 83.3 億, 雖然和股本約 1,257 億還有一大段距離, 不像本書的例子那麼誇張. 但從另外一個角度看, 管理階層是在不稀釋經營權的前提之下, 稀釋了普通股股東的權益. 至於管理階層自己被稀釋的部分,  還可以從員工認股 (7 億) 那邊補回來. 也難怪金控們都喜歡這樣玩啊!