1.前言
很久沒有碰Pytorch了,準備以實戰項目代碼回顧的方式進行複習。
2.Pytorch安裝
現在我又切回了ubuntu系統,裡面沒有Pytorch,是以順便從Pytorch最新版安裝開始講起吧。
(1)本機配置
CUDA9.0, CUDNN7.1.2
Anaconda5.2.0
linux下查cuda,cudnn版本的方法:
① cuda
cat /usr/local/cuda/version.txt
② cudnn
(2)官方安裝
官方連結
2020.5.17官網已經更新到了pytorch1.5版本了,要求是:

最新版需要cuda9.2,我的是9.0無緣了,隻能安比較新的pytorch1.1.0,有anaconda的直接運作:
conda install pytorch==1.1.0 torchvision==0.3.0 cudatoolkit=9.0 -c pytorch
注意: 不用vpn安裝會很慢哦。
(3)運作測試
import torch
x = torch.rand(5, 3)
print(x)
print(torch.cuda.is_available())
輸出True就是使用了GPU了,而且運作中沒有tensorflow顯示得那麼複雜,很間接,而且能夠直接輸出numpy.array類型,非常pythonic。
注意: 如果你是python2.7,但還想用3.x的print文法,就在最前面加上以下的語句就ok了。
from __future__ import print_function
至此,pytorch安裝完畢。
3.Pytorch項目代碼回顧
這裡的項目具體是:
我不不會一行一行地講代碼,而是說說一些函數用法的注意事項以及探索。廢話不多說,開始吧。
1)一些常用函數的探索
(1)Tensor加法
import torch
x = torch.rand(5, 3, dtype=torch.float32)
y = torch.rand(5, 3, dtype=torch.float32)
print(x)
print(y)
y.add_(x) # 相當于python中的y+=x
print(y)
(2)torch.empty
最開始,我以為這個就是0的生成,結果不是。這個是建立了一個未被初始化數值的tensor,換句話說就是生成的tensor裡面的數是沒有規律的。
(3)資料切片
完全類似于numpy。
import torch
x = torch.rand(2, 2, dtype=torch.float32)
print(x)
y = x[:, 1]
print(y, y.shape)
"""
output:
tensor([[0.1247, 0.8228],
[0.5879, 0.0067]])
tensor([0.8228, 0.0067]) torch.Size([2])
"""
(4)view
完全類似于numpy中的reshape,并且
y = x.view(4)
與
y = x.reshape(4)
都是ok的。
import torch
x = torch.rand(2, 2, dtype=torch.float32)
print(x)
y = x.view(4)
print(y, y.shape)
"""
output:
tensor([[0.6341, 0.7080],
[0.5801, 0.2063]])
tensor([0.6341, 0.7080, 0.5801, 0.2063]) torch.Size([4])
"""
(5)tensor與array轉換
在tensorflow中,這種轉換很複雜,如要建構靜态圖,然後在run或者eval,才可以得到array。pytorch中非常簡單。
① 單一數字tensor的直接轉換
import torch
x = torch.rand(1, dtype=torch.float32)
print(x)
print(x.item())
"""
output:
tensor([0.3996])
0.3996013402938843
"""
② 數組tensor的直接轉換
import torch
x = torch.rand(2,2, dtype=torch.float32)
print(x)
print(x.numpy())
"""
output:
tensor([[0.7119, 0.3798],
[0.1673, 0.0765]])
[[0.71185666 0.37983876]
[0.16733897 0.07648808]]
"""
③ numpy轉tensor
import torch
import numpy as np
x = np.ones((2, 2))
print(x)
print(torch.from_numpy(x))
"""
output:
tensor([[0.7119, 0.3798],
[0.1673, 0.0765]])
[[0.71185666 0.37983876]
[0.16733897 0.07648808]]
"""
注意:
1.
np.ones((2, 2))
寫成
np.ones(2, 2)
是錯誤的。
2.一定要注意淺copy和深copy的差別,這裡與python是一樣的
1’淺copy:
import torch
x = torch.rand(2, 2, dtype=torch.float32)
print(x)
y = x
x += 1
print(x)
print(y)
"""
output:
tensor([[0.9920, 0.5458],
[0.9623, 0.2851]])
tensor([[1.9920, 1.5458],
[1.9623, 1.2851]])
tensor([[1.9920, 1.5458],
[1.9623, 1.2851]])
"""
或者使用copy庫:
import torch
import copy
x = torch.rand(2, 2, dtype=torch.float32)
print(x)
y = copy.copy(x)
x += 1
print(x)
print(y)
"""
output:
tensor([[0.9920, 0.5458],
[0.9623, 0.2851]])
tensor([[1.9920, 1.5458],
[1.9623, 1.2851]])
tensor([[1.9920, 1.5458],
[1.9623, 1.2851]])
"""
1’深copy:
這裡由于是對tensor操作的,并不能使用python中的.copy()哦!
import torch
import copy
x = torch.rand(2, 2, dtype=torch.float32)
print(x)
y = copy.deepcopy(x)
x += 1
print(x)
print(y)
"""
output:
tensor([[0.3382, 0.5585],
[0.2366, 0.9174]])
tensor([[1.3382, 1.5585],
[1.2366, 1.9174]])
tensor([[0.3382, 0.5585],
[0.2366, 0.9174]])
"""
(6)cpu,gpu兩種狀态的轉換需求
① 變量
import torch
if torch.cuda.is_available():
device = torch.device('cuda')
print(device)
x = torch.rand(2, 2, dtype=torch.float32, device=device)
print(x)
# print(x.numpy()) # 會報錯的,因為x變量已經放在了cuda上了,而numpy是在cpu上運作的
# corvert cuda to cpu
print(x.cpu().numpy())
print(x.to('cpu').numpy())
"""
output:
tensor([[0.7047, 0.3864],
[0.1722, 0.4075]], device='cuda:0')
[[0.70474064 0.3864395 ]
[0.1721652 0.40747693]]
[[0.70474064 0.3864395 ]
[0.1721652 0.40747693]]
"""
② 模型
2)實戰兩層神經網絡的訓練
網絡配置:
第一層:300
第二層:50
第三層:5
樣本數:32
學習率:1e-5
疊代次數:500
以下代碼已經有了詳細的注解
注意:
1.
dot
是真正的矩陣乘法,
*
和
multiply
是逐元素的乘法。
2.一定要注意在indexing的時候,True與1意思不一樣哦,True表示選擇某個index,而1表示選擇第二個元素,具體見下面的比較:
a = np.array([1, 2, 3, -1])
b = [False, True, False, True]
c = [0, 1, 0, 1]
out1 = a[b]
out2 = a[c]
print(out1, out2)
"""
output:
[ 2 -1] [1 2 1 2]
"""