最近一點微小的工作
update一下performance:
coco的resnet101到了34.3,比tf-faster-rcnn還要高那麼一丟丟了,所以我就假裝這個代碼是Ok的了。(vgg的coco結果差超多。。。。但是我也懶得管了,vgg是什麼,能吃嗎)
每年夏天我都要做一下faster-rcnn。。。。我也不懂了。
去年做torch的faster rcnn的起因,是想做來提升captioning結果的。然後就從densecap出發,做了一個faster rcnn。
原本以為會很簡單,因為感覺大體的結構一毛一樣嘛,densecap就是從faster-rcnn來的結構嘛。。。結果改成傻逼了。各種改。。最終也沒復現出來。(現在感覺可能是因為用了spatial transformer network啊。。。。。)
至今我好像也沒有看到成功的torch上的faster-rcnn的復現。fast-rcnn倒是有。。。。真奇怪。。。
今年又重新做faster-rcnn。起因是,同實習的小夥伴要用faster-rcnn,我問那你用什麼,他說用tensorflow,我說為啥不用pytorch,他說因為現在pytorch實現的結果都一般,都沒有認真調;我想,哎喲我去,這怎麼行,然後就自己開始寫了。。。
當然也沒有從頭開始造輪子;小夥伴跟我說他用的tf-faster-rcnn,裡面結果很好,所以我就是直接tf-faster-rcnn clone,然後開始改。
其實主要的代碼並沒有改多久,基本上還是很簡單的,但是一開始結果不行。一會就nan。
結果發現是沒有zero_grad。。。。。。。
反正又遇到一些問題,一個是vgg取的layer取錯了。。。取成了pool5,應該是conv5_3,導致nan。。。。。。第二個是resnet固定參數固定batch norm亂七八糟的。其實都不難,都是細節。
anyway,現在的版本至少在pascal voc的結果差不多和tf-faster-rcnn match了。。。。。。。雖然就是差那麼1。。。。。。
coco結果似乎差很多。。。。。。不知道為啥~~~~講道理嘛如果voc結果差不多的話,也不應該coco差這麼多啊?????
github在這,ruotianluo/pytorch-faster-rcnn,pretrained模型都有,雖然coco上的只有非常弱的版本。(長的最近還在訓練。。。。。。太慢了。。。。。)
強迫症部分:
1. tensorboard
雖然我非常討厭tensorflow,但是我非常喜愛tensorboard!
visdom看起來也不錯,但是總感覺差了這麼一點。(最近好像有看到對visdom有類tensorboard的分裝,可以看看。但是tensorboard確實做的真的好啊)
由於原本的tensorflow版本都是對圖中的node做summary operation,最後session run的時候一起跑,但是我由於沒有內部節點,所以沒法直接獲得summary op。結果我就專門開了一個計算圖,這個圖沒有別的,只有placeholders(所以其實不是圖),然後所有的operations都是summary。。。。session run只干一件事,收集summary。。。。。
雖然很傻逼,但是至少給了我tensorboard可視化的結果。
然後。。。。後來我看到了一個東西叫tensorboard-pytorch。。。。。。。。
(其實之前不是沒有tensorboard普適版,什麼crayon啊,mxnet也有一個tensorboard。。。但是。。。功能貌似都不全)反正tensorboard-pytorch是我第一個看到幾乎支持所有tensorboard功能的(甚至還可以展示pytorch 的計算圖),雖然他其實就是對tensorboard做了一個封裝——所以你還是要裝tensorflow。(但是裝tensorflow還是很方便的)
但是我現在github裡面的code還沒改成用tensorboard_pytorch,因為最近冒出了一系列類似的東西。tensorboard_logger(這個好像很垃圾功能很少), inferno(除了tensorboard還有trainer什麼的)
所以,再觀望一段時間好了。
2. python layer
py-faster-rcnn還有tf-faster-rcnn都是中間有python layer的。就是要把網路當中結果拿出來,放到python下運算。
其實py-faster-rcnn還好。。。。tf-faster-rcnn那個py_func真的是超級麻煩。。。。。。
pytorch其實就跟py-faster-rcnn差不多,不需要弄個啥py_func,直接拿出來中間接過來放進去,非常順暢,就是一個普通的python function。
其實好好的不要去動它挺好的。。。。。。但是我心有不甘。。。。。
怎麼可以這麼幾層用python,用numpy呢!!!!!
而且,因為我的crop_and_resize使用stn實現的(crop_and_resize是roi pooling的替代品,說比roi pooling效果好),所以我就想如果全部在pytorch下,就可以從stn也獲得offset的gradient了(事實上,stn獲得gradient之後效果差了很多。。。。媽蛋。(所以去年densecap寫失敗是因為這個原因嗎。。。。))。
於是我就試圖把這幾層改成torch的。。。。。。。踏上了一條不歸路。(浪費了超多生命)
1 )gpu下做nms
一開始想法是follow densecap的做法,他也是在gpu下做的nms,用的torch
然後我就直接按照他的做。(他比一般的c下的nms演算法有點區別,為了避免indexing的耗時) jcjohnson/densecap 可以看一下。
然而還是巨慢
然後我就想,算了反正py-faster-rcnn本來就有gpu的nms_kernel就用那個了。(誒,既然有gpu version,為啥還要自己寫,因為原本的gpu_nms接收的是numpy array;所有對我們的code來說,其實很腦殘,我們先把cudatensor轉成了cpu numpy,然後在gpu_nms裡面又把這個numpy放會了gpu里。。雖然其實時間上差得好像沒那麼多,但是。。不爽)
然後我就用cffi手寫了好幾個。原本的nms_kernel分成兩部分,一個是算overlap,用cuda寫的,一個根據overlap做supression,在cpu下做的。
我第一個版本就是把suppression也放在了gpu下做,開了一個單線程的kernel。。。。慢。。。。。(但是就算這樣也比densecap那種方法快了無數倍;只是比原本得拷來拷去的gpu_nms要慢)
然後我就把supression放回了cpu。速度快了一些。
(把代碼改成TH api研究了很久。。。感覺自己又會寫c了(各種不打分號。。。。))
2 )numpy的argsort和torch.sort
其實還有一個提速的點是排序。用gpu下的torch.sort就會快很多。然而一開始調試的時候,為了match faster-rcnn的nms結果。。。。。怎麼都不match。。。。
後來發現。。。原來是sort的結果不一樣媽蛋。torch.sort對於值相同的element,順序是隨機的。。。。。。
Order of equal elements after torch.sort
可以試一下我上面的代碼。。。。大概是因為並行的原因吧。。。。。
但是這浪費了我超級超級久的時間。。。。。。一步一步測試啊。。。。。真是坑爹。。。
3 )np.random.choice vs torch.multinomial
proposal_target_layer有一步是sample roi,需要uniform隨機選取proposal。一開始我使用了torch.multinomial,輸入就是一個每個點都概率一樣。結果超級超級慢(平均一個iteration要花0.02秒)(可想而知又是各種看每個步驟的時間,賊麻煩)。
然後我就用np.random.choice。。。。。(0.003秒。。。)
差的也太多了吧。。。。。
4 )其它一些
雖然現在的nms層快了(大概0.01秒一個iteration),換了np.random.choice快樂,但是proposal_target_layer還是要比原來慢0.003秒一個iteration。。。。。。
還得再細分看每個步驟的時間。。。。再說吧。。。(cudatensor的indexing是真的慢!!!!!!!能不做就別做!!!!)
5) bbox_overlap
之前的代碼用的是一個cython實現的bbox overlap的代碼,然後我改成了numpy,和torch,都用的是np和th裡面的計算部件,照理說應該如果有多線程的話是可以更快的吧。。。。。。以為cython哪個是單線程的。。。然而慢了10倍。。。。。。雖然這個也不是bottleneck,但是特別迷
~~(然而這部分都還在本地,沒有傳到github上,還要改的再好看一點)~~已經放到master了。
faster-rcnn一不小心寫多了;
那另外的一句帶過了:
又重新好好修改了我的neuraltalk2.pytorch的代碼,readme應該乾淨和諧了很多,加了pretrained的model;另外100行不到寫了一個非常屌的model(一篇paper里的),cross entropy training能到1.07的karparthy test split CIDER score。雖然SCST之後效果就不是最好了,但是我也還沒怎麼調。
我也不知道為什麼我要莫名其妙擼代碼。。。。。。我的志向不是software engineer啊,。。。
推薦閱讀:
※一個優雅的框架 | Pytorch 初體驗
※FCN 的簡單實現
※PyTorch中如何使用tensorboard可視化
※PyTorch參數初始化和Finetune
TAG:PyTorch |