您好,登錄后才能下訂單哦!
這篇“Pytorch:dtype不一致問(wèn)題如何解決”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“Pytorch:dtype不一致問(wèn)題如何解決”文章吧。
RuntimeError: Expected object of scalar type Double but got scalar type Float for argument #3 ‘mat2’ in call to _th_addmm_out
在訓(xùn)練網(wǎng)絡(luò)的過(guò)程中由于類型的沖突導(dǎo)致這種錯(cuò)誤,主要是模型內(nèi)部參數(shù)和輸入類型不一致所導(dǎo)致的。主要有兩個(gè)部分需要注意到:1.自己定義的變量要設(shè)置為一種數(shù)據(jù)類型;2.網(wǎng)絡(luò)內(nèi)部的變量類型也要統(tǒng)一。
統(tǒng)一聲明變量的類型。
# 將接下來(lái)創(chuàng)建的變量類型均為Double torch.set_default_tensor_type(torch.DoubleTensor)
or
#將接下來(lái)創(chuàng)建的變量類型均為Float torch.set_default_tensor_type(torch.FloatTensor)
一定要注意要在變量創(chuàng)建之間聲明類型。
在訓(xùn)練過(guò)程中加入一下兩點(diǎn)即可:
# For your model net = net.double() # For your data net(input_x.double)
1. 用conda安裝pytorch-gpu時(shí)
用這個(gè)命令就夠了,網(wǎng)上其他人說(shuō)的都不好使
conda install pytorch cuda92
注意得是清華源的
2. 比較兩個(gè)行向量或者列向量
以期求得布爾數(shù)組時(shí),必須要保證兩邊的數(shù)據(jù)類型一樣,并且返回的布爾數(shù)組類型和比較的兩個(gè)向量結(jié)構(gòu)保持一致。另外,所有torch.返回的東西,如果要取得里面的值,必須要加.item()
# !user/bin/python # -*- coding: UTF-8 -*- import torch a = torch.arange(16).view(4, 4) b = torch.argmax(a, dim = 1) print([round(x.item(), 5) for x in b]) z = torch.tensor([3, 1, 2, 5], dtype = torch.long) # 類型必須保持一致 z = z.view(-1, 1) b = b.view(-1, 1) print(b) print(z) print(b == z) # tensor([[ True], # [False], # [False], # [False]]) print(torch.sum(b == z)) # tensor(1)
3. numpy轉(zhuǎn)tensor,其中,ndarray必須是等長(zhǎng)的
x = np.array([[1, 2, 3], [4, 5, 6]]) # 正確 # x = np.array([[1, 2, 3], [4, 5]]) # 錯(cuò)誤 print(torch.from_numpy(x))
4. unsqueeze (不改變?cè)袛?shù)據(jù))
import torch import numpy as np x = torch.tensor([[1, 2], [3, 4]]) print(x) # tensor([[1, 2], # [3, 4]]) # 在第0維的地方插入一維 print(x.unsqueeze(0)) # tensor([[[1, 2], # [3, 4]]]) print(x.unsqueeze(0).shape) # torch.Size([1, 2, 2]) print(x.unsqueeze(1)) # tensor([[[1, 2]], # [[3, 4]]]) print(x.unsqueeze(1).shape) # torch.Size([2, 1, 2])
5. nn.embedding
# !user/bin/python # -*- coding: UTF-8 -*- import torch import torch.nn as nn import torch.nn.functional as F # 看看torch中的torch.nn.embedding # embedding接收兩個(gè)參數(shù) # 第一個(gè)是num_embeddings,它表示詞庫(kù)的大小,則所有詞的下標(biāo)從0 ~ num_embeddings-1 # 第二個(gè)是embedding_dim,表示詞嵌入維度 # 詞嵌入層有了上面這兩個(gè)必須有的參數(shù),就形成了類,這個(gè)類可以有輸入和輸出 # 輸入的數(shù)據(jù)結(jié)構(gòu)不限,但是數(shù)據(jù)結(jié)構(gòu)里面每個(gè)單元的元素必須指的是下標(biāo),即要對(duì)應(yīng)0 ~ num_embeddings-1 # 輸出的數(shù)據(jù)結(jié)構(gòu)和輸入一樣,只不過(guò)將下標(biāo)換成對(duì)應(yīng)的詞嵌入 # 最開(kāi)始的時(shí)候詞嵌入的矩陣是隨機(jī)初始化的,但是作為嵌入層,會(huì)不斷的學(xué)習(xí)參數(shù),所以最后訓(xùn)練完成的參數(shù)一定是學(xué)習(xí)完成的 # embedding層還可以接受一個(gè)可選參數(shù)padding_idx,這個(gè)參數(shù)指定的維度,但凡輸入的時(shí)候有這個(gè)維度,輸出一律填0 # 下面來(lái)看一下吧 embedding = nn.Embedding(10, 3) inputs = torch.tensor([[1, 2, 4, 5], [4, 3, 2, 9]]) print(embedding(inputs)) # tensor([[[ 0.3721, 0.3502, 0.8029], # [-0.2410, 0.0723, -0.6451], # [-0.4488, 1.4382, 0.1060], # [-0.1430, -0.8969, 0.7086]], # # [[-0.4488, 1.4382, 0.1060], # [ 1.3503, -0.0711, 1.5412], # [-0.2410, 0.0723, -0.6451], # [-0.3360, -0.7692, 2.2596]]], grad_fn=<EmbeddingBackward>)
6. eq
# !user/bin/python # -*- coding: UTF-8 -*- # eq import torch a = torch.tensor([1, 2, 2, 3]) b = torch.tensor((1, 3, 2, 3)) print(a.eq(b)) # tensor([ True, False, True, True]) print(a.eq(0)) # tensor([False, False, False, False]) print(a.eq(2)) # tensor([False, True, True, False])
7. expand
# expand # expand不修改原有值 # 只能擴(kuò)展維度是1的那個(gè)維度 # 另外,expand還能增加新的維度,不過(guò)新的維度必須在已知維度之前比如從2 * 3 到 5 * 2 * 3 a = torch.tensor([[1, 2, 3]]) print(a.size()) # torch.Size([1, 3]),第一維是1,所以只能擴(kuò)展第一維 print(a.expand(3, 3)) # tensor([[1, 2, 3], # [1, 2, 3], # [1, 2, 3]]) print(a) # tensor([[1, 2, 3]]) a = torch.tensor([[1], [2], [3]]) print(a.size()) # torch.Size([3, 1]),第二維是1,只能擴(kuò)展第二維 print(a.expand(-1, 4)) # 第一維用-1代表第一維不變,還是3 # tensor([[1, 1, 1, 1], # [2, 2, 2, 2], # [3, 3, 3, 3]]) a = torch.randn(2, 1, 1, 4) # 同理,只能擴(kuò)展第2和第3維 print(a.expand(-1, 2, 3, -1)) a = torch.tensor([1, 2, 3]) print(a.size()) # torch.Size([3]) print(a.expand(2, 3)) # tensor([[1, 2, 3], # [1, 2, 3]]) # print(a.expand(3, 2)) 會(huì)報(bào)錯(cuò),因?yàn)樾戮S度跑到原有維度之后了 print(a.expand(3, 2, -1)) a = torch.rand(2, 3) print(a.expand(5, 2, 3)) # 正確
8. repeat
# repeat # repeat不改變?cè)兄? # repeat傳入的參數(shù)的個(gè)數(shù)等于原有值的維度個(gè)數(shù),表示將對(duì)應(yīng)維度的內(nèi)容重復(fù)多少次 a = torch.tensor([1, 2, 3]) # size = [3] print(a.repeat(2)) # 將第一個(gè)維度的重復(fù)兩次 tensor([1, 2, 3, 1, 2, 3]) print(a) # tensor([1, 2, 3]) a = torch.tensor([[1, 2, 3], [4, 5, 6]]) # 2 * 3 print(a.repeat(2, 3)) # 第一維重復(fù)兩次,第二維重復(fù)三次,就變成了4 * 9 # tensor([[1, 2, 3, 1, 2, 3, 1, 2, 3], # [4, 5, 6, 4, 5, 6, 4, 5, 6], # [1, 2, 3, 1, 2, 3, 1, 2, 3], # [4, 5, 6, 4, 5, 6, 4, 5, 6]])
9. torch.stack 這個(gè)函數(shù)接受一個(gè)由張量組成的元組或者列表
與cat的區(qū)別是,stack會(huì)先增加一維,然后再進(jìn)行拼接
10. 對(duì)于一維張量a,維度為m,a[None, :]的shape為1×m,a[:, None]的shape為m×1
11. 兩個(gè)不同維度的矩陣比較,利用了廣播機(jī)制
12. torch.nn.CrossEntropyLoss(),這個(gè)類比較復(fù)雜,我們慢點(diǎn)說(shuō)。
首先,這是一個(gè)類,定義如下:
class CrossEntropyLoss(_WeightedLoss): def __init__(self, weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean'): super(CrossEntropyLoss, self).__init__(weight, size_average, reduce, reduction) self.ignore_index = ignore_index def forward(self, input, target): return F.cross_entropy(input, target, weight=self.weight, ignore_index=self.ignore_index, reduction=self.reduction)
可以看到這個(gè)類非常簡(jiǎn)單。在構(gòu)造函數(shù)中,我們重點(diǎn)關(guān)注weight和reduction
weight
:表示每個(gè)類的權(quán)重,這個(gè)在樣本不平衡分類問(wèn)題中很有用,它應(yīng)該是一個(gè)長(zhǎng)度為C的一維張量,C為類別數(shù)。
reduction
:用于控制最終的輸出結(jié)果,默認(rèn)為mean,如果是mean,返回的是一個(gè)數(shù),即shape為torch.tensor([]) ,如果是none,則返回的情況有兩種,一種是(N,),一種是(N, d_1, ..., d_K),至于是哪一種,得看我們輸入到forward函數(shù)中的input和target是哪種形狀的。
可以看到,forward函數(shù)直接調(diào)用F.cross_entropy這個(gè)函數(shù),這個(gè)函數(shù)中的weight和reduction我們已經(jīng)講過(guò),不再贅述。我們重點(diǎn)將input和target應(yīng)該是什么形狀的。
這里分兩種情況。
第一種,input是二維,即(N, C),N代表batch_size,C代表類別,即對(duì)于每一個(gè)batch,都有一個(gè)一維長(zhǎng)度為C的向量,通常這里的C表示的是對(duì)應(yīng)類別的得分。target表示標(biāo)簽,它應(yīng)該是(N,),表示每一個(gè)batch的正確標(biāo)簽是什么,內(nèi)容應(yīng)該在0~C-1之中。如果reduction取默認(rèn)值mean,則返回的是一個(gè)數(shù),這個(gè)數(shù)是每個(gè)batch的損失的平均。如果是none,則返回的是(N,),即代表每一個(gè)batch的損失,沒(méi)有進(jìn)行平均。
第二種,input的維度是(N, C, d_1, ... d_K),這里K>=1。N表示batch_size,C表示類別數(shù),d_1...d_K 可以看做一個(gè)整體,表示在某個(gè)批次,某個(gè)類別上,損失并不是一個(gè)數(shù)字,而是一個(gè)張量。按這種方式理解的話,第一種就可以理解為,在某個(gè)批次,某個(gè)類別上,損失是一個(gè)數(shù),而第二種不是一個(gè)數(shù),是一個(gè)張量,這個(gè)張量的形狀是(d_1, ..., d_K),這個(gè)張量的每一個(gè)位置都代表對(duì)應(yīng)位置的損失。拿NLP中seq2seq的損失函數(shù)為例,decoder的輸出應(yīng)是(batch_size, seq_len, vocab_size),label為(batch_size, seq_len),那么這里我們顯然應(yīng)該用第二種,因?yàn)樵谀硞€(gè)批次,某個(gè)類別上,我們的損失函數(shù)并不單單是一個(gè)數(shù),而是一個(gè)(seq_len,)的張量,對(duì)于長(zhǎng)度為seq_len的每個(gè)單詞,每個(gè)位置都有一個(gè)損失,所以我們要用第二種。所以這里,我們需要將input的后兩維置換,即transpose(0, 1),使其變成(batch_size, vocab_size, seq_len)。對(duì)于第二種,target,也就是label的維度應(yīng)該是(N, d1, ..., d_K),表示對(duì)于每個(gè)批次,這個(gè)“損失張量”(這個(gè)名字我自己起的)的每個(gè)位置對(duì)應(yīng)的標(biāo)簽。因此,對(duì)于seq2seq來(lái)說(shuō),label的維度應(yīng)該是(N, seq_len)。對(duì)于第二種情況,如果reduction是mean,輸出還是一個(gè)數(shù),這個(gè)數(shù)表示所有批次,“損失張量”所有位置的損失的平均值。如果是none,輸出為(N, d1, ...d_K),表示每一個(gè)批次,“損失張量”每一個(gè)位置的損失。
下面的例子代表第一種情況。
13. torch中mask作為torch的下標(biāo),可以不必和torch一樣的shape
當(dāng)然,也可以直接用下表來(lái)進(jìn)行賦值
14. repeat in torch & numpy is very different.
look at the pic above, repeat in torch does not have a argument 'axis =', and it regard the whole tensor as one which can not be seperated.
Next, we will talk about repeat function in numpy. We would like to divide it into two part. The former is that the array is 1-D and the other is N-D
part 1:
if array is one-dimensional, there is no need to specify the 'axis' argument. It will seperate each number, and repeat them respectively.
part 2:
Here the shape of array c is (2, 2), so we can specify the 'axis'. The condition will be as follows:
(1) If axis is not specified, it will firstly flatten the array and continue repeating operation which is like part 1.
(2) If axis = 0, it will repeat along the first dimension.
(3) If axis = 1, it will repeat along the second dimension.
15. torch的多維張量a,如果a[-1],默認(rèn)代表第一axis的最后一維,即等價(jià)于a[-1,:,:,...,:]
16. torch.cat(XXX, dim = ?) 其中XXX可以是list,不一定非要tensor
17. contiguous()
亦即,對(duì)tensor進(jìn)行transpose時(shí),其實(shí)是淺拷貝,如果要深拷貝,就要在后面補(bǔ)上一個(gè)contiguous()
18. net是網(wǎng)絡(luò)模型的一個(gè)object,調(diào)用zero_grad函數(shù),表示將網(wǎng)絡(luò)內(nèi)部所有參數(shù)的梯度置0
19. torch.utils.data中的DataLoader和TensorDataset
先用TensorDataset對(duì)打包的文件進(jìn)行校對(duì),在DataLoader中會(huì)指定batch_size,假設(shè)原本data和label各N個(gè),那么DataLoader會(huì)將其打亂后,每batch_size為一組,共N/batch_size個(gè)。
假設(shè)DataLoader返回的是iter,對(duì)iter進(jìn)行for遍歷的時(shí)候,假設(shè)每一輪取樣為batch,則batch的長(zhǎng)度是2,batch為一個(gè)list,這個(gè)list里面有兩個(gè)元素,一個(gè)是data,一個(gè)是label,data和label的第一維大小都是batch_size。
以上就是關(guān)于“Pytorch:dtype不一致問(wèn)題如何解決”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。