記PyTorch踩過的坑~(更新中)

像認真記錄生活一樣記錄Bug.

未經(jīng)允許,不得轉(zhuǎn)載,謝謝~~

1. 從autograd.Variable中取Tensor

  • BUG:
    RuntimeError: copy from Variable to torch.FloatTensor isn't implemented
    這個錯誤比較簡單,就不給完整報錯信息了。
  • 問題分析:
    錯誤語句:new_output[:,:,i,:,:]=temp2D_output
    這里的new_output是Tensor類型,temp2D_output是Variable類型。
    所以問題就變成了怎么樣從autograd.Variable中取到Tensor
  • 解決方法:
    上圖:

    這是autograd.Variable的結(jié)構(gòu)圖,忘記了可以看看這個
    PyTorch入門學習(二):Autogard之自動求梯度
    所以直接用Variable.data屬性即可。

2. Pytorch的計算類型不匹配問題

  • BUG:
    Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'weight'
  • 完整報錯信息:
Traceback (most recent call last):
  File "p3d_model.py", line 425, in <module>
    out=model(data)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "p3d_model.py", line 299, in forward
    x = self.maxpool_2(self.layer1(x))  #  Part Res2
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/container.py", line 67, in forward
    input = module(input)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "p3d_model.py", line 166, in forward
    out=self.ST_A(out)
  File "p3d_model.py", line 120, in ST_A
    x = self.bn2(x)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 325, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/modules/batchnorm.py", line 37, in forward
    self.training, self.momentum, self.eps)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/nn/functional.py", line 1013, in batch_norm
    return f(input, weight, bias)
RuntimeError: Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'weight'

從報錯信息來看應該是:需要的輸入?yún)?shù)類型為torch.FloatTensor,但實際上給定是torch.cuda.FloatTensor

  • 錯誤歷程
    可以看到出錯的語句為:self.bn2(x)
    一開始一直以為是自己傳入的x類型不符合要求,
    def conv2_fyq(self,x):
        deep=x.shape[2] 
        temp2D_output=self.conv2(x[:,:,0,:,:])
        new_output=torch.Tensor(temp2D_output.shape[0],temp2D_output.shape[1],deep,temp2D_output.shape[2],temp2D_output.shape[3])
        for i in range(deep):
            temp2D_input=x[:,:,i,:,:]
            temp2D_output=self.conv2(temp2D_input)
            print (temp2D_output.shape)      # (10, ,160,160)
            new_output[:,:,i,:,:]=temp2D_output.data
        print (new_output.shape)                  # (10, ,16,160,160)  
        # print (new_output)
        result=new_output.type(torch.FloatTensor)
        # print (result)
        result=Variable(result)
        return result

   x = self.conv2_fyq(x)
   x = self.bn2(x)                    #error

所以一直在修改函數(shù)conv2_fyq()函數(shù)的返回值,希望從torch.cuda.FloatTensor類型轉(zhuǎn)為torch.FloatTensor,試過很多方法,比如:

  1. result=result.cpu()
  2. 借用numpy array類型作為中轉(zhuǎn)
  3. 使用類型轉(zhuǎn)換 result=new_output.type(torch.FloatTensor)
  • 解決方法
    首先可以肯定的是由于張量類型不一致導致的;
    查了很多資料發(fā)現(xiàn)本質(zhì)是由于兩個張量不在同一個空間例如一個在cpu中,而另一個在gpu中因此會引發(fā)錯誤。
    print result發(fā)現(xiàn)為torch.FloatTensor類型,由此想到出現(xiàn)問題的是nn.BatchNorm3d中其他的參數(shù)類型為torch.cuda.FloatTensor.
    所以最后的解決方案:將result轉(zhuǎn)為torch.cuda.FloatTensor類型
    result=new_output.type(torch.cuda.FloatTensor)

  • 參考文獻
    torch.Tensor類型的構(gòu)建與相互轉(zhuǎn)換
    expected CPU tensor (got CUDA tensor)
    PyTorch遇到令人迷人的BUG與記錄

這一個小bug的解決也花了近2小時了~
雖然沒有直接在參考文獻中找到答案,但還是深受啟發(fā)~
自己解決一個木有現(xiàn)成答案的問題還是挺有意思的哈哈哈哈,心里話是開心都是騙人的,過程最折磨人。

3. 數(shù)據(jù)集label取值問題

  • BUG:
    THCudaCheck FAIL file=/opt/conda/conda-bld/pytorch_1512378360668/work/torch/lib/THC/generated/../generic/THCTensorMathPointwise.cu line=301 error=59 : device-side assert triggered
  • 完整報錯信息:
hl@hl-Precision-Tower-5810:~/Desktop/lovelyqian/CV_Learning/pseudo-3d-conv_S$ python P3D_train_fyq.py
hello
[1,1] loss: 4.593
[1,2] loss: 5.070
[1,3] loss: 4.854
[1,4] loss: 4.764
[1,5] loss: 4.807
[1,6] loss: 4.664
[1,7] loss: 4.797
[1,8] loss: 4.802
[1,9] loss: 4.808
[1,10] loss: 4.564
[1,11] loss: 4.509
[1,12] loss: 5.150
[1,13] loss: 4.323
[1,14] loss: 4.779
[1,15] loss: 5.295
THCudaCheck FAIL file=/opt/conda/conda-bld/pytorch_1512378360668/work/torch/lib/THC/generated/../generic/THCTensorMathPointwise.cu line=301 error=59 : device-side assert triggered
Traceback (most recent call last):
  File "P3D_train_fyq.py", line 43, in <module>
    loss.backward()
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/autograd/variable.py", line 167, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph, retain_variables)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/autograd/__init__.py", line 99, in backward
    variables, grad_variables, retain_graph)
RuntimeError: cuda runtime error (59) : device-side assert triggered at /opt/conda/conda-bld/pytorch_1512378360668/work/torch/lib/THC/generated/../generic/THCTensorMathPointwise.cu:301
  • 問題分析:
    這個問題的錯誤跟源代碼也沒有多大的關(guān)系,可以直接看到是在用pytorch的backward時候出現(xiàn)了報錯信息。
    算了,還是貼一下源代碼吧~~
 #dataset
    myUCF101=UCF101()
    classNames=myUCF101.get_className()
    # print (classNames)

    #model
    model = P3D199(pretrained=False,num_classes=101)
    model = model.cuda()
    # print (model)

     
    #loss and optimizer
    criterion=nn.CrossEntropyLoss()
    optimizer=optim.SGD(model.parameters(),lr=0.001)

    #train the network
    for epoch in range(2):         #loop over the dataset multiple times
        running_loss=0
        batch_num=myUCF101.set_mode('train')
        for batch_index in range(batch_num):
            # get the train data
            train_x,train_y=myUCF101[batch_index]   
            # warp them in Variable
            # train_x,train_y=Variable(train_x.cuda()),Variable(train_y.type(torch.LongTensor).cuda())
            train_x,train_y=Variable(train_x).cuda(),Variable(train_y.type(torch.LongTensor)).cuda()
            # set 0
            optimizer.zero_grad()
            # forward+backwar+optimize
            out=model(train_x)
            loss=criterion(out,train_y)
            loss.backward()
            optimizer.step()
            # print statistics
            running_loss+=loss.data[0]
            print ('[%d,%d] loss: %.3f' %(epoch+1,batch_index+1,running_loss))
            print >> f, ('[%d,%d] loss: %.3f' %(epoch+1,batch_index+1,running_loss))
            running_loss=0.0

從代碼來看就很簡單的邏輯,就是用常規(guī)的思路對網(wǎng)絡(luò)模型進行數(shù)據(jù)的輸入,梯度清零,計算輸出值,計算損失函數(shù),然后反向求梯度并更新。

這個問題沒有找到一模一樣的情況,但是在下文給出的參考文獻中找到了解決思路,即跟label有關(guān)。
也發(fā)現(xiàn)每一次出現(xiàn)錯誤信息的時間段不一樣,即能成功訓練的batch的數(shù)目不同,有的時候多,有的時候少。
所以想到把train_y給輸出來,多運行幾次之后發(fā)現(xiàn)每次出錯都是在label中出現(xiàn)了101的時候,再回過來考慮這個問題。
本項目用的是UCF101數(shù)據(jù)集,共有101種類型,所以在讀入label的時候自然就根據(jù)數(shù)據(jù)集制作者給出的label進行處理,取值為1-101. 但是PyTorch要求的范圍為:0-100

4.TypeError: only integer scalar arrays can be converted to a scalar index

  • BUG:
    TypeError: only integer scalar arrays can be converted to a scalar index
  • 情況說明:
    給出相關(guān)的源代碼
def test(dateset,model,model_state_path):
    myUCF101=dateset
    model.load_state_dict(torch.load(model_state_path))
    classNames=myUCF101.get_className()
    # test the network on the test data
    batch_num=myUCF101.set_mode('test')
    for batch_index in range(batch_num):
        batch_correct=0
        # get the test dat
        test_x,test_y_label=myUCF101[batch_index]
        # warp teat_x in Variable
        test_x=Variable(test_x.cuda())
        # get teh predicted output
        out=model(test_x)
        _,predicted_y=torch.max(out.data,1)
        predicted_label=classNames[predicted_y]
        batch_correct+= (predicted_label==test_y_label).sum()
        print('bactch: %d  accuracy is: %.2f' %(batch_index+1,batch_correct/float(len(test_y_label))))
        print >> f, ('bactch: %d  accuracy is: %.2f' %(batch_index+1,batch_correct/float(len(test_y_label))))
    print ('Test Finished')

主要看這兩行:

  out=model(test_x)
  _,predicted_y=torch.max(out.data,1)
 predicted_label=classNames[predicted_y]

out是我取到的分類值; predicted是最有可能的label集合;classNames是具體的label。

  • 錯誤分析:

1. 首先把predicted_y由cuda的longTensor改成numpy格式的。

predicted_y=predicted_y.cpu().numpy()
  1. 然后還是不行,就把predicted_y打印出來,發(fā)現(xiàn)是np.ndarray形式的,猜測可能需要轉(zhuǎn)換為np.array()。
    例如:
predicted_y=np.array(predicted_y,dtype=np.uint8)

這樣依然沒有解決問題,且網(wǎng)上提供的很多解決方案例如predicted_y=predicted_y.flatten()將多維數(shù)組轉(zhuǎn)為展開成一維數(shù)組都行不通。

3. 既然提示需要直接使用np.array,所以我就定義了 a=np.arange(8),來測試classNames[a],發(fā)現(xiàn)還是一樣的錯誤。到這里就覺得已經(jīng)不是下標的問題了,所以才想到是不是classNames的問題。
然后才想到classNames不是array,而是list。所以我就將classNames做了一個從array到list的類型轉(zhuǎn)換。

 classNames=np.array(classNames)

到這里就就決問題了。

  • 解決方法 :
  # cuda.longTensor to numpy.array
  predicted_y=predicted_y.cpu().numpy()
  # ndarray to array
  predicted_y=np.array(predicted_y,dtype=np.uint8)
  # list to array
  classNames=np.array(classNames)

總結(jié)來說,TypeError: only integer scalar arrays can be converted to a scalar index這個問題可以從下標和數(shù)組這兩個對象來看,都需要是np.array類型的。

5.DataLoader處理數(shù)據(jù)集時候的數(shù)據(jù)問題

  • BUG:
    RuntimeError: invalid argument 2: cannot unsqueeze empty tensor at /opt/conda/conda-bld/pytorch_1512378360668/work/torch/lib/TH/generic/THTensor.c:601
  • 完整報錯信息:
Traceback (most recent call last):
  File "UCF101_pytorch_fyq.py", line 182, in <module>
    for i_batch,sample_batched in enumerate(dataloader):
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/utils/data/dataloader.py", line 210, in __next__
    return self._process_next_batch(batch)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/utils/data/dataloader.py", line 230, in _process_next_batch
    raise batch.exc_type(batch.exc_msg)
RuntimeError: Traceback (most recent call last):
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/utils/data/dataloader.py", line 42, in _worker_loop
    samples = collate_fn([dataset[i] for i in batch_indices])
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/utils/data/dataloader.py", line 116, in default_collate
    return {key: default_collate([d[key] for d in batch]) for key in batch[0]}
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/utils/data/dataloader.py", line 116, in <dictcomp>
    return {key: default_collate([d[key] for d in batch]) for key in batch[0]}
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/utils/data/dataloader.py", line 96, in default_collate
    return torch.stack(batch, 0, out=out)
  File "/home/hl/anaconda2/lib/python2.7/site-packages/torch/functional.py", line 62, in stack
    inputs = [t.unsqueeze(dim) for t in sequence]
RuntimeError: invalid argument 2: cannot unsqueeze empty tensor at /opt/conda/conda-bld/pytorch_1512378360668/work/torch/lib/TH/generic/THTensor.c:601
  • 錯誤分析:
    這個問題大概可以看出來是DataLoader的問題,但是使用框架的時候具體到哪個函數(shù),哪行代碼就會比較麻煩??磮箦e信息的最后一行應該可以知道是空的Tensor引起的。

我們不用DataLoader的情況下,輸出數(shù)據(jù)樣本:

print (len(myUCF101))
for i in range (5):
    sample=myUCF101[i]
    print(sample['video_x'].size(),sample['video_label'])

得到如下所示:


可以看到與video_label會有關(guān)系。

  • 解決方法:
    超級感謝這篇資料的引導了:# Cannot Unsqueeze Empty Tensor

    確實是由于video_label是標量引起的,最后做了改動,具體如下所說:
    錯誤
修改后

----------20180806更新----------

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

  • BUG:RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation
  • 完整報錯信息:

/home/fuyuqian/anaconda3/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/transforms.py:188: UserWarning: The use of the transforms.Scale transform is deprecated, please use transforms.Resize instead.
Traceback (most recent call last):
  File "/home/fuyuqian/Projects/Temporal_Deformable_P3D/network_train.py", line 88, in <module>
    myTrainClassifier.train_network()
  File "/home/fuyuqian/Projects/Temporal_Deformable_P3D/network_train.py", line 59, in train_network
    loss.backward()
  File "/home/fuyuqian/anaconda3/lib/python3.6/site-packages/torch/tensor.py", line 93, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/home/fuyuqian/anaconda3/lib/python3.6/site-packages/torch/autograd/__init__.py", line 89, in backward
    allow_unreachable=True)  # allow_unreachable flag
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation
  • 錯誤分析:由于pytorch升級到pytorch0.4之后,與之前pytorch0.3的用法發(fā)生來了一些變化,比如最重要的在pytorch0.4中將Tensor與Variance都組合成了同一個東西,pytorch0.4不再支持inplace操作。
  • 解決方法:基本網(wǎng)上我能看到的所有資料,可執(zhí)行的方案主要有以下幾點:
  • 解決方案1:把所有的inplace=True改成inplace=False
  • 解決方案2:將out+=residual這樣所有的+=操作,改成out=out+residual
  • 解決方案3: 將pytorch版本回退到0.3,或者添加一個pytorch0.3的conda環(huán)境。

此類問題的一點總結(jié):以上的方案1與方案2其實都是在解決pytorch0.4不能處理inplace操作的問題。但是其實都不全。

舉個簡單的例子來理解一下inplace=True與inplace=False,就像所有的博客里給出的+=這個操作。x+=1是在x的基礎(chǔ)上直接做加法操作的,這個就屬于在原來的x上做擴展,是inplace=True的情況。而x=x+1就是先做加法,然后重新賦值,就是inplace=False。

但是我們要注意到+=只是inplace的一種操作,并不是把所有的+=替換掉就可以解決問題的。在這篇博客pytorch 學習筆記(二十二):關(guān)于 inplace operation中給出了完整的說明,非常建議看看。

總結(jié)一下:如果你的程序比較簡短,情況比較簡單,那么就直接改里面的+=這樣的inplace操作。另外在修改的時候可以用variance.backward()來試試這個variance之前的代碼是不是都已經(jīng)正確了。 如果代碼量比較大,那還是建議用conda再創(chuàng)建一個環(huán)境,用來安裝pytorch0.3,簡單省事。

  1. 創(chuàng)建一個名為pytoch0.3的conda環(huán)境:conda create -n pytorch0.3 python=3.6;
  2. 激活pytorch0.3環(huán)境:source activate pytorch0.3,這時中斷提示符前面會多一個pytorch0.3標記;
  3. 要關(guān)閉pytorch0.3環(huán)境,就用: source deactivate;
  4. 在里面用conda安裝0.3版本的pytorch:先在官網(wǎng)下載對應的版本torch-0.3.1-cp36-cp36m-linux_x86_64.whl,進入目錄用pip install torch-0.3.1-cp36-cp36m-linux_x86_64.whl命令安裝pytorch,然后再用pip install torchvision安裝torchvision。

7. 關(guān)于網(wǎng)絡(luò)測試時候顯卡溢出的問題

  • 問題描述:我寫了一個網(wǎng)絡(luò),用同樣的BATCH_SIZE對模型進行訓練沒有問題,但是進行測試就會溢出。
  • 問題思考: 在數(shù)據(jù)加載以及網(wǎng)絡(luò)模型一樣的前提下,分類任務(wù)的test只需要計算前向傳播得到精度即可,都不需要梯度返回的過程,應該網(wǎng)絡(luò)參數(shù)的大小比訓練的時候要小才對。
  • 問題解決: 在測試時候加上:with torch.no_grad():語句即可。
  • 原因分析:推斷是測試的時候沒有對網(wǎng)絡(luò)參數(shù)的梯度進行優(yōu)化。(未驗證)

8. 關(guān)于同一個模型在測試時得到的結(jié)果不同--model.train()與model.eval()

  • 問題描述:同樣的一個網(wǎng)絡(luò)結(jié)構(gòu),在多次測試的時候發(fā)現(xiàn)得到的結(jié)果會不一樣。
  • 問題思考: 一樣的網(wǎng)絡(luò)結(jié)構(gòu),一樣的數(shù)據(jù),排除數(shù)據(jù)加載中存在隨機裁剪這樣的問題之后就覺得這種情況一定是不合理的。
  • 問題解決:如果你的網(wǎng)絡(luò)中有BN層或者dropout層,那么就需要在測試的實時候加上語句model.eval(),默認情況下是train()模式的,這樣就不會出現(xiàn)上述的問題;
  • 原因分析: BN在訓練時是根據(jù)mini_batch中的樣本來得到均值和方差的,但是在test的時候我們需要的是對每個樣本進行預測,所以取固定的均值和方差就可以了。而dropout則只是train的時候為了防止過擬合而用的,test的時候并不需要這一層。

----------20181117更新----------

9 關(guān)于cuda out of momery問題

  • 問題描述:當需要用同一個網(wǎng)絡(luò)對很多的輸入進行計算輸出的時候,可能會出現(xiàn)所有的變量都留在gpu中導致顯卡溢出。
  • 問題解決:將計算完之后的結(jié)果移到內(nèi)存中,例如我想到的是網(wǎng)絡(luò)輸出的某一個feature 值,那么就用feature.cpu().detach()的方式將它移到內(nèi)存中保存。

----------20190215更新----------

10. 關(guān)于多線程出現(xiàn)錯誤問題

  • 問題描述
    當我用pytorch自帶的dataloader多線程讀取數(shù)據(jù)時,如果對讀出的數(shù)據(jù)使用append()方法,會出現(xiàn)內(nèi)存錯誤,程序異常終止的問題;
  • 相關(guān)代碼
    trainloader_single = DataLoader(trainset,batch_size=1,shuffle=False,num_workers=NUM_WORKERS)   

    image_features=[]
    image_labels=[]


    for i, data in enumerate(trainloader_single):
        # get the inputs
        inputs, labels = data
        inputs, labels = inputs.numpy(), labels.numpy()
        img_feature = inputs.reshape(inputs.shape[1:])
        img_label = labels[0]
        print(i,img_feature.shape, img_label)

        image_features.append(img_feature)
        image_labels.append(img_label)

只要出現(xiàn)最底下的這兩行append語句,就會出錯。

  • 解決方法:
    最簡單的方法就是直接改成單線程,但是我一直以為是設(shè)置num_works=1即可。
    事實是需要將它設(shè)置為0:num_works=0來達到disable multi-processing的效果。

----------20190225更新----------

11. 關(guān)于多次網(wǎng)絡(luò)交替求導的問題

  • 問題描述:網(wǎng)絡(luò)中存在多個sub-network,有2個甚至2個以上的loss需要分別對網(wǎng)絡(luò)參數(shù)進行更新。(不是loss = loss1 + loss2這種情況),而是兩個需要分別執(zhí)行loss1.backward() loss2.backward().
  • 問題所在:兩個loss可能會有共同的部分,所以在執(zhí)行第一次loss1.backward()完成之后,Pytorch會自動釋放保存著的計算圖,所以執(zhí)行第二次loss2.backward()的時候就會出現(xiàn)計算圖丟失的情況;
  • 錯誤信息:
RuntimeError: Trying to backward through the graph second time, but the buffers have already been freed. Please specify retain_variables=True when calling backward for the first time.
  • 解決方法:
  1. 執(zhí)行loss1.backward(retain_graph=True)保留計算圖;
  2. 如果你不希望兩次的梯度疊加,那么執(zhí)行一次net.zero_grad();
  3. 執(zhí)行loss2.backward()
  4. 根據(jù)自己的情況對網(wǎng)絡(luò)分別定義optimizer,進行step()梯度更新;

12. TypeError: unhashable type: 'numpy.ndarray'

  • 問題描述:在將pytorch的longTensor轉(zhuǎn)為numpy,并用于dict的key的時候,會出現(xiàn)這樣的錯誤。其實程序輸出已經(jīng)是int了,但是還是會被認為是ndarray。
  • 問題解決: 在原來的基礎(chǔ)上加上.item()
# classId = support_y[i].long().cpu().detach().numpy()
classId = support_y[i].long().cpu().detach().numpy().item()

13. from torch._C import * ImportError: numpy.core.multiarray failed to import

  • 問題描述: 在新的虛擬環(huán)境Python=2.7中重新安裝的pytorch,導入的時候會有問題。
  • 錯誤信息:
>>> import torch
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/fuyuqian/anaconda3/envs/cmr/lib/python2.7/site-packages/torch/__init__.py", line 84, in <module>
    from torch._C import *
ImportError: numpy.core.multiarray failed to import
  • 問題解決:
  1. 執(zhí)行多次pip uninstall numpy直到系統(tǒng)提示沒有安裝numpy;
  2. 重新用pip install numpy -U命令安裝numpy;
  3. 然后就可以正常導入torch了。

--------20191031更新------------

14. 使用torch.view()時出現(xiàn) view size is not compatible with input tensor's size and stride 的問題

  • 問題描述: 需要將一個shape為[64, 4,2,2]的Tensor變換為[64,-1], 但是執(zhí)行過程一直報錯;
  • 報錯信息:
 aim_region_reshape=aim_region.view(feature_dim,-1)
RuntimeError: invalid argument 2: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view(). at /pytorch/aten/src/THC/generic/THCTensor.cpp:226
  • 解決方法:
    按照提示信息在view()的前面先加.contiguous()
  • 原因分析:
    找到一個比較好的解釋是view()的原理是需要Tensor中的元素地址是連續(xù)的,但是有可能出現(xiàn)Tensor不連續(xù)的情況,所以先用.contiguous()函數(shù)將其在內(nèi)存中變成連續(xù)分布。

2020107: 踩過的坑又踩了一次 (▼ヘ▼#)


--------20200413更新---------

15. 關(guān)于torch.sqrt()在網(wǎng)絡(luò)訓練中出現(xiàn)NAN的問題

問題描述:

我寫了一個loss function,其中有一個步需要兩點之間的歐式距離,然后我用了torch.sqrt()來開根號。

核心code: loss = torch.sqrt(a)

在網(wǎng)絡(luò)訓練初期是沒有什么問題的loss也都正常下降,但是訓練到一半會出現(xiàn)NAN。

問題分析:
首先我把相關(guān)的所有l(wèi)oss print 出來看,本來以為是由于loss 計算本身出現(xiàn)的(比如分母為0)。

可以看到上一輪迭代都是正常的,然后首先是在網(wǎng)絡(luò)的輸出上導致了NAN,進而導致各項loss都是NAN。

這就基本可以確定是網(wǎng)絡(luò)更新的問題,梯度過大。

然后排查后發(fā)現(xiàn)torch.sqrt()函數(shù)當輸入的值為0的時候,得到的梯度是NAN。

問題解決:
為了防止這種問題出現(xiàn),就加一個很小的值,修改code如下:

e = 1e-6
torch.sqrt(a  + e)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容