我用的是Ubuntu16.04,顯卡是2070s,python3.6,cuda版本是9.0(系統環境安裝),pytorch版本是1.0.0。
一、運行的一些注意事項:
1.數據集linemod_preprocessed(一共有13個類:1、2、4、5、6、8、9、10、11、12、13、14、15)
class | 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | total |
train | 186 | 181 | 181 | 180 | 177 | 179 | 189 | 188 | 184 | 186 | 173 | 185 | 184 | 2373 |
test | 1050 | 1031 | 1020 | 1016 | 1002 | 1009 | 1065 | 1065 | 1036 | 1051 | 979 | 1042 | 1041 | 13407 |
文件夾linemod_preprocessed下的子文件夾為:data、models、segnet_results。
其中
(1)data文件夾:雖然序號是到15,但是實際上只有13個文件夾,3和7文件夾是沒有的。分別對應13個類別。
隨便進入一個文件夾,如1:
1. depth(目錄): 深度圖;
2. mask(目錄):目標物體的掩碼,為標准的分割結果;
3. rgb(目錄):保存為RGB圖像;
4. gt.yml(文件):保存了拍攝每張圖片時,其對應的旋轉矩陣和偏移矩陣,以及目標物體的標准box, 和該圖像中目標物體所屬於的類別;
5. info.yml(文件):拍攝每張圖像,對應的攝像頭的內參,以及深度縮放的比例;
6.test.txt(文件):划分好的測試數據集;
7.train.txt(文件):划分好的訓練數據集。
(2)models文件夾
Linemod_preprocessed\models中每個ply文件,其中的點雲信息,都是以linemod\Linemod_preprocessed\data\xx\rgb\0000.png作為參考面的。有了這個參考面的點雲數據(包含了整個目標的完整點雲),我們就能根據其他的拍攝照片時的攝像頭參數(旋轉和偏移矩陣),計算出其他的視覺對應的點雲數據了。
models_info.yml文件,其保存的是每個目標點雲模型的半徑,x,y,z軸的起始值和大小范圍。
(3)segnet_results文件夾
在訓練模型的時候,是拿最標准的數據去訓練我們的模型,所以訓練和驗證時,都是使用最標准的mask(Linemod_preprocessed/data/mask),作為分割的標簽。
但是在測試的時候,要結合應用場景,我們希望越接近實際場景越好,在實際場景中,DenseFusion網絡是對分割出來的目標進行姿態預測,所以實際應用中,還需要一個分割網絡。所以segnet_results中,保存的就是語義分割網絡分割出來的圖片,為了和實際場景更加接近,這也是其和標准的mask的一點區別。
2.軟鏈接的問題
將代碼文件夾的數據集文件夾鏈接到解壓縮的數據集文件夾:ln -s 解壓縮后的數據集文件夾的路徑 代碼里的數據集文件夾路徑
ln -s /home/zza/datasets/LineMOD/Linemod_preprocessed /home/zza/code/DenseFusion-master/datasets/linemod/Linemod_preprocessed
解壓縮后數據集的路徑(這里的Linemod_preprocessed文件夾是實際存在的) 代碼的數據集文件夾路徑(這里的Linemod_preprocessed文件夾不用創建,運行這句命令后會自動生成,會是一個帶有向上箭頭的文件夾,如下圖:)
3.將訓練好的模型用於測試:
python3 ./tools/eval_linemod.py --dataset_root ./datasets/linemod/Linemod_preprocessed --model trained_models/linemod/pose_model_current.pth --refine_model trained_models/linemod/pose_refine_model_current.pth
測試結果(成功率)為:
二、運行出現的問題:
1.下載的版本的問題
DenseFusion-master:是0.4版本。https://github.com/j96w/DenseFusion
DenseFusion-Pytorch-1.0:是1.0版本。https://github.com/j96w/DenseFusion/tree/Pytorch-1.0
2.在運行./experiments/scripts/eval_linemod.sh的問題
'AttributeError: module 'lib.knn.knn_pytorch' has no attribute 'knn'' .
解決辦法:
在/home/zza/code/DenseFusion-Pytorch-1.0/lib/knn運行:python setup.py build和python setup.py install,然后會在/home/zza/code/DenseFusion-Pytorch-1.0/lib/knn生成dist文件夾,將里面的knn_pytorch-0.1-py3.6-linux-x86_64.egg文件解壓,將knn_pytorch-0.1-py3.6-linux-x86_64.egg_FILES/knn_pytorch里面的knn_pytorch.cpython-36m-x86_64-linux-gnu.so和knn_pytorch.py文件復制到/home/zza/code/DenseFusion-Pytorch-1.0/lib/knn目錄。
還會有一個問題:
將一個語句的前面的“_,”去掉即可。
3.在運行./experiments/scripts/train_linemod.sh的問題
每記錯的話應該是這個ImportError: libcudart.so.9.0: cannot open shared object file: No such file or directory
我一開始是cuda9.0,然后換成了cuda10.0和在pytorch官網安裝了對應的pytorch; 然后又換回cuda9.0,再在pytorch官網安裝了對應的pytorch就可以了,也不知道為啥。
4.在訓練時如果出現中斷,可以加載訓練了一段時間的模型(--resume_posenet pose_model_current.pth),繼續訓練,而不用重新訓練。
python3 ./tools/train.py --dataset linemod --dataset_root ./datasets/linemod/Linemod_preprocessed --resume_posenet pose_model_current.pth
5.在訓練過程中會中斷,是因為誤差滿足要求,要開始訓練refinenet,代碼出現錯誤。
RuntimeError: the derivative for 'index' is not implemented
解決辦法是:

添加了.detach()
三、開始復現
訓練過程:訓練過程包含兩個部分:(i)DenseFusion模型的訓練。(ii)訓練迭代優化模型。在此代碼中,將首先訓練DenseFusion模型。當平均測試距離結果(非對稱對象的ADD,對稱對象的ADD-S)小於一定的余量(refine_margin)時,迭代優化模型的訓練將自動開始,然后DenseFusion模型將被固定。您可以更改此margin以在不進行細化的情況下獲得更好的DenseFusion結果,但它比迭代細化后的最終結果差。
checkpoints和resuming:每訓練1000個批次后,將保存一個pose_model_current.pth
/pose_refine_model_current.pth
檢查點。您可以使用它來恢復訓練。在每個測試時期之后,如果平均距離結果是迄今為止最好的,則將保存一個pose_model_(epoch)_(best_score).pth
/ pose_model_refiner_(epoch)_(best_score).pth
檢查點。您可以將其用於評估。
注意:迭代精化模型的訓練需要一些時間。請耐心等待,經過約30次練習后,情況才會有所改善。
訓練之前我先用linemod_preprocessed數據集給定的模型進行了驗證,結果如圖所示:
可見,成功率有0.95。
訓練的時候會加載2373張訓練集,但會重復訓練20次,所以就會有2373X20=47460幀,但是由於batch_size是8,所以47460/8=5932.5,最后不足8張,所以只會有5932個batch加載,即:5932X8=47456幀。
加載1336張測試集。
1.第一次訓練只需要加載訓練要用的數據集即可:epoch:29(1~30),在第30個epoch停止。時間:9h53m30s。Avg dis:0.011346239087811091。Avg dis:平均距離(average distance)ADD。
python3 ./tools/train.py --dataset linemod --dataset_root ./datasets/linemod/Linemod_preprocessed
其實不止29個epoch,因為之前訓練出現了中斷之類的很多情況,這里我是直接用了之前訓練的姿態估計模型來繼續訓練,由於refine_margin沒有達到預定的值(0.013),所以沒有進行姿態細化模型的訓練,自然也就沒有它的模型了,所以也加載不了。
python ./tools/eval_linemod.py --dataset_root ./datasets/linemod/Linemod_preprocessed --model pose_model_current.pth
訓練會產生一些log文件和訓練出來的模型(包括姿態估計(pose_model_current.pth)和姿態細化(pose_refine_model_current.pth)的模型),
其中log文件保存在/home/zza/code/DenseFusion-Pytorch-1.0/experiments/logs/linemod,
模型保存在/home/zza/code/DenseFusion-Pytorch-1.0/trained_models/linemod。
訓練完成之后可以使用驗證腳本進行驗證:(--model是自己訓練好的姿態估計模型,--refine_model是自己訓練好的姿態細化模型)
python ./tools/eval_linemod.py --dataset_root ./datasets/linemod/Linemod_preprocessed --model trained_models/linemod/pose_model_current.pth --refine_model trained_models/linemod/pose_refine_model_current.pth
驗證結果如圖所示:
成功率只有0.8,可知結果並不是很好。
2.第二次訓練:epoch:29(30~59),在第59個epoch停止。時間:12h17m09s。Avg dis:0.011077157911425595。
由於第一次的成功率並不高,我以為將refine_margin(當Avg dis小於refine_margin時就會開始訓練姿態細化模型)這個參數設置低一點,結果會有所提升,我就將默認的值(0.013)改成了0.0013(后面又該成0.065),由於第一次訓練Avg dis就低於refine_margin,第一次訓練就有姿態細化模型了,但是我並沒有對它進行加載,而只加載了姿態估計模型,但是設置的refine_margin過於低了,導致訓練完所有周期也沒有開始重新(沒有加載先前訓練好的姿態細化模型,會重新進行訓練。但是由於Avg dis並沒有低於refine_margin而沒有進行訓練)訓練姿態細化模型,因為很難達到那么低的值。我覺得這也是導致這次結果比第一次結果還要差的原因:沒有進行姿態細化模型的訓練,而是使用了第一次訓練的姿態細化模型來進行驗證。
驗證結果如圖所示:
成功率比第一次還要低了。
3. 第三次訓練:epoch:30(1~31),在第31個epoch停止。時間:9h15m23s。Avg dis:0.008868885608165159。
這一次訓練我將refine_margin改回了默認值(0.013),並且加載第一次訓練的姿態細化模型,所以它就會停止訓練姿態估計模型,並開始訓練姿態細化模型。可見下圖:輸出的第一個模型名字就是姿態細化模型的名字(pose_refine_model_1_0.010882976234449258.pth),而不是姿態估計模型的名字,代碼就是這樣,如果沒有加載姿態細化模型且Avg dis並沒有低於refine_margin,那么輸出的模型名字就是姿態估計模型的名字。
python3 ./tools/train.py --dataset linemod --dataset_root ./datasets/linemod/Linemod_preprocessed --resume_posenet pose_model_current.pth --resume_refinenet pose_refine_model_current.pth
驗證結果如圖所示:
這次的結果有所改善,且開始接近linemod_preprocessed數據集給定的模型驗證的成功率。
所以1、2、3一共訓練了有88(29+29+30)次以上。
4. 第四次訓練:epoch:30(31~61),在第61個epoch停止。時間:9h14m22s。Avg dis:0.007780234729972233。
這一次我修改了refine_margin:0.008,並且同時加載姿態估計模型和姿態細化模型,而且由於加載了姿態細化模型,那么它就只會訓練姿態細化模型(看代碼是這樣的,要么加載了姿態細化模型,要么Avg dis低於refine_margin,它就會開始訓練姿態細化模型),而不會訓練姿態估計模型。可見下圖:輸出的第一個模型名字就是姿態細化模型的名字(pose_refine_model_31_0.008742919701296547.pth),而不是姿態估計模型的名字,代碼就是這樣,如果沒有加載姿態細化模型且Avg dis並沒有低於refine_margin,那么輸出的模型名字就是姿態估計模型的名字。
驗證結果如圖所示:
可見這次的結果已經優於linemod_preprocessed數據集給定的模型驗證的成功率了。
所以1、2、3、4一共訓練了有118(29+29+30+30)次以上。
5. 第五次訓練:epoch:30(61~91),在第91個epoch停止。時間:9h26m27s。Avg dis:0.007370748565341262。
這一次我保持上次的refine_margin:0.008,還是同時加載姿態估計模型和姿態細化模型,而且由於加載了姿態細化模型,那么它就只會訓練姿態細化模型(看代碼是這樣的,要么加載了姿態細化模型,要么Avg dis低於refine_margin,它就會開始訓練姿態細化模型),而不會訓練姿態估計模型。可見下圖:輸出的第一個模型名字就是姿態細化模型的名字(pose_refine_model_61_0.007777808692393766.pth),而不是姿態估計模型的名字,代碼就是這樣,如果沒有加載姿態細化模型且Avg dis並沒有低於refine_margin,那么輸出的模型名字就是姿態估計模型的名字。
驗證結果如圖所示:
可見這次的結果也是優於linemod_preprocessed數據集給定的模型驗證的成功率。
所以1、2、3、4、5一共訓練了有148(29+29+30+30+30)次以上。
時間一共用了:50h6m51s