這個禮拜都在處理會遇到 target 變很多個的問題,因為原本的 target 只會有一個(追蹤任務),但我現在變很多個(偵測任務),所以就多了一個維度;但其實最麻煩的問題是,原本只有一個 target 的情況,所有的 anchors 在算類別和迴歸的差異的時候,就全部都去跟唯一的那個 target 算就好了,可是我現在不行,我有很多個 targets,所以每一個 anchor 要去跟 "哪一個" target 去算類別和迴歸的差異就要去找,最後我是用將每一個 anchor 和每一個 target 都去算 iou,然後選和該 anchor 有最大 iou 的那個 target 就是要互相去計算的一個 pair
演算法的部分寫在 bbox.py 的 def target_overlaps() 裡面。方法其實就很基礎,跑兩層 for 迴圈,然後會得到每一個 anchor 和每一個 target 的 iou 的矩陣 [N(anchor), K(target)],然後用 argmax 就可以得到和每個 anchor iou 最大的那個 target,之後再把這個東東放去 def target_delta() 裡面去計算 delta(迴歸)。
以上就是這個禮拜處理的東西 (應該花了有 3,4天😥),主要是因為多維的矩陣讓我很難確定是好好對齊維度的 qq。
成功讀到資料了,真感動,雖然裡面的 bbox 和 圖片大小都還是錯的 哀,但至少把多個 targets 的問題處理好了,可是不知道後面還會有多少問題...,現在又遇到一個神奇的問題,RuntimeError: Trying to resize storage that is not resizable
,但現在是 02:37,有夠晚,可是仲瑜也還在線上!! 但我要去睡了 嗚嗚。
上面的問題我先把 num_worker 設為 0,就 "暫時" 沒事了,但這是假象,因為會報錯的原因是有些 annotations 是空的,導致沒辦法 iter。
RuntimeError: stack expects each tensor to be equal size, but got [4, 1] at entry 0 and [4, 2] at entry 2
然後我又遇到類似的 bug,因為 target 的數量不一樣導致的...;問了亭儀後,我其實馬上就找到方法,要在 dataset 裡面多加一個 def collate_fn(),用不同的方法傳資料 (真的超麻煩)- AttributeError: 'list' object has no attribute 'cuda'
把裡面的每個元素都 .cuda()
我發現想要把所有遇到的問題都記下來真的太麻煩了,而且應該很難遇到一樣的情況,頂多類似,類似的話應該也可以想起來之前是怎麼做的,就像解數學題目一樣的感覺,反正今天終於成功讓他跑起來了。
然後發現 phew 一下就跑完了,原來它竟然只有跑一個 epoch,應該是因為原本是使用了 4個資料集,已經超級大了,這個地方需要改一下。
不過現在最重要的是切 template, search 的方式不太對,要先弄這部分,希望其他部分不要有太大的問題,拜託~~。
整天都在對資料有沒有標籤錯誤,也是遇到一堆奇怪問題,像是 cv2 讀進來的資料是 BGR,用 cv2 畫圖的座標一定要整數,bbox 一下子是比例,一下是 corner 又或是 center,反正一堆神奇的問題,但我真的覺得在一開始如果都寫清楚 訂好的話,就不會一堆我看不懂的問題了,不然至少寫一個註解吧...;但其實現在裡面怎麼切割圖片和放大縮小的我完全沒看,因為真的太醜了,而且不知道它的原理慢慢理解超級花時間,現在雖然程式跑起來了,但是還有很多問題要解決,loss 降不下來, 負樣本還沒給, nms, k-means 找 anchor,有夠多的拉。
晚上在處理 test 的部分,我拿我的模型效果真的頗差,但是用官方的權重檔,效果變超好!! 真的是滿厲害的ㄟ,看來接下來要把 train 的部分搞定了,像是加入 neg (負樣本) 之類的,我也不確定他們要怎麼用 其實...。
- 處理拿 neg 會遇到 anchor 的問題 (我改成任意選擇一個當作 target)。
- 用單一目標的情況,loss 變超低,可是我自己寫的多目標追蹤 loss 很高,所以應該就是我那裏寫的有問題。
晚上正式讓多目標的也正常跑起來了!! 好感動,結果之前錯的原因是因為我 IoU 算錯,我的算法讓沒有交集的也會有 iou (因為我取距離後的絕對值),總之就是全錯的,後來改成原版的算法後就整個正常了...,我也是對自己傻眼,竟然錯在這個地方,寫程式就是這樣吧,不每個地方都小心檢查永遠都不知道自己錯在哪裡!!。
今天整天在搞資料集,剛開始花太多時間在弄論文使用的資料集了,他的和我的方法真的差滿多,所以其實不太需要去參考她的做法,不過還是簡單介紹,
我是用 coco 當作測試,在一開始的 par_crop.py 裡面,就已經對圖片做處理了,他將拿到的 train 影像,做了一些隨機裁切,具體怎麼做我不是很想看懂了,但反正最重要的是,在這裡的所有 search 的中心點的 127x127 的範圍,都是 template,這點超重要,因為在他的 dataset.py 裡面,就已經全部把 search 的中心當作是 template 的中心了,一開始看就覺得莫名其妙,為甚麼 template 一定是在影像的中心阿?? (話說這樣也頗賤,直接在一開始就偷做處理,不過好處就是以後跑程式就都不用在執行這個,速度會變快,或許我也可以考慮🤔)。 之後 dataset.py 還有是把 search 做論文裡面有提到的 shift 動作,讓 search 裡面的 template 不會都一定是在中心點了,這裡我也沒深入理解 code 的具體怎麼實作,因為我的題目應該用不到,我有很多個 target,所以本來就會平均散佈在 search 的影像中了。
今天把 template crop 的部分完成,我現在先設定成沒有背景的情況 (我自己也覺得比較合理),把 template 根據長邊進行縮放,然後再移動到 127x127 template 的中心,其餘部分 padding 成黑色,之後還想加一個參數可以調整要加入的背景範圍多寡。
早上花個兩個小時就把 search crop 的地方做完了,過程很順。 原因是我基本上是很清楚知道我要達到甚麼目標,以及我現在擁有甚麼,我可能可以使用的方法有哪些,我真的非常需要一個清晰且完整的流程圖在我的腦中,只要腦中有這個架構我就可以寫得很順,其實我覺得更重要的是工具,就是我可以使用哪些方法,我常會陷入一個輪迴是,我總覺得現在的方法不夠好,一定有更好的方法,所以就一直東翻西翻,然後就浪費時間,可能真的有更好的方法,但我也要花更多時間研究 我搞不好還看不懂,不如先用現有的方法,除非真的跑很慢,不然先求有再求好比較重要。
晚上非常認真的認知到一件事 (之前就有察覺,但沒有 "深刻" 的刻在腦子中),就是 training 時候的 model 和 testing 時候的 model 是寫在兩個完全不同的檔案裡的!!
- train: ./models/ 裡面
- test: ./tracker/ 裡面
我在看訓練和測試的時候一直翻來翻去,我整個超級混亂,想說為甚麼互相一直呼叫,原來是分成兩個大架構!! 搞清楚這點後應該會看得更順了。
p.s. 我覺得他整個的取名都不好,讓我超級混淆...,不知道是不是因為追蹤都這樣取,snapshot/ 裡面是放訓練好的 model,我問號??
奧 另外,這裡面有用到繼承,真的是我看那麼多少數有用到繼承方法的人呢。 他在 self.get_subwindow() 有用到,我想說這個檔案裏面怎麼找都找不到,原來是因為這個 class 是繼承自另外一個 class (SiamRPNTracker 繼承自 SiameseTracker),滿酷的拉,但我還是覺得他的寫法很亂,而且取名很爛 xd。
今天在處理測試也要用無背景的資料,還有花很多時間在研究 anchor 的設置,我不太懂他到底是在設定啥,而且 training 和 testing 的 anchor 的定位座標不一樣,讓我滿頭問號?? 所以現在跑出來的框框會是全部歪的。
所以明天就來處理 anchor 的定位問題啦,希望明天可以處理好。
終於應該是看懂了 anchor 的設置,training 和 testing 的設置真的不一樣,大小是一樣 但是座標不一樣!!! 這真的讓我搞超久
- training 時是把左上角當作 (0, 0)
- testing 時是把 "中心" 當作 (0, 0) 當時 ori 這個參數就讓我滿頭問號了,果然是他出的問題,他就是在設定起始位置的。那為甚麼 testing 的時候要這樣設定呢? 應該就是為了要縮放回原圖的時候比較簡單,因為把中心當作原點的話,乘以二, 除以二 框框的位置就會直接跟著移動,不需要再去做其他的微調,如果是以左上角當原點的話,就不能直接把座標乘二除二了,其實這招還真的滿聰明的ㄟ,可是我真的因為這個設定讓我熬夜好幾個晚上...。
我可能真的發現為甚麼跑那麼慢囉,我印出在 __getitem__
需要的時間,結果需要 0.1 ~ 0.5 秒,然後再特別去看,發現時間都花在 target_overlap
這步,因為這裡是在 Dataset
運算 也就是用 cpu,當然比較久,然後我再去看其他人怎麼算的,才發現原來大家的 cls
, delta
這些東西都是在 forward
裡面運算,也就是 gpu,我傻眼,當初他們這樣寫我也就跟著做,沒有想這麼多,果然寫 code 是真的需要 coding 之外的其他能力 才有辦法變成很會 coding 的人,要想怎麼樣才能讓 code 的效率變好。