Pytorch的基本使用

本篇內(nèi)容參考官方文檔自己總結(jié)而來僅供自學(xué)自查霉撵,詳細(xì)需求請查閱官方文檔磺浙。

數(shù)據(jù)類型

  • 張量(Tnsor

什么是張量?簡單來說就可以看成是向量喊巍。一階張量屠缭,就是一維向量箍鼓,如此如此崭参。

1. torch自己的方法構(gòu)造的數(shù)據(jù)都是默認(rèn)為Tensor的張量,比如:
  • 定值構(gòu)造
    定值構(gòu)造方法還有很多款咖,如下:
import torch
torch.Tensor(list/ndarray)#---->將列表轉(zhuǎn)為何暮,數(shù)組轉(zhuǎn)為tensor
torch.eye(3)#---->生成3行3列的值為1的對角矩陣
torch.linspace(start, end, steps=100, out=None)#---->等差數(shù)列矩陣
torch.logspace(start, end, steps=100, out=None)#---->對數(shù)等差數(shù)列矩陣

torch.zeros()、ones()铐殃、等等方法和numpy類似海洼,不一一舉例。

  • 隨機(jī)構(gòu)造
    這類構(gòu)造方法也不少富腊,如下:
import torch
torch.rand(2,2)# ----->生成2X2的矩陣坏逢,數(shù)值再0-1之間
torch.randn(2,2)# ---->生服從標(biāo)準(zhǔn)正態(tài)分布的2X2
torch.arange(1,20,2)# ---->序列數(shù)組
2. numpy的array或者list數(shù)組轉(zhuǎn)換而來。

這里介紹一下numpy的array和torch的tensor的區(qū)別赘被,numpy的array是不支持GPU的是整,只支持CPU。而torch的tensor是兩個(gè)都支持的民假。

  • array轉(zhuǎn)tensor-----orch.from_numpy()
>>> a = numpy.array([1, 2, 3])
>>> t = torch.from_numpy(a)
>>> t
torch.LongTensor([1, 2, 3])
>>> t[0] = -1
>>> a
array([-1,  2,  3])

這個(gè)方法有一個(gè)缺點(diǎn)也是優(yōu)點(diǎn)浮入,生成的tensor和array指向同一個(gè)內(nèi)存地址,一個(gè)變了都會變羊异。

  • tensor轉(zhuǎn)array
    tensor轉(zhuǎn)成其他的數(shù)據(jù)的方法有很多事秀,如下:
import torch
a = torch.rand(2,2)
# to numpy.ndarray
a.numpy()
# 轉(zhuǎn)換成支持CPU
a.cpu()
# 轉(zhuǎn)換成支持GPU
a.cuda()
3. tensor的屬性
  • 數(shù)據(jù)類型
    32位浮點(diǎn)型:torch.FloatTensor。也是pyorch.Tensor()的默認(rèn)類型野舶。
    64位整型:torch.LongTensor易迹。
    32位整型:torch.IntTensor。
    16位整型:torch.ShortTensor平道。
    64位浮點(diǎn)型:torch.DoubleTensor睹欲。
  • 張量的大小
    tensor.size()
    tensor.shape
>>> tt1
tensor([[0.1372, 0.6473, 0.6765],
        [0.3346, 0.1886, 0.4174]])
>>> tt1.shape
torch.Size([2, 3])
>>> tt1.size()
torch.Size([2, 3])
  • 張量的元素個(gè)數(shù)
    torch.numel(input)
>>> tt1.numel()
6
>>> torch.numel(tt1)
6

基本上張量的簡介就差不多了,更多內(nèi)容參考pytorch中文文檔巢掺。

  • 變量(Variable

Variable類型數(shù)據(jù)是張量的升級版句伶,給tensor加了裝備:前向傳播劲蜻、反向傳播自動求導(dǎo)等功能考余,在計(jì)算圖的構(gòu)建中起的很重要的作用先嬉。有一個(gè)圖能很形象的說明:


其中最重要的兩個(gè)屬性是:data和grad。.data表示該變量保存的實(shí)際數(shù)據(jù)楚堤,通過該屬性可以訪問到它所保存的原始張量類型疫蔓,而關(guān)于該 variable(變量)的梯度會被累計(jì)到.grad 上去。與tensor不同身冬,Variable在另一個(gè)模塊內(nèi)----torch.autograd衅胀。不過,pytorch 0.4之后的版本酥筝,好像把Tensor和Variabel合并了滚躯。requires_grad變成了Tensor本來的一個(gè)屬性了。這里給一片博客可以參考

import torch
from torch.autograd import Variable 
# 定義三個(gè)Variable變量
# requires_grad 是設(shè)置是否需要計(jì)算梯度
x = Variable(torch.Tensor([1, 2, 3]), requires_grad=True)
w = Variable(torch.Tensor([2, 3, 4]), requires_grad=True)
b = Variable(torch.Tensor([3, 4, 5]), requires_grad=True)
# 構(gòu)建計(jì)算圖嘿歌,公式為:y = w * x^2 + b
y = w * x * x + b 
# 自動求導(dǎo)掸掏,計(jì)算梯度
# 這里傳入的torch.Tensor([1,1,1])是用來表示每個(gè)梯度的權(quán)重的
y.backward(torch.Tensor([1, 1, 1])) 
print(x.grad)# 2*w*x
print(w.grad)# x*x
print(b.grad)# 常量的導(dǎo)數(shù)為1

數(shù)據(jù)操作

- 索引 ---- 和numpy的索引相同
>>> tt1
tensor([[0.1372, 0.6473, 0.6765],
        [0.3346, 0.1886, 0.4174]])
>>> tt1[1,1]
tensor(0.1886)
>>> tt1[:,2]
tensor([0.6765, 0.4174])
- 切片---- 和numpy的切片相同
>>> tt1
tensor([[-0.3623, -0.6115,  0.7283],
        [ 0.4699,  2.3261,  0.1599]])
>>> tt1[:,1:2]
tensor([[-0.6115],
        [ 2.3261]])
>>> tt1[:,:]
tensor([[-0.3623, -0.6115,  0.7283],
        [ 0.4699,  2.3261,  0.1599]])
- 連接 ---- torch.cat()
>>> tt1 = torch.rand(2,3)
>>> tt2 = torch.rand(2,3)
>>> torch.cat((tt1,tt2),0)
tensor([[0.1372, 0.6473, 0.6765],
        [0.3346, 0.1886, 0.4174],
        [0.8388, 0.7322, 0.7819],
        [0.4745, 0.2260, 0.7371]])
>>> torch.cat((tt1,tt2),1)
tensor([[0.1372, 0.6473, 0.6765, 0.8388, 0.7322, 0.7819],
        [0.3346, 0.1886, 0.4174, 0.4745, 0.2260, 0.7371]])
- reshape ---- torch.view()、torch.reshape()
# view()
>>> tt1
tensor([[-0.3623, -0.6115,  0.7283],
        [ 0.4699,  2.3261,  0.1599]])
>>> tt1.view(-1)
tensor([-0.3623, -0.6115,  0.7283,  0.4699,  2.3261,  0.1599])
>>> tt1.view(3,2)
tensor([[-0.3623, -0.6115],
        [ 0.7283,  0.4699],
        [ 2.3261,  0.1599]])
# reshape()
>>> tt1
tensor([[-0.7242,  0.6419, -1.2202],
        [-0.7509, -0.9206,  0.9566]])
>>> tt1.reshape(3,2)
tensor([[-0.7242,  0.6419],
        [-1.2202, -0.7509],
        [-0.9206,  0.9566]])
  • 最后補(bǔ)充一個(gè)增加和去除無用維度的操作
    • 去除-----torch.squeeze(input, dim=None, out=None)
    • 增加-----torch.unsqueeze(input, dim=None, out=None)
>>> tt1
tensor([[-0.7242,  0.6419, -1.2202],
        [-0.7509, -0.9206,  0.9566]])
>>> tt = tt1.view(2,1,3)
>>> tt
tensor([[[-0.7242,  0.6419, -1.2202]],

        [[-0.7509, -0.9206,  0.9566]]])
>>> tt.shape
torch.Size([2, 1, 3])
>>> ttt = tt.squeeze()
>>> ttt
tensor([[-0.7242,  0.6419, -1.2202],
        [-0.7509, -0.9206,  0.9566]])
>>> ttt.shape
torch.Size([2, 3])

二者用法類似宙帝,返回張量與輸入張量共享內(nèi)存丧凤,所以改變其中一個(gè)的內(nèi)容會改變另一個(gè)。

數(shù)學(xué)運(yùn)算

  • 基本四則運(yùn)算-----python自帶的四則運(yùn)算符 " +步脓、-愿待、*、/ "
    都是對應(yīng)位置的操作靴患。
>>> tt1 = torch.randn(2,3)
>>> tt2 = torch.randn(2,3)
>>> tt1
tensor([[-0.7242,  0.6419, -1.2202],
        [-0.7509, -0.9206,  0.9566]])
>>> tt2
tensor([[-0.7343, -2.0070,  1.1552],
        [ 0.1351, -0.5211,  0.7543]])
>>> tt1+tt2
tensor([[-1.4585, -1.3651, -0.0649],
        [-0.6158, -1.4417,  1.7109]])
>>> tt1-tt2
tensor([[ 0.0100,  2.6489, -2.3754],
        [-0.8859, -0.3995,  0.2023]])
>>> tt1*tt2
tensor([[ 0.5318, -1.2883, -1.4096],
        [-0.1014,  0.4797,  0.7215]])
>>> tt1/tt2
tensor([[ 0.9863, -0.3198, -1.0562],
        [-5.5598,  1.7666,  1.2683]])

torch的:
加法torch.add(input, value, out=None)
乘法-----torch.mul(input, value, out=None)
除法-----torch.div(input, value, out=None)

# input是"被操作數(shù)"仍侥,必須是tensor,value是"操作數(shù)"蚁廓。
# 兩個(gè)張量相加访圃,對應(yīng)位置相加
>>> torch.add(tt1,tt2)
tensor([[-1.4585, -1.3651, -0.0649],
        [-0.6158, -1.4417,  1.7109]])
# tensor+標(biāo)量,為每個(gè)位置加上這個(gè)標(biāo)量
>>> torch.add(tt1,1)
tensor([[ 0.2758,  1.6419, -0.2202],
        [ 0.2491,  0.0794,  1.9566]])

這三個(gè)方法類似相嵌,不一一舉例腿时。

  • 高級運(yùn)算
    • 求對數(shù)(e為底)-----torch.log(input, out=None)
    • 求指數(shù)(e為底)-----torch.exp(tensor, out=None)
    • 其他2、10為低的指數(shù)-----torch.log2()饭宾,torch.log10()
    • 求次冪-----torch.pow(input, exponent, out=None)
    • 求絕對值-----torch.abs(input, out=None)
    • 三角函數(shù)-----torch.cos()批糟、torch.sin()、torch.tan()
    • 反三角函數(shù)-----torch.acos()看铆、torch.asin()徽鼎、torch.atan()
    • 均值、求和、方差否淤、標(biāo)準(zhǔn)差-----torch.mean()悄但、torch.sum()、torch.var()石抡、torch.std()
# 以tt1為底檐嚣,0為指數(shù)
>>> torch.pow(tt1,0)
tensor([[1., 1., 1.],
        [1., 1., 1.]])
# 以2.7為底,tt1為指數(shù)
>>> torch.pow(2.7,tt1)
tensor([[0.4871, 1.8919, 0.2976],
        [0.4743, 0.4008, 2.5861]])
# e為底
>>> torch.exp(tt1)
tensor([[0.4847, 1.9001, 0.2952],
        [0.4720, 0.3983, 2.6029]])

基本上夠用了啰扛,方法不熟悉就邊查遍用嚎京。
最后補(bǔ)充一點(diǎn)矩陣方面的東西:

  • torch.dot(tensor1, tensor2) -> float
    計(jì)算兩個(gè)一階張量的點(diǎn)積
  • torch.eig(input, eigenvectors=False, out=None) -> (Tensor, Tensor)
    • 計(jì)算input(方陣:n行n列)的特征值和特征向量。
    • eigenvectors=True隐解,同時(shí)計(jì)算特征值和特征微量鞍帝,否則只計(jì)算特征值。
  • torch.inverse(input, out=None) -> Tensor
    對方陣input求逆
  • torch.mm(mat1, mat2, out=None) -> Tensor
    對矩陣mat1和mat2進(jìn)行相乘煞茫。
  • torch.mv(mat, vec, out=None) -> Tensor
    對矩陣mat和向量vec進(jìn)行相乘帕涌。
  • torch.t(input, out=None)
    輸入一個(gè)矩陣(2維張量),并轉(zhuǎn)置0,1維溜嗜,可以被視為torch.transpose(input, 0, 1)的簡寫函數(shù)宵膨。torch.transpose()可以多維轉(zhuǎn)置。

流程結(jié)構(gòu)

這里主要介紹模型的搭建流程炸宵。

1. 構(gòu)建網(wǎng)絡(luò)
  • class Net(torch.nn.Module)方式:
import torch
import torch.nn.functional as F


class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)
        self.predict = torch.nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x
# 實(shí)例化
net = Net(10,3,2)
  • torch.nn.Sequential()
# 直接在Sequential類中初始化
net = torch.nn.Sequential(
    torch.nn.Linear(1, 10),
    torch.nn.ReLU(),
    torch.nn.Linear(10, 1)
)

這里有一篇文檔做了更詳細(xì)的舉例

2. 定義優(yōu)化器、損失函數(shù)

反向傳播的流程是借助損失函數(shù)谷扣,優(yōu)化器來實(shí)現(xiàn)的(更多函數(shù)請參考loss functionoptim)土全。

# 定義損失函數(shù)
loss_func = torch.nn.CrossEntropyLoss()

# 定義優(yōu)化器
optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
3. 前向傳播

上面兩個(gè)方法的前向傳播都是如此

predict = net(input)
4. 更新參數(shù)

使用優(yōu)化器通過優(yōu)化損失函數(shù),得到梯度会涎,反向更新模型參數(shù)裹匙。

# 1. 計(jì)算loss
loss = loss_func(predict,y_true)
# 2. 計(jì)算梯度
optimizer.zero_grad()   # 梯度清空
loss.backward()         # 反向傳播-->給優(yōu)化器
optimizer.step()        # 單步更新-->給參數(shù)

如此一個(gè)網(wǎng)絡(luò)搭建和一次訓(xùn)練就完成了!

- 最后補(bǔ)充一點(diǎn)如何決定使用CPU還是GPU

在訓(xùn)練網(wǎng)絡(luò)之前末秃,我們可以決定是通過CPU還是GPU來進(jìn)行訓(xùn)練概页。

  • 默認(rèn)的方式是CPU,無需任何操作练慕。
  • 選擇GPU
    第一種惰匙、實(shí)例化的時(shí)候使用.cuda()
    第二種、使用類似tensorflow的方式指定CUDA_VISIBLE_DEVICES
net = Net(10,3,2).cuda()
loss_func = torch.nn.CrossEntropyLoss().cuda()
#================================================
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
  • 智能選擇铃将,可以用以下代碼來決定:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

對應(yīng)的我們在實(shí)例化網(wǎng)絡(luò)和損失函數(shù)的時(shí)候都需要.to(device)项鬼。即:

net = Net(10,3,2).to(device)

loss_func = torch.nn.CrossEntropyLoss().to(device)

最后補(bǔ)充一篇解決模型超GPU顯存的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市劲阎,隨后出現(xiàn)的幾起案子绘盟,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件龄毡,死亡現(xiàn)場離奇詭異吠卷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沦零,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門撤嫩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蠢终,你說我怎么就攤上這事序攘。” “怎么了寻拂?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵程奠,是天一觀的道長。 經(jīng)常有香客問我祭钉,道長瞄沙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任慌核,我火速辦了婚禮距境,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垮卓。我一直安慰自己垫桂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布粟按。 她就那樣靜靜地躺著诬滩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灭将。 梳的紋絲不亂的頭發(fā)上疼鸟,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音庙曙,去河邊找鬼空镜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捌朴,可吹牛的內(nèi)容都是我干的吴攒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼男旗,長吁一口氣:“原來是場噩夢啊……” “哼舶斧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起察皇,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤庇茫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后偷厦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堡纬,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜕依,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琉雳,到底是詐尸還是另有隱情样眠,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布翠肘,位于F島的核電站檐束,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏束倍。R本人自食惡果不足惜被丧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绪妹。 院中可真熱鬧甥桂,春花似錦、人聲如沸邮旷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽廊移。三九已至糕簿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狡孔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工蜂嗽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苗膝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓植旧,卻偏偏與公主長得像辱揭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子病附,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • torch 本筆記引用自PyTorch中文文檔 包torch包含了多維疑是的數(shù)據(jù)結(jié)構(gòu)及基于其上的多種數(shù)學(xué)操作问窃。 1...
    zhaoQiang012閱讀 83,463評論 0 27
  • 該文章為轉(zhuǎn)載文章,作者簡介:汪劍完沪,現(xiàn)在在出門問問負(fù)責(zé)推薦與個(gè)性化域庇。曾在微軟雅虎工作嵌戈,從事過搜索和推薦相關(guān)工作。 T...
    名字真的不重要閱讀 5,207評論 0 3
  • 每過一段時(shí)間听皿,總會有一個(gè)python庫被開發(fā)出來熟呛,改變深度學(xué)習(xí)領(lǐng)域。而PyTorch就是這樣一個(gè)庫尉姨。 在過去的幾周...
    AiTechYun閱讀 3,999評論 0 4
  • 在自媒體時(shí)代庵朝,到底有多少人通過各種自媒體平臺發(fā)出聲音,很難統(tǒng)計(jì)出一個(gè)準(zhǔn)確的數(shù)字又厉。據(jù)艾媒咨詢最新權(quán)威發(fā)布《2016年...
    微語東來閱讀 589評論 0 5
  • 靈感九府,猶如花兒,多數(shù)在夜里悄悄綻放覆致。如折扇般輕輕打開侄旬,散發(fā)著若有似無的馨香。 我?guī)е老猜乜拷穸洌刂ǖ拿}絡(luò)肌...
    丫丫18閱讀 415評論 4 6