如果英文已經不錯了, 要學一點點西班牙文相對就不會太難; 但是英文能力對於學習彈鋼琴可能並沒有幫助。 這就是 transfer learning 學習遷移的現象。 類神經網路也是這樣: 已經訓練好、 可以辨識 1000 種類型相片的 caffe 圖像辨識模型, 如果要再拿來改訓練成 「辨識六種猿類相片」 的模型, 因為工作內容很類似, 所以對就花的運算資源相少很多, 也相對比較容易訓練得好。
請見本文插圖。 用 caffe 做 transfer learning 時,
最核心的工作, 就是要用 caffe train ...
這個指令把 bvlc_reference_caffenet.caffemodel
這個權重矩陣訓練成名為 _iter_4000.caffemodel 之類的另一個權重矩陣。
類神經網路的模型架構寫在 train.prototxt 這個設定檔裡面。 這是由 AI 研究學者所設計的; 我們只會去改相關檔案的路徑, 還有最後面輸出那一層的架構, 因為原先要辨認 1000 類圖片, 現在只要辨認 6 類圖片。 秉持著 不求甚解工程師 的精神, 前面的其他層次看不懂也沒關係 :-)
除了類神經網路的架構之外, 訓練時還需要指定一些額外的參數,
例如多久要把整個權重矩陣做一次快照 (snapshot:
) 等等。
這些參數寫在 solver.prototxt 裡面。 你在 caffe train ...
的命令列上看不到模型架構的檔名 (train.prototxt),
只看得到 solver.prototxt 的檔名, 但 caffe 會從
solver.prototxt 裡面的 net:
那一句找到模型架構檔。
訓練完成後, 要用 cnclassify.py 來辨識未知圖片時,
除了要有權重檔 _iter_4000.caffemodel 之外,
當然也要餵模型架構 deploy.prototxt 給 cnclassify.py 吃。
你可以用一個比較強的文字編輯器 (例如 vimdiff)
把它拿來跟 train.prototxt 比較 --
deploy.prototxt 基本上就是簡化版
(只保留 forward phase; 丟棄 back propagation)
的 train.prototxt 。 另外, caffe 類神經網路在辨識圖片時,
輸出的結果並不是文字字串, 而是 0 到 5 之間的一個整數。
到底 0 代表哪一種猩猩、 5 代表哪一種猿類,
需要有一個標籤列表的文字檔來解讀。 等一下我們再詳細交代
wnid.txt 這個標籤列表檔的內容。
最後, 辨識時還需要把訓練過程當中所有相片的平均值
mean.npy 拿來參考 -- 這點我們在
caffe 初體驗 當中已學過。
也請下 ./cnclassify.py -h
查看更多選項。
回頭看如何準備訓練用的圖片。 訓練用的 .jpg 圖片檔並不是直接餵給 caffe, 而是要先用 pic2lmdb.py 指令把它們轉成 lmdb 的格式、 把所有圖片塞進 training/ 跟 validation/ 底下的兩個資料庫。 但別忘了這是 supervised learning, 所以你必須告訴 caffe 每一張相片究竟是黑猩猩還是大猩猩。 你的圖片檔必須按照類別命名或是按照類別放在各自的資料夾, 類似這樣:
chimp-0001.jpg chimp-0002.jpg ... gorilla-0225.jpg gorilla-0226.jpg
或類似這樣:
chimp/0001.jpg chimp/0002.jpg ... gorilla/0225.jpg gorilla/0226.jpg
總之代表類別的圖片類別代號 (chimp、 gorilla 等等; 姑且稱之為 pcid)
必須是一個文數字的字串 ([a-zA-Z_0-9]+) 並且必須出現在路徑當中,
而且前後不可緊鄰其他文數字。
這是因為我在 pic2lmdb.py 裡面用 regex 的 \b 去圖片檔路徑裡面比對 pcid
(picture class id), 據此來決定這張圖片的類別。
至於路徑的其他部分 (0001 或 0002) 並不重要, 可以任意命名。
然後你需要建一個長得類似
wnid-apes.txt 的文字檔, 左邊是 pcid, 右邊是任意中英文字串, 列印用的。
把這個對照表跟一串圖片目錄餵給 pic2lmdb.py, 它就會產生兩個 lmdb 的目錄,
一個是 training 用, 另一個是 validation 用。
也請下 ./pic2lmdb.py.py -h
查看更多選項。
如果你跟我一樣手邊沒有很多現成的圖片, 那麼可以這樣子準備訓練用的圖片:
- 看你想訓練哪幾類圖片的辨識網路, 先 畫出這些名詞在 wordnet 裡面的從屬關係。
- 用 wordnet 的 wnid 當作上述的 pcid, 手動建立上述對照表。 好幾個不同的 wnid 可以對應到同一個列印用的字串, 例如 n02481823 n02482474 n02482286 n02482060 這四個 pcid 都對應到 「黑猩猩」, 但它們在對照表當中必須連續出現。 列印字串 (而不是 pcid) 出現的順序, 就對應到 caffe 模型當中的類別代號 (0-5)。
- 按照 wnid 下載 ImageNet 訓練圖片的一小部分。
對了, 產生了 training 的 lmdb 之後, 還要用 $CAFFE_ROOT/build/tools/compute_image_mean 來產生訓練時要用的圖片平均值檔 mean.binaryproto, 再用 bpt2npy 把平均值檔的格式轉成 .npy 以供辨識時使用。
本文所提到的檔案跟指令, 可從 transfer-learning 這個 github repo 下載。 完整的指在 README.md 裡。 超級感謝原作者撰寫程式及教學文: A Practical Introduction to Deep Learning with Caffe and Python。
訓練圖片要用工人智慧細心挑選, 因為 ImageNet 上有一些圖片標錯了 (把紅毛猩猩標成大猩猩之類的很明顯錯誤)。 我只用 CPU 訓練, 跑了兩天左右, 得到 4000 個 iterations 之後的權重矩陣, 測試結果還不錯。 也許更早就可以收工了。 除了侏儒黑猩猩判別率較低 (我自己也判別不太出來; 搞不好訓練圖片也沒餵正確), 其他判別率都還不錯。 參數/時間/正確率的分析, 就等以後再研究吧。
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。