vs2015網(wǎng)站開發(fā)教程seo搜索優(yōu)化待遇
1 安裝
1.1 簡介
pytorch可用gpu加速,也可以不加速。gpu加速是通過cuda來實現(xiàn),cuda是nvidia推出的一款運算平臺,它可以利用gpu提升運算性能。
所以如果要裝帶加速的pytorch,需要先裝cuda,再裝pytorch,如果不需用加速,即默認(rèn)用cpu計算,可不用裝cuda
裝cuda需要電腦有nvidia的顯卡,如果你的網(wǎng)卡是amd,那么抱歉,windows上裝不了加速的pytorch,因為cuda不支持amd,pytorch也不支持amd。不過可以裝沒加速的pytorch,因為官網(wǎng)寫了,pytorch不支持amd,但linux上pytorch支持amd(ROCm)
1.2 安裝
官網(wǎng)上如果能安裝,直接拷貝命令安裝就行。我的環(huán)境是windows下conda環(huán)境,官網(wǎng)那個頁面就可以選stable(穩(wěn)定版),windows,conda,python,cpu,然后拷貝下面'run this command'處的命令去安裝
注意
1 當(dāng)時安裝時下載包超時一直報錯,可以去國內(nèi)鏡像下載對應(yīng)的版本包,然后conda install --offline package_name離線安裝
2 原理與簡單使用
2.1 常規(guī)命令
x = torch.rand(5, 3) # 5行3列的值在0-1范圍內(nèi)矩陣
y = torch.randn(5, 3) # 5行3列滿足均值0方差1正態(tài)分布的矩陣
z = torch.ones(2, 5, 3)
x.mm(y.t()) # x和y矩陣乘法
x.mm(y.T) # 同上,寫法不同
x * y # # x和y數(shù)乘,需滿足x和y矩陣形狀相同# pytorch和numpy轉(zhuǎn)換
x = torch.randn(2, 3)
y = np.random.rand(2, 3)
x_np = x.numpy()
y_torch = torch.from_numpy(y)# 使用gpu張量運算
if torch.cuda.is_available(): # 判斷torch是否可cuda加速x = x.cuda()y = y.cuda()print(x + y)# 使用cpu張量運算(把x.cuda()換成x.cpu()即可)
x.cpu()
...
2.2 動態(tài)計算圖
可為神經(jīng)網(wǎng)絡(luò)提供統(tǒng)一的反向傳播算法方案,可以使人專注于神經(jīng)網(wǎng)絡(luò)設(shè)計。通過動態(tài)計算圖,在神經(jīng)網(wǎng)絡(luò)運算完成后,可以讓反向傳播算法自動運行。好處是不用手動設(shè)計反向傳播算法,動態(tài)計算圖弄成了自動
計算圖的解決思路是將正向計算過程記錄下來,只要計算過程可微分,就可以對計算過程求導(dǎo)算梯度
計算圖有靜態(tài)的和動態(tài)的,pytorch即支持動態(tài)也可以靜態(tài)
2.3 自動微分變量
pytorch通過自動微分變量實現(xiàn)動態(tài)計算圖,自動微分變量比一般張量結(jié)構(gòu)更復(fù)雜
如何反向傳播:計算圖弄好后,直接調(diào)用.backward()即可獲取每個計算過程梯度,并存儲在自動微分變量結(jié)構(gòu)體中
自動微分變量有三個重要屬性data, grad, grad_fn
data存儲自動微分變量的值
grad存儲自動微分變量的梯度
grad_fn就是計算圖中每個箭頭和其方向,這樣就可以通過grad_fn回溯計算圖。調(diào)backward后,會將每個變量的梯度保存到變量的grad屬性中
創(chuàng)自動微分變量時,通過傳入關(guān)鍵字requires_grad為True實現(xiàn)
x = torch.ones(2, 2, requires_grad=True)
pytorch 0.4版本以后,自動微分變量和一般張量合并了,即可以不用顯式傳入requires_grad獲取的張量也是自動微分變量
backward方法只能對計算圖的葉節(jié)點調(diào)用,如果非葉節(jié)點調(diào)用會得到None
3 實例
from matplotlib import pyplot as plotimport torch
from sklearn.model_selection import train_test_splitclass Sample():def exec(self):self.prepare_data()self.train()self.predict()self.plot()def prepare_data(self):self.x = torch.linspace(1, 100, 100).type(torch.FloatTensor)rand = torch.randn(100) * 10self.y = self.x + rand#self.data = train_test_split(self.x, self.y)self.data = self.x[:-10], self.x[-10:], self.y[:-10], self.y[-10:]self.a = torch.rand(1, requires_grad=True)self.b = torch.rand(1, requires_grad=True)self.learning_rate = 0.0001def train(self):for i in range(2000):prediction = self.a.expand_as(self.data[0]) * self.data[0] + self.b.expand_as(self.data[0])loss = torch.mean((prediction - self.data[2]) ** 2)if i % 200 == 0:print(f'loss: {loss}')loss.backward()self.a.data.add_( - self.learning_rate * self.a.grad.data)self.b.data.add_( - self.learning_rate * self.b.grad.data)self.a.grad.data.zero_()self.b.grad.data.zero_()def predict(self):self.pred = self.a.expand_as(self.data[1]) * self.data[1] + self.b.expand_as(self.data[1])def plot(self):plot.figure(figsize=(10, 8))plot.plot(self.data[0].data, self.data[2].data, 'o')plot.plot(self.data[1].data, self.data[3].data, 's')plot.plot(self.data[0], self.data[0] * self.a.data + self.b.data)plot.plot(self.data[1], self.pred.detach().numpy(), 'o')plot.xlabel('x')plot.ylabel('y')plot.show()def main():Sample().exec()passif __name__ == '__main__':main()
注意
1 self.b.data.add()和self.b.data.add_()區(qū)別是帶下劃線的是自運算,即將運算獲得的值賦值給自身
2 對a b調(diào)用expand_as是為了擴維至x,因為a,b是數(shù),但x是矩陣