用 tf.slim train 好了 model 以後,要拿來做 inference 才發現腦袋不大清楚不知道怎麼弄,查了一下,看到這邊,原來 tensorflow 本身就有提供 freeze 的工具,slim 也有 script 讓使用者可以方便的 export model。
照著註解裡面步驟做就可以了,兩步,橫簡單,連我都會。
昨天浪費了我幾個小時在那邊摸索,真的很笨。不知道昨天為什麼突然忘記「開始動手做之前先看看別人怎麼做」我的天哪...
[0] https://github.com/tensorflow/models/blob/master/slim/export_inference_graph.py
2017年6月28日 星期三
2017年6月22日 星期四
TF.slim 吃自訂格式的 data
Tensorflow.slim 預設是吃他 TFRecord。但我的圖很多,我不想全部轉成 TFRecord,這樣會吃掉很多硬碟,我想要保留 .jpg 的檔案在硬碟裡,然後有一個文字檔,裡面描述了哪些檔案有哪些 label。
0.jpg -1:* 1:0,7
1.jpg -1:* 1:1,2,4...
表示 0.jpg 這張圖,有第 0 個 label 跟第 7 個 label。這兩個 label 是 1,其他都是 0。然後 1.jpg 這張圖,有第 1 第 2 第 4 個 label,其他都沒有。至於總共有多少 label,在描述 dataset 的 .py 檔會有寫。
slim 有自己的 reader class,有做了 parallel reader,對於需要大量訓練的時候可以加快 read data 的時間,但是 reader 讀進來之後,decoder 卻只有一個人。如果 decoding 需要很多時間,那這邊就會有問題。為了繞過這個問題,我決定把 reader 跟 decoder 合併在一起。
我根據 slim 的 parallel_reader.py 加了一個 parallel_reader_decoder.py,multi-thread 在讀取檔案以後,同時就會去 decode,之後才放進一個 common queue 讓之後的 node 取用。
這邊註記幾點:
- 寫 decoder 的時候,真的要注意效能問題,本來我用很 python 的方法在處理 numpy 陣列,後來發現效能慘不忍睹,改用 numpy style 以後 performance 快了幾百倍。
- tf.py_func() 就很好用,不一定要用 C++ 去寫 Op,當然如果真的需要就不要偷懶。
- tf.losses 會幫忙把 loss 登錄到 GraphKey.LOSSES,之後會有人去取用,所以不要覺得好奇怪為什麼這個 loss 都沒有人用到
- 記得把 slim 的 preprocessing thread 的數量也開到對,不然你會發現 reading 夠快,decoding 夠快,GPU 的 forward computation 跟 backward propagation 也夠快,但是 throughput 就是有夠低。最後發現是死在 preprocessing thread 數量太少。這個數值跟你的 model 所需要的 preprocessing 複雜度有關。mnist 的 preprocessing 很簡單,一個說不定就夠了,inception 可能要 4(或 8?)。
- slim 裡面有幾個 queue,queue capacity 記得要改到夠大,pop 以後的 min-size 也要調整(小),不然你會發現他一批一批的做,比方說你 queue capacity 是 16,min-size 卻是 8,但是你有 8 個 clone,這樣他一次要吃掉 8 個,吃完以後這個 queue 的 producer 才會做事,很不方便。這樣這個 queue 等於沒有 buffering 的效果。
- Filename Queue (after enumerate files)
- Parallel Reading Queue (after read)
- Prefetch Queue (after preprocessing)
- Batch Queue (after batch packing)
- 開太多 preprocessor 的話,tensorboard 秀 graph 會 gg =_=||
- sigmoid_cross_entropy 不要亂餵,他的值域就是 0 ~ 1,雖然我自己的 multi-label 標注方法是 1 positive, -1 negative, 0 don't care,但計算的時候,不要去把 logit 轉換到 -1 ~ 1,而是要把 label 從 -1 ~ 1 轉換成 0 ~ 1(但是 label 真的是 0 的時候,要記得 don't care)用tf.abs 跟 tf.maximum 可以做到。不難。
2017年6月18日 星期日
tensorflow 自訂 operator
考慮開發速度的話,先使用 tf.py_func [0]
如果遇到限制,或是考慮執行效能的話,再去看 Adding a New Op [1]
雖說 [1] 比 [0] 麻煩,但其實也相當簡單,不用害怕,進去看著照做就可以了,半個小時的事情
[0] https://www.tensorflow.org/api_docs/python/tf/py_func
[1] https://www.tensorflow.org/extend/adding_an_op
如果遇到限制,或是考慮執行效能的話,再去看 Adding a New Op [1]
雖說 [1] 比 [0] 麻煩,但其實也相當簡單,不用害怕,進去看著照做就可以了,半個小時的事情
[0] https://www.tensorflow.org/api_docs/python/tf/py_func
[1] https://www.tensorflow.org/extend/adding_an_op
訂閱:
文章 (Atom)