PyTorch 有哪些坑/bug?

轉 PyTorch 的人越來越多了,不過 PyTorch 現在還不夠完善吧~

有哪些已知的坑呢?


分享一下我最近的踩坑經歷吧

這幾天在實現一個語義分割的loss

該loss考慮了邊緣,結果一致性等因素 如圖

loss最複雜的部分

由於公式較為複雜, 決定用風格和numpy相似的pytorch來實現

再由於torch是動態圖 而且 Python的for循環很慢, 所以打算全用Tensor操作。

想著應該和numpy差不多 難度中等 加上熟悉API的時間 一天足夠了

開工前 準備了一組(image, ground truth, 及假裝是分割網路結果的概率矩陣prob) 作為測試用例, 然後 正式開工!

image, ground truth 及假裝是分割網路結果的prob

寫著寫著 發現處理後的圖片根本不對,可視化一下.發現 ground truth轉化成`FloatTensor`後 就成了這個鬼樣子

查明後 原因是: 對`torch.FloatTensor`傳一個bool的numpy array , 即`torch.FloatTensor(Bool_Ndarray)` 就會成為上面這樣的亂碼

得先轉化為float32 即 `torch.FloatTensor(np.float32(labels))`

繼續寫 咦 torch不支持[::-1]和flip?那自己寫一個flip

又繼續寫, 全Tensor操作, 遇到複雜公式, 就意味著超多維度的select, index, 緯度變換,緯度匹配 ,若出了bug 分析起來特別麻煩

比如:

otherSideEdgeLossMap = -th.log(((probnb*gtind).sum(-3)*gtdf).sum(-3)/gtdf.sum(-3))

這麼黑燈瞎火地寫下去,調試又複雜又慢。

工欲善其事, 必先利其器

於是 我便先去改之前只支持numpy可視化的工具代碼 yllab ,增加其對torch的支持。

配合`Ipython@Spyder` 調試效率提高不少 比`print xx.shape,xx.mean()` 不知高到哪裡去了

最後, loss總算寫出來了, 而且可視化出來的 loss map 符合預想效果,還很好看!

左圖:crossEntropyMap 右圖: edgeLossMap

最後一到工序 將概率矩陣prob變成Variable 測試一下反向傳播,我天真得以為 工作馬上就要被完成了

改成Variable(prob)後, loss.backward()一下, 啥?Error?Variable 竟然不能和 Tensor 運算 ! 不用記錄grad的Variable和 Tensor 有啥區別? 無語, 那全改為Variable 吧

嚓, Tensor和Variable部分api竟然不一樣 比如(`.type`). 行, 為了兼容性 函數都加上判斷是否為Variable, 並轉化為Variable.data

繼續吐槽一下 torch的類型系統 `Tensor/Variable * 8個數據類型` * `cuda/cpu` 共 `2*8*2=32` 類啊!! 而且 8個數據類型不支持類型自動轉換,所以 這32個類型的數據 都是兩兩互斥

不同類型間 操作前都得轉化, 可怕的是轉換操作還有許多像上文提到的那種坑!

改好代碼, 反向傳播通了 趕忙可視化一下 prob.grad

毛線!! 全是白的 分析一下 grad 中 99.97%的是nan, 人家 loss 都好人一個 你梯度怎麼就成了nan! 數學上不成立啊

可視化分析 loga(grad)的結果

遂開始了漫長的DEBUG之路, 終於 在不斷地拆開loss

分別 Backpropagation 後 將兇手精準定位了導致nan的loss

進一步分析 果然是pyTroch的BUG 整理好BUG後 就提交到了pytorch 的 GitHub上了

x.grad should be 0 but get NaN after x/0 · Issue #4132 · pytorch/pytorch

BUG如下

Reproduction BUG code

x = Variable(torch.FloatTensor([1.,1]), requires_grad=True)
div = Variable(torch.FloatTensor([0.,1]))

y = x/div # =&> y is [inf, 1]
mask = (div!=0) # =&> mask is [0, 1]

loss = y[mask]
loss.backward()
print(x.grad) # grad is [nan, 1], but expected [0, 1]

由於被`mask`阻擋, `x[0]`根本就沒在計算圖中 所以`x[0]`梯度應該為0 卻返回了`nan`

我還給出了BUG的解決方案:

Your code should"t generat any inf in forward, which often produce by torch.log(0) and x/[0, ]

That means 0 should be filtered before do torch.log(x) and x/div

為避免這個BUG 代碼變得更複雜了

variables

└─ /: 4
├── gtind: torch.Size([1, 2, 300, 400]) torch.cuda.FloatTensor
├── edge: torch.Size([1, 300, 400]) torch.cuda.ByteTensor
├── probnb: torch.Size([1, 8, 2, 300, 400]) torch.cuda.FloatTensor
└── gtdf: torch.Size([1, 8, 300, 400]) torch.cuda.FloatTensor
th = torch
tots = lambda x:x.data

code(before)

otherSideEdgeLossMap = -th.log(((probnb*gtind).sum(-3)*gtdf).sum(-3)/gtdf.sum(-3))
otherSideEdgeLossMap[~tots(edge)] = 0

code(after)

numerator = ((probnb*gtind).sum(-3)*gtdf).sum(-3)
numerator[tots(edge)] /= gtdf.sum(-3)[tots(edge)]
numerator[tots(edge)] = -th.log(numerator[tots(edge)])
otherSideEdgeLossMap = (numerator)
otherSideEdgeLossMap[~tots(edge)] = 0

最後 把代碼適配成多batch版本加上分割網路 順利跑通了 。 回想著一路下來 還好用的是動態圖的pyTorch, 調試靈活 可視化方便 若是靜態圖 恐怕會調試得吐血,曾經就為了提取一個mxnet的featrue 麻煩得要死。

不過 換成靜態圖的話 可能就不會顧著效率,用那麼多矩陣操作了,直接for循環定義網路結構 更簡單直接 。

所有loss 反向傳播後,prob 的 grad

寫於 2017.12

torch version : 0.3


誒。瀉藥。

1 torch和numpy的function名字不太一樣:

我反正numpy也用不太來。(據說會有torch.np,得等第二個改完)

2 要寫一個對於Variable和Tensor都通用的function時:一般的加減乘除還可以,最蛋疼就是新建tensor。

假設,我要輸出一個和輸入一樣類型的全零的tensor:

如果是tensor:

tensor.new(tensor.size()).zero_()

如果是Variable,得是:

Variable(tensor.new(tensor.size()).zero_())

(這個現在正在改,可能下個版本就有了吧。就是Variable Tensor完全一樣用法,Tensor只是一個 requires_grad為False的Variable)

3 cuda和cpu自動轉換

沒有一個context manager能夠說這下面默認都是cpu或者都是cuda。

麻煩的在於,如果要定義一個新的tensor,必須得input.data.new而不能torch.Tensor(xxxx)。

嗯。以上的問題gluon好像都沒有(刷個好感度)。(然而我還是用pytorch)

補充:

backward報錯沒有operator定位。(雖然我也不知道為什麼能forward不能backward,照理說不應該)

忘了zero_grad各種nan(血與淚的教訓)


Tensor和Variable的問題

為了對齊類型經常要Variable(tensor)或者variable.data……然而每個變數到底是Tensor還是Variable並不是很容易推斷,只能寫完跑一遍再慢慢改。

還有就是argmax.data.cpu().numpy().transpose().astype(int)[0],當然也可以寫成out.cpu().data.numpy().squeeze(axis=0).tolist(),並沒有什麼區別……

再補充一個:pytorch沒有提供Flatten()這個module,同樣也不支持shape的自動推斷。沒有Flatten這個作者沒有給出具體原因,論壇里討論過最後決定不加入這個Module。不支持shape自動推斷是因為Pytorch的分散式是一開始就要在多進程當中分配好Tensor,所以不能在第一遍forward的時候再推斷shape

總體來說Pytorch設計的非常優雅,大部分問題應該都是設計取捨。顯式的.cpu()和.cuda()能讓用戶意識到顯卡和內存之間的拷貝成本。Gluon在設計的時候也應該借鑒了很多


  1. 做CPU計算時,0.12版本速度遠高於最新的0.2,https://github.com/pytorch/pytorch/issues/2518
  2. 還有就是用set_num_threads設線程的時候要小心了,pytorch不一定聽你的,最好設環境變數,而且兩個最好都設:MKL_NUM_THREADS, OMP_NUM_THREADS pytorch not respecting torch.set_num_threads · Issue #975 · pytorch/pytorch


以下坑或 Bug 以 0.3 版本為準,其他人已提出且我贊同的答案不再贅述。

下一個版本得到修正的坑或 bug 會被歸檔,早先已歸檔的則會被刪除。所以要趁此填上項目里的被動坑。

DataLoader 有 ulimit 上限

其實我不清楚這算不算官方的鍋,好像有人批評 DataLoader 沒有釋放好 file descripter: DataLoader causing `RuntimeError: received 0 items of ancdata` · Issue #973 · pytorch/pytorch 某簡易解決方案也在其 issue 樓下給出了。

Advanced Indexing 可能不完善

我曾想取值 a[b, :1] 其中 a 是 Tensor, b 是 LongTensor, 結果報錯: TypeError: Performing basic indexing on a tensor and encountered an error indexing dim 0 with an object of type torch.LongTensor. The only supported types are integers, slices, numpy scalars, or if indexing with a torch.LongTensor or torch.ByteTensor only a single Tensor may be passed. 害得我改成 a[b, :][:, :1]

查了下,有很多類似的報告:Add documentation note about currently supported advanced indexing functionality · Issue #2423 · pytorch/pytorch feature 本身似乎也沒徹底完工:Feature Request: Advanced Indexing · Issue #1080 · pytorch/pytorch

Module.parameters() 返回生成器

於是沒法使用多次,官方拒絕修正,參見:`parameters()` should be a list, not an iterator · Issue #2954 · pytorch/pytorch

動態分配的內存很不確定

今天跑腳本,執行完 train 輪到執行 test 時,函數體幾乎一模一樣,用同一個模型,batchsize 也一樣,理論上由於 net.eval() 內存(y &> 0).sum() 之類的運算有可能溢出。內存佔用會更少,但會報內存不夠用的錯誤,不知道這函數跳轉之間到底發生了什麼。害得我只能設置 test 的 batchsize 為 device_id 的數量,同時也沒法用 cudnn.benchmarks 優化了。

PyTorch 沒有上傳到 PyPI

害得大家沒法一鍵 pip 安裝,只能跑去官網扒 URL 下。

然而真正的原因竟然是……rebuild pip wheels with manylinux · Issue #566 · pytorch/pytorch!

torch.cat 不支持直接把 list of int/float 轉變成 LongTensor/Tensor

這和 numpy.concatenate 不一樣。torch.stack 估計也不能。

nonzero 和 Numpy 的同名函數很不一樣

核心開發者之一也想改成後者了:nonzero doesn"t squeeze dimension · Issue #1834 · pytorch/pytorch

Tensor/Variable 的 cuda() 不是 in-place, Module 則反

這不一致的,好在目前也可以把後者賦值給自我一遍。

沒有官方 benchmarks 證實 "Tensors and Dynamic neural networks in Python with strong GPU acceleration." 的主張

這主張就是 PyTorch 官網的第一句話,於是我在論壇提出問題:Do you encourage user to use torch.Tensor instead of Numpy? 沒有官方答覆,於是存疑,用戶得自己親自寫 benchmarks 來解決。

大概由於用戶爆出 PyTorch 0.2 相對於 0.1.9 有嚴重的 CPU 性能下降 bug, 官方終於開始寫 pytorch/benchmark 了。

不支持 negative slice

對 Tensor 取 [::-1] 會報錯:slice step has to be greater than 0

不支持 Poly Scheluer

Poly Scheluer 是 Deeplab 提出的重要語義分割訓練法,我提 feature issue, 一個月過去了沒回應:Add the new lr_scheduler which called poly · Issue #2854 · pytorch/pytorch 真不知道 FAIR 在忙啥。

Tensor 能用的函數,Variable 不一定能用

參見:Implement remaining Variable functions · Issue #440 · pytorch/pytorch 在這個徹底施工完前,你拿不準哪個函數 Variable 能用,踩中坑就要轉成 data 用函數再轉成 Variable,是 cuda 變數時就更麻煩。

torchvision 用 PIL 而不是 scikit-image 圖像處理

於是就要額外花時間記憶 PIL 的 Image 類型以及其方法,沒法像 Numpy 用戶能直接無縫使用 scikit-image.

不完全或不一致的 torch.nn.functional 和 torch.nn.Loss

torch.nn.Softmax 只能處理 2D Tensor, torch.nn.functional.softmax 卻能處理 1D, 2D, 3D, 4D Tensor,後者的文檔也沒說它能處理什麼 Tensor, 從哪個維上 softmax. 還有好多 functional 都沒文檔。從我自己的測試來看,F.softmax 處理 2D 時 axis 為 1,處理 3D 時 axis 為 0,處理 4D 時 axis 為 1. F.cross_entroy 文檔指定了 Input 為 2D Tensor,但我傳 3D Tensor 則報錯:ValueError: Expected 2 or 4 dimensions (got 3).

目前同時實現了 NLLLoss, NLLLoss2d, CrossEntropyLoss, 唯獨缺了 CrossEntropyLoss2d. NLLLoss 接收的輸入得是 2D Tensor, NLLLoss2d 則接收 4D Tensor. 理論不紮實的新手容易被這名字繞暈。雖然官方似乎打算 deprecate NLLLoss2d, 使 NLLLoss2d 和 CrossEntropyLoss 能處理 2D, 4D 輸入,雖然半年過去了還沒弄好:Add CrossEntropyLoss2d by desimone · Pull Request #687 · pytorch/pytorch

參見:Add CrossEntropyLoss2d · Issue #551 · pytorch/pytorch

from_numpy() 不支持把 numpy 里的 int8 ndarray 轉換成 CharTensor

參見:Support int16 numpy conversions · Issue #891 · pytorch/pytorch

optimizer 裡面沒有 lr 作為 attribute

參見:Expose optimizer options as attributes when there"s a single param group · Issue #1736 · pytorch/pytorch

torch.Tensor 某軸的長度為零時,表現不怎麼符合直覺

既然 a 沒有 dimension, 那麼 c 應該也沒有才對;反之,即當 c 為刻意只保留非零值 dimension 的 Tensor, 說明值為零的 dimension 沒有意義,那麼 a 就無法被正常賦於只有零值 dimension 的 Tensor,即會拋異常。

既然 a 沒有 dimension, 那麼取 b[a] 應該返回沒有 dimension 的 Tensor.

不光無法取 b[a], 也不能直接對沒有 dimension 的 Tensor 進行運算以得到沒有 dimension 的 Tensor. 即害得我把某代碼寫成這樣子:

while tmp_order.numel() &> 0:
...清楚
indexes = (over &<= threshold).nonzero().squeeze() if indexes.numel() == 0: break else: tmp_order = tmp_order[indexes + 1]

如果能運算,代碼能更優雅:

while tmp_order.numel() &> 0:
...
indexes = (over &<= threshold).nonzero().squeeze() + 1 tmp_order = tmp_order[indexes]

後來果然在 PyTorch Issues 找到了類似的看法:

zero-dimensional numpy arrays should raise exception on from_numpy · Issue #2055 · pytorch/pytorch

unexpected behavior when resize shape include 0s. · Issue #2806 · pytorch/pytorch

官方也承認了 PyTorch 的 0 dimensional tensor 有很大的缺陷,甚至提出了可能要大改 API, 在高度貫徹 numpy-like API 的同時順便解決 0 dimensional tensor 問題,並且淘汰 Scalar: introduce torch.Scalar to represent scalars in autograd · Issue #1433 · pytorch/pytorch 不過估計要解決這問題得等很久了……


PyTorch 0.3 版本已解決的舊 bug:

(y &> 0).sum() 之類的運算有可能溢出。

因為 (y &>0) 一般返回 ByteTensor, 哪怕 y 原本是 LongTensor. 畢竟布爾值用 ByteTensor 就夠了,但這意味著 sum() 也返回 ByteTensor. 於是當 y 里大於 0 的元素多於 128 (或 256)時,就溢出了。坑死我了!

可以把 Tensor 傳進一些 Module 或 F

參見:Is is amazing that I can pass a Tensor to nn.AvgPool1d().forward() 返回值類型還神奇地變成 Variable 了。

TypeError: torch.sort received an invalid combination of arguments - got (torch.FloatTensor, descending=bool)

參見:TypeError: torch.sort received an invalid combination of arguments - got (torch.FloatTensor, descending=bool) · Issue #3497 · pytorch/pytorch

torchvision.datasets 的 transform, target_tramsform 不好用

不能同時 transform data 和 target, transform 順序也被定死。

好在 torchvision 改進了 transforms, 大概下一個版本會解決,參見:Proposal for extending transforms · Issue #230 · pytorch/vision


Variable和Tensor不能混合操作……


1.variable, tensor, numpy和cpu/gpu之間的轉換:這個在訓練rl的時候尤其煩。拿openai gym做個例子:

action = net(Variable(torch.from_numpy(obs[np.newaxis])).cuda()

action = action.data.cpu().numpy()[0]

obs, reward, done, _ = env.step(action)

所以前兩天寫了個gym env wrapper來自動轉換。

跟tensorflow相比,由於tf是直接定義好圖,輸出輸入直接是numpy,不需要再轉換。

2. contiguous:view只能用在contiguous的variable上。如果在view之前用了transpose,需要叫contiguous來返回一個contiguous copy。

先想這麼多,想到了再來答。不過總的來說pytorch用起來還是比tf舒服多了。


  • 不熟悉計算圖的運作原理可能埋雷

loss_total = 0
for ....
loss = loss_function(input,target)
loss_total += loss # 正確做法是 loss_total += (loss.data.cpu())
loss.backward()
print(loss_total/step)

這個一言難盡,慢慢學吧, 任何一個框架, 不學好計算圖都會踩到各種奇怪的坑

  • Python2 multiprocessing 殭屍進程

如果你使用Python 2.7的話,程序不正常退出(一般是Ctrl C強制退出時出現, 程序因為Exception退出沒問題),可能會導致顯存/內存未釋放.

問題描述和臨時解決方法參考論壇的帖子: GPU memory not returned

這個嚴格來說並不算PyTorch的問題,應該算是multiprocessing 庫的bug

先寫這麼多 慢慢補充

還有一些bug/坑, 大多是一些細枝末節, 看報錯信息,就能解決,第二次基本也就不會再犯了,

  • 對輸入類型要求,比如 nn.Embedding的輸入必須是LongTensor
  • 忘記把數據轉移到GPU,(模型轉移了數據沒轉移)

更多的bug可以去github上的issue裡面找 pytorch/pytorch , 不過基本不會遇到. 遇到了也容易調試,畢竟動態圖, pdb.set_trace() 全搞定.


  1. 部分tensor的操作並不支持Variable,比如torch.histc 和 torch.eig,如果你想用Variable作為這些操作的輸入的話,就只有自己手寫了。
  2. 單機多卡在運行時,有時會出現Nan的問題,完全相同的代碼在單卡上是正常的。我目前的解決方案是在出現Nan的層之前加個eps。。。
  3. Pytorch對於多機多卡的支持實在是有點不給力
  4. 單機多卡的情況下,會出現某張卡(默認第一張)負載遠大於其他幾張卡的情況。不過在一些第三方的parallel上面有修復[DataParallel](Data Parallel - Encoding master documentation)


pytorch 的dataloader 進程經常殺不幹凈,導致GPU內存沒有釋放。

還得使用 ps aux|grep lk|grep python|awk "{print $2}"|xargs kill 來進一步殺死進程,

才能徹底釋放GPU


曾經遇到的,lstm內存泄漏,訓練著訓練著就掛了,用了master branch的fix問題還是存在。。。


說個我的痛點(如果有大神能幫解決的話當然更好~):

Pytorch定義網路非常靈活,定義一個Resnet152所需要的代碼量比caffe要少的多得多。

但就是因為太靈活了,所以有的時候,也會遇到麻煩。

舉個例子,經常會有這種情況:假設已經預訓練了一個網路A,然後我們不想要A的FC層了,只想要它的pool5層,然後在後面再接一個其他的網路B,如圖所示:

如果在caffe中,這個問題十分好辦,因為caffe的每一層都定義在prototxt文件中,每一層都需要指定一個top blob和bottom blob,我們只要改寫相應層代碼就好了。

但這件事兒在Pytorch裡面有點麻煩。Pytorch是這樣定義網路的:首先在__init__函數中實例化所有有參數的層,在forward過程中,再調用它們。它的top-bottom關係反映在你的forward代碼裡面,定義方式類似:

def forward(self, x):
x = F.relu(F.maxpool(nn.conv2d(x)))
...

上述定義方式,雖然有助於我們定義動態的、複雜的網路,但是層與層的關係並不十分明確,需要我們仔細閱讀代碼,才能明白。

如果是一個Sequential model,這個事還有解決的辦法:

import torch
import torch.nn as nn
from torchvision import models

model = models.alexnet(pretrained=True)

# remove last fully-connected layer
new_classifier = nn.Sequential(*list(model.classifier.children())[:-1])
model.classifier = new_classifier

或者:

import torch
import torch.nn as nn
from torchvision import models

original_model = models.alexnet(pretrained=True)

class AlexNetConv4(nn.Module):
def __init__(self):
super(AlexNetConv4, self).__init__()
self.features = nn.Sequential(
# stop at conv4
*list(original_model.features.children())[:-3]
)
def forward(self, x):
x = self.features(x)
return x

model = AlexNetConv4()

但如果是非Sequential的模型,就有點兒複雜了,比如說下圖:

紅色是原有網路,一個類似resnet的結構,現在我們想把第二個單元的結果引出一條綠線,到一個新的網路,如果用上面代碼的方法,無疑會破壞原有的結構。

希望有大神能幫忙解答一下這個問題......


我覺得模型的保存就有坑。自定義class保存後,如果在新的文件里load,還需要重新定義class。

1/2更新:因為onnx需要用源碼編譯pytorch,所以重新安裝一遍。首先就是版本問題,cudnn/cuda版本如果不對,是無法編譯完成的。重點是,編譯完成後,你迫不及待的import torch想驗證是否安裝成功時,出現了importerror,更神奇的是,官方給出的解釋是,不要在pytorch根目錄下import…


在做inference時,千萬要記住對輸入的Variable設置volatile 為true.而不能設置requires_grad 為false.血的教訓。。。


1、Variable 和 Tensor 的操作不統一,有些函數可以在Tensor上做,但不可以在Variable上做

2、分散式訓練,官方給的ImageNet Tutorial 分散式訓練多GPU可以,但是多機多卡訓練會有問題

3、網路架構名字定義:卷積神經網路里每一層的名字是4.1.0.1,這誰看得懂是第幾層,是conv層還是relu層還是BN層...

然而我還是支持pytorch,同時支持mxnet。 逃...


一個最近一直被困擾的問題:由於pytorch的rnn實現默認直接拉的cudnn,導致如果想customize某些特殊rnn的話非常麻煩,顯存佔用明顯上升的同時速度慢個幾倍……(也包括了其他答案說到的for循環的問題)

還有之前遇到的:用兩張卡做data parallel訓練的時候loss的下降顯著慢於單卡訓練,至今沒明白我哪裡弄錯了,於是再沒用過多卡訓練…


舉個我沒解決的例子:

想跑Wikipedia這樣的數據集,發現顯存用著用著就out of memory了。

按道理說,假如我有Variable使用了沒釋放,那麼我的gpu memory應該是逐步增加的。但我目前的狀態是每隔半小時顯存使用突然上跳1G。

崩潰。找不到什麼太好的debug方法,如果是tensorflow,看一下tensorboard就能解決。

希望大佬們給點意見。

這個問題終於解決了,自己手動build from source pytorch 顯存就正常了!WQNMLGB

PS:

1.如果你搜一下Softmax這個函數,你就會發現吐槽無數。。。softmax比如輸入一維,是對第一維做softmax;輸入二維,那麼是對第二維做softmax;輸入三維是對第二維做。。。維數選擇像隨機數一樣。

2.算grad要register_hook

3.數據格式NCHW,NHWC隨機跳轉。使用MKL時候NCHW會更快,GPU時NHWC更快。 尼瑪給我隨便跳,你讓我用MKL還是GPU?

4.LSTM里的drop_out 參數在一層LSTM時是無用的, 但一般人就用一層。

5. for循環效率太差


pytorch訓練得到的結果總是會比caffe的差一點點??


本答案適用於 0.2.0 版。

  1. (極為嚴重,已在 master 版修復)用 np.newaxis (None) 給 Tensor/Variable 加維度的時候,和 numpy 不一致 Parity with NumPy newaxis placement in indexing by killeent · Pull Request #2779 · pytorch/pytorch。剛剛遇到這個坑,於是儘可能把 code 換成用 Tensor.view 改寫了。
  2. DataLoader 有時候會死掉 possible deadlock in dataloader · Issue #1355 · pytorch/pytorch。我是在使用 0.1.2 版本的時候遇到的這個問題。目前(在 master 版上)似乎還是沒有解決,大家眾說紛紜。


原來想在自己踩過的坑上點個贊... 結果看下來幾乎都踩了...

補充一個神一樣的inplace operation, tensor可以跑 variable不可以, forward可以跑 backward不可以

"""

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation

RuntimeError: in-place operations can be only used on variables that don"t share storage with any other variables, but detected that there are 2 objects sharing it

"""

不懂計算圖的原理真的很難寫對


推薦閱讀:

PyTorch提取中間層特徵?
如何評價 2017 年 12 月 5 日發布的 PyTorch 0.3.0?
如何評價MXNet發布的1.0版本?
PyTorch到底好用在哪裡?
2017年1月18日Facebook發行的PyTorch相比TensorFlow、MXNet有何優勢?

TAG:深度學習DeepLearning | PyTorch |