用了一段時間PYTORCH,感覺這個開始用着很得勁的,所以把BUG梳理一下,再接再厲,祝大家寫的一手好BUG,
並能調的通。- —— -
圖像分割任務相對特殊的就是他的標籤,是類別圖,這也是pytorch有意思的一點。
pytorch的NLLLoss2d用來做n類圖像分割,接受的每個數據的標籤是 W x H 的標籤圖,每個像素上是該元素的類別號從0開始,到C-1,官方文檔是這麼描述的:
#Input: (N,C,H,W) where C = number of classes
#Target: (N,H,W) where each value is 0 <= targets[i] <= C-1
所以這種標籤圖mask在轉tensor的時候不能用ToTensor,直接用torch.from_numpy(mask)就好啦。
下爲我用的代碼的這一部分(放在繼承類class MyFolder(ImageFolder)的def __getitem__(self, index)裏),寫的不好,還請指正:
mask=np.array(mask)[...,0]
#這句爲啥一會兒解釋,實在是因爲BUG,加這麼一句調好了兩個BUG,神不神奇。
mask_label=np.zeros(mask.shape,dtype=np.int64)
for i,label in enumerate(self.labels[1:]):
mask_label[np.where(mask==label)]=i+1
mask_label=mask_label.astype(np.int64)
好的,下面說下爲啥要在上面轉類型,因爲計算loss的函數規定標籤圖必須爲torch.cuda.LongTensor(如果放進cuda的話),不然就會出這個BUG:
TypeError: CudaClassNLLCriterion_updateOutput received an invalid combination of arguments - got (int, torch.cuda.FloatTensor, !torch.cuda.IntTensor!, torch.cuda.FloatTensor, bool, NoneType, torch.cuda.FloatTensor), but expected (int state, torch.cuda.FloatTensor input, torch.cuda.LongTensor target, torch.cuda.FloatTensor output, bool sizeAverage, [torch.cuda.FloatTensor weights or None], torch.cuda.FloatTensor total_weight)
解決方案分兩種:
一種是一開始就在處理數據是用.astype(np.int64)轉成long的格式,到時轉tensor自動變torch.cuda.LongTensor
還有一種是在轉成tensor後放到cuda裏前使用Tensor.type(torch.LongTensor)進行轉換。
感謝大佬 http://blog.csdn.net/u011276025/article/details/73826562,這個BUG是學習他的自己總結的。
2.cuda bug:
RuntimeError: cuda runtime error (59) : device-side assert triggered at /pytorch/torch/lib/THC/generic/THCStorage.c:32
這個BUG看了好久,大家普遍認爲是標籤出了問題,仔細斷點查找數值變化發現一個人的標籤中出現-1,發生了類似的錯誤:
所以我重新產生了一個0矩陣,只變我的標籤像素對應的類別號,這樣就濾去了樣本標籤中可能存在的問題。
問題也可能是別的,我的錯誤可以這麼解決,大致就是:標籤有問題!