Boxx:一個旨在提升 Python 代碼開發和調試效率的工具庫,尤爲在計算機視覺領域

介紹一個Python 工具包 boxxhtml

在調試視覺代碼時, 基本就是和多維數組打交道, 多維數組有不少的屬性,打印起來比較麻煩。 boxx.loga 能夠一次性展示出一個數組的大多數屬性.
python

💡 Note:git

  • loga 是 "log array" 的縮寫, 若 array 裏面還含有 naninf, loga 也會一併提示出來。
  • loga 支持許多能夠轉爲 numpy 的數據類型,包括 torch.tensor, mxnet.ndarray, PIL.Image 等。

作計算機視覺,可視化圖像和 feature 很是重要。boxx.show 能方便地作可視化。
github


💡 Note: show 會在複雜的數據結構中 找出全部多是圖像的矩陣,並一一顯示( plt.imshow)出來。 固然, show 也支持 numpytorchmxnetPIL.Image .etc

在開發 CV 代碼時,會遇到一些複雜的 dict,list(好比 batch、模型參數)。boxx.tree 能夠直觀地展現複雜結構。
編程

💡 Note: 在理解和適配別人的代碼時,常常用到 treetree 還支持自動從 torch.Dataloader/Dataset 中 sample 一個 batch 來可視化 (P.S. boxx.show 也支持)數組


以上三個工具是我在視覺領域常常用到的工具, 接下來介紹一些通用的 Python 開發調試工具,只要寫 Python 代碼,均可以用上。瀏覽器

打印變量是最簡單、直接的debug方式, 那能不能更簡單?
服務器

💡 Note: boxx.p 使用了 magic method, p/x 便會打印 x 並返回 x。這樣即可以在任何地方打印,好比 例子中的 p/randint(0, 3) 就不須要新建變量即可直接打印網絡

在函數內運行 p(),便會將函數或 module 內的全部變量名和值一同打印(至關於快捷打印 locals())
數據結構

💡 Note: 在函數內 import boxx.pp() 有相同的效果

許多數狀況下, 直接 print 沒法得到調試的關鍵信息。 好比訓練 loss 跑飛了, 致使 Bug 的多是 tensor 的尺度/類型不對, 矩陣裏有 nan , inf 等狀況。我曾遇到過 梯度含有nan 的狀況

這時 就必須對矩陣進行分析, 方式有:

  1. 在調試處加上 print(x.mean(), np.hasinf(x),.np.hasnan(x))
  2. 設置斷點進行分析

方法1 每改一次調試代碼 都要運行整個代碼, 不靈活,操做也繁瑣。
方法2 中進入和退出 Debug console 比較麻煩,Debug console 自己也不太好用(沒有自動補全功能)
boxx.g 提供了一種新的方式,經過 g.name 能夠將變量傳到當前的 Python 交互終端

變量傳到 Python 終端後,就能對變量進行全面分析了,好比 使用 logatree 來分析

💡 Note:

  • gg 的意思是 to Global and log, 和 g 的用法同樣, 但 gg 會在傳輸的同時打印變量.
  • 須要注意, 若是以前在終端中存在同樣的變量名稱,則變量的值會被新值覆蓋.

在函數內運行 g(),便會將函數 (或 module) 內的全部變量一同傳到當前的 Python 交互終端

這樣 任何錯誤均可以在終端中復現和分析了。固然, 注意不要覆蓋重要的全局變量。

💡 Note: 在函數內 import boxx.gg() 有相同的效果

在實際開發調試中, 函數或 module 內可能含有很是多的變量 但咱們只對幾個變量感興趣, with p, with g, with gg 可使操做只做用於幾個感興趣的變量,只需把變量放入 with 結構中便可 :


💡 Note:

  • with p, with g, with gg 只做用於在 with 結構中進行賦值操做的變量.
  • 若是變量名在 with 前存在於 locals() 中, 同時 id(變量) 沒有變化 , with 結構可能沒法檢測到該變量.

總結一下,boxx 的調試工具能夠彙總爲一個表

boxx 調試工具矩陣

變量個數 \ 操做 print transport print & transport
單變量 p/x g.name/x gg.name/x
多變量 with p: with g: with gg:
locals() p() g() gg()
locals()_2 import boxx.p import boxx.g import boxx.gg

💡 Note:

  • transport 操做是指 把函數內的變量傳送到 Python interactive console 中
  • locals() 指 做用於函數或 module 內的全部變量
  • locals()_2: 當 boxx 未導入時, import boxx.{操做} 能等價於 from boxx import {操做};{操做}()

在學習新框架或適配大佬代碼時,常常會使用 print(x), dir(x), help(x), type(x) 來了解某個變量的各方面的信息 (變量多是 值/function/class/module 等),因而我寫了一個 boox.what(x) 來全面瞭解"what is x?":


💡 Note: what(x) 經過打印 x 本身及 x文檔, 父類繼承關係, 內部結構全部屬性 來全面瞭解 x. 是 help(x) 的補充.


說了這麼多調試 再說一下性能調優

測試代碼性能時,計時很經常使用, 我寫了一個方便的計時工具boxx.timeit 將想要計時的代碼塊放入 with timeit(): 中就能夠計時了:

此外 SnakeViz 是一個很棒的性能分析工具,SnakeViz 可以經過 cProfile 文件,來統計代碼的函數調用狀況,並可視化出代碼的 火焰圖。可是, 先生成 cProfile 文件,再運行 SnakeViz 的流程很是繁瑣,我把這一套操做封裝成了 boxx.performance 來簡化流程:

💡 Note: performance 也支持字符串形式的 Python 代碼.

現在的數據集都數百上千 GB,在數據清洗和預處理時 要寫多進程的 Python 代碼 來榨乾 CPU 的每個線程得到加速。但我以爲 Python 多進程的幾個範式都不夠方便,我參照 map 的思想和用法把多進程操做封裝成 boxx.mapmp 函數(意思是"Map for Mulit Processing"). mapmpmap 有同樣的用法, 只需把 map 替換爲 mapmp 便可得到多進程加速:


💡 Note:

  • mapmppool 參數來控制進程數目,默認爲 CPU 線程數目.
  • 在多進程程序中, 打印進度每每很是麻煩. mapmpprintfreq 參數能解決這個問題.
  • 如同 map 同樣,mapmp 支持將多個參數輸入函數,如mapmp(add, list_1, list_2)
  • 在 Python 中,多進程代碼最好在 __name__ == '__main__' 環境中運行.
  • 若是加速 numpy 程序,請注意 在 MKL 版本的 numpy 中,多進程會更慢, 能夠運行 boxx.testNumpyMultiprocessing() 來測試當前環境對多進程 numpy 的友好程度

當要下載 url 形式的數據集或網絡爬取圖片時,多線程編程對這類高IO操做會頗有用。boxx 還有個多線程版本的 map -- mapmt (意思是 "Map for Mulit Threading")。mapmt 用法和 mapmp 同樣, 但沒有多進程的諸多限制。


再分享一下我本身在寫視覺代碼的感覺吧

因爲我本身

  1. 寫 CV 代碼離不開強大的 Qt console for IPython
  2. 受不了遠程編輯對網絡的依賴和延遲

因此 一直用 Anaconda 自帶的 Spyder 做爲 Python 開發的 IDE. Spyder 雖然不夠強大,但自帶的 Qt-IPython, 配合本身寫的工具,調試起來仍是比較方便, 順手。因此, 我開發的工具都儘量地直接, 簡潔,上面介紹的大部分工具都支持 func-x 來代替 func(x) 以方便調試時調用。甚至,我還寫了一些字符串處理工具,直接在IPython 內使用, 以彌補 Spyder 做爲 IDE 的不足。

此外,個人工做流通常是 先在本地開發調試, 用 boxx.sysi 檢測運行環境來自動切換運行參數, 本地開發調試 OK 了, 用 rsync 命令 只傳改過的 .py 文件到服務器 再來 train。雖然這樣傳代碼比較麻煩, 但開發, 調試起來會方便不少。

以前在實驗室一直是本地 GPU 環境調試 比較方便。實習後, 曠廠不提供本地 GPU。我主力是 PyTorch, 爲了方便調試 我寫了個 boxx.ylth 包,若是檢測到沒有 CUDA 環境,boxx.ylth 會強行使 .cuda() 和大部分 GPU 操做無效。只要在代碼開頭 import boxx.ylth 大多數只基於 GPU 的 torch 代碼, 能夠不經更改 直接在 CPU 上運行和調試。(這操做太暴力 請慎用)


GitHub 主頁:github.com/DIYer22/box…

安裝:pip install git+https://github.com/DIYer22/boxx (其餘安裝方法及說明)

教程:boxx 的教程是一個可執行的在線 Notebook。 也就是說,無需下載和運行任何代碼,只需瀏覽器點擊下面的連接,就能夠在線執行 Notebook 教程中的代碼塊。
=> 可直接執行的在線教程

最後 特別感謝徐曉棟、吳國棟、範浩強和熊鵬飛對 boxx 提出的建議。

相關文章
相關標籤/搜索