1. 程式人生 > >PyTorch筆記1-PyTorch簡介

PyTorch筆記1-PyTorch簡介

PyTorch簡介

PyTorch的安裝

PyTorch的安裝十分簡單,根據PyTorch官網,對系統選擇和安裝方式等靈活選擇即可。這裡新建一個Python3的虛擬環境後,然後在虛擬環境下用pip安裝,如下圖所示

這裡寫圖片描述

PyTorch 會安裝兩個模組, 一個是 torch, 一個 torchvision, torch 是主模組, 用來搭建神經網路的, torchvision 是輔模組, 有資料庫, 還有一些已經訓練好的神經網路等著你直接用, 比如 (VGG, AlexNet, ResNet).

PyTorch之Tensor

pytorch是使用GPU和CPU優化的深度張量庫,torch中最重要的一個數據型別就是Tensor(張量)
Tensor是PyTorch的計算單元,可以理解為:N-dim陣列,跟Numpy類似。舉慄如下:
常數,如:a1 = 1,為0階Tensor;
向量,如:a2 = [2,1,5,1.1,2.3,1,5,1.1],為1階Tensor(也可以說一個維度);
二階矩陣為2階Tensor(2個維度),如:a3 =

[1739]
3個二階矩陣為3階Tensor(3個維度),如:a4 =
[1739][1739][1739]
  • 注意:Tensor是有尺寸大小的,跟維度區分開,如a2.size()=8, a3.size()=(2,2), a4.size()=(3,2,2)

Tensor運算

下面演示其中一些操作,PyTorch的Tensor全部運算,參見這裡

import torch
import numpy as np
from torch.autograd import Variable
import torch.nn.functional as F        # activation function
import matplotlib.pyplot as plt # python 的視覺化模組,畫圖用 %matplotlib inline
x1 = torch.rand(5,3) # 建立一個5*3的隨機矩陣
print(x1)
 0.3658  0.7387  0.0901
 0.4840  0.6414  0.1183
 0.4703  0.8766  0.9165
 0.7749  0.5472  0.4456
 0.5532  0.4522  0.1290
[torch.FloatTensor of size 5x3]
x2 = torch.ones(5,3) # 建立 5*3 的全1矩陣
print(x2)
 1  1  1
 1  1  1
 1  1  1
 1  1  1
 1  1  1
[torch.FloatTensor of size 5x3]
y1 = x1 + x2   # 兩個矩陣相加
print(y1)
 1.3658  1.7387  1.0901
 1.4840  1.6414  1.1183
 1.4703  1.8766  1.9165
 1.7749  1.5472  1.4456
 1.5532  1.4522  1.1290
[torch.FloatTensor of size 5x3]

PyTorch與Numpy

Torch自稱為神經網路界的Numpy,因為它能將torch產生的Tensor放在GPU中加速運算,就像Numpy的array可以在CPU中加速運算,且numpy array和torch tensor可以相互轉換
所有numpy上關於ndarray的運算都可以運用於Tensor
從numpy到tensor的轉換:torch.from_numpy(np_data)
從tensor到numpy的轉換:np_data.numpy()
tensor與numpy的最大不同是:tensor可以在GPU上運算

np_data = np.arange(4).reshape(2,2)
torch_data = torch.from_numpy(np_data)
tensor2array = torch_data.numpy()
print(
    'numpy array: \n', np_data,
    '\n=================\n',
    '\ntorch tensor: ', torch_data,
    '\n==================\n',
    'tensor to array: \n ', tensor2array
)
numpy array: 
 [[0 1]
 [2 3]] 
=================

torch tensor:  
 0  1
 2  3
[torch.LongTensor of size 2x2]

==================
 tensor to array: 
  [[0 1]
 [2 3]]

Torch tensor的運算和Numpy array類似,詳細參考,下面演示一些

# abs 絕對值計算
data = [-1, -2, 1, 2]
tensor = torch.FloatTensor(data) # 轉換成32位浮點 tensor
print(
    'numpy abs: ', np.abs(data),
    '\ntorch abs: ', torch.abs(tensor)
)

# sin 三角函式
print(
    '\nnumpy sin: ', np.sin(data),
    '\ntorch sin: ', torch.sin(tensor)
)

# mean 均值
print(
    '\nnumpy mean: ', np.mean(data),
    '\ntorch mean: ', torch.mean(tensor)
)
numpy abs:  [1 2 1 2] 
torch abs:  
 1
 2
 1
 2
[torch.FloatTensor of size 4]


numpy sin:  [-0.84147098 -0.90929743  0.84147098  0.90929743] 
torch sin:  
-0.8415
-0.9093
 0.8415
 0.9093
[torch.FloatTensor of size 4]


numpy mean:  0.0 
torch mean:  0.0
# matrix multiply
data = [[1,2], [3,4]]
tensor = torch.FloatTensor(data)
# correct
print(
    'numpy matmul: ', np.matmul(data, data),
    '\ntorch matmul: ', torch.mm(tensor, tensor)
)
numpy matmul:  [[ 7 10]
 [15 22]] 
torch matmul:  
  7  10
 15  22
[torch.FloatTensor of size 2x2]

Variable

在 Torch 中的 Variable 就是一個存放會變化的值的地理位置. 裡面的值會不停的變化. 就像一個裝雞蛋的籃子, 雞蛋數會不停變動. 那誰是裡面的雞蛋呢, 自然就是 Torch 的 Tensor 咯. 如果用一個 Variable 進行計算, 那返回的也是一個同類型的 Variable.

這裡寫圖片描述

如上圖,一個Variable裡面包含著三個屬性,data,grad和creator,其中creator表示得到這個Variabel的操作,比如乘法或者加法等等,grad表示方向傳播的梯度,data表示取出這個Variabel裡面的資料

本質上 Variable 和 Variable 沒有區別,不過 Variabel 會放入一個計算圖,然後進行前向傳播,反向傳播以及自動求導, Variable 在計算同時,會把計算路徑記錄下來,在記憶體中構造一個計算圖

  • 下面定義一個Variable
# 先產生雞蛋
tensor = torch.FloatTensor([[1,2], [3,4]])
# 把雞蛋放到籃子中,requires_grad 參不參與反向傳播,要不要計算梯度
variable = Variable(tensor, requires_grad=True)
print("tensor: ", tensor)
print("\n variable:", variable)
tensor:  
 1  2
 3  4
[torch.FloatTensor of size 2x2]


 variable: Variable containing:
 1  2
 3  4
[torch.FloatTensor of size 2x2]
  • Variable 計算、梯度
# 對比 tensor 和 variable 的計算
t_out = torch.mean(tensor*tensor)
v_out = torch.mean(variable*variable)
print("tensor mean: ", t_out)
print("\n variable mean: ", v_out)
tensor mean:  7.5

 variable mean:  Variable containing:
 7.5000
[torch.FloatTensor of size 1]

到目前為止, 我們看不出什麼不同, 但是時刻記住, Variable 計算時, 它在背景幕布後面一步步默默地搭建著一個龐大的系統, 叫做計算圖, computational graph.

這個圖是用來幹嘛的? 原來是將所有的計算步驟 (節點) 都連線起來, 最後進行誤差反向傳遞的時候, 一次性將所有 variable 裡面的修改幅度 (梯度) 都計算出來, 而 tensor 就沒有這個能力啦.

v_out = torch.mean(variable*variable) 就是在計算圖中新增的一個計算步驟, 計算誤差反向傳遞的時候有他一份功勞, 我們就來舉個例子:

v_out.backward() # 模擬 v_out 的誤差反向傳遞

# 下面兩步看不懂沒關係, 只要知道 Variable 是計算圖的一部分, 可以用來傳遞誤差就好.
# v_out = 1/4 * sum(variable*variable) 這是計算圖中的 v_out 計算步驟
# 針對於 v_out 的梯度就是, d(v_out)/d(variable) = 1/4*2*variable = variable/2

print(variable.grad) # 初始 variable 的梯度
Variable containing:
 0.5000  1.0000
 1.5000  2.0000
[torch.FloatTensor of size 2x2]
  • 獲取 Variable 裡面的資料
    直接print(variable)只會輸出 Variable 形式的資料,在很多時候是用不了的(如想要用 plt 畫圖),所以我們要轉換一下,將它變成 tensor 形式
print(variable) # Variable 形式
print(variable.data) # tensor 形式
print(variable.data.numpy()) # numpy 形式
Variable containing:
 1  2
 3  4
[torch.FloatTensor of size 2x2]


 1  2
 3  4
[torch.FloatTensor of size 2x2]

[[ 1.  2.]
 [ 3.  4.]]

動態圖機制

下面的動畫展示了 PyTorch 計算圖的動態生成過程
這裡寫圖片描述

從上面的動畫,可以看出,PyTorch的計算圖是在 forward 執行過程中被定義生成的。

PyTorch 中的激勵函式

Torch 中的激勵函式(activation function)有很多,如:relu、sigmoid、tanh、softplus,

relu:g(z)={0zz<0z0 sigmoid:g(z)=11+ez tanh:g(z)=ezezez+ez softplus:g(z)=ln(1+ez)
下面演示
x = torch.linspace(-5, 5, 200) # x data(tensor), shape(100,1)
x = Variable(x)
x_np = x.data.numpy()    # 轉成 numpy array,出圖時用 

# 幾種常用的激勵函式
y_relu = F.relu(x).data.numpy()
y_sigmoid = F.sigmoid(x).data.numpy()
y_tanh = F.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()
# y_softmax = F.softmax(x).data.numpy  softmax 比較特殊,不能直接顯示,用於多分類

# 畫圖
plt.figure(1, figsize=(8, 6))  # 作用新建繪畫視窗,獨立顯示繪畫的圖片
plt.subplot(221)
plt.plot(x_np, y_relu, c='red', label='relu')
plt.ylim(-1, 5)    # 設定 y 軸範圍
plt.legend(loc="best")  # 顯示圖例,best 為自適應

plt.subplot(222)
plt.plot(x_np, y_sigmoid, c='red', label='sigmoid')
plt.ylim(-0.2, 1.2)
plt.legend(loc="best")

plt.subplot(223)
plt.plot(x_np, y_tanh, c='red', label='tanh')
plt.ylim(-1.2, 1.2)
plt.legend(loc="best")

plt.subplot(224)
plt.plot(x_np, y_softplus, c='red', label='softplus')
plt.ylim(-0.2, 6)
plt.legend(loc="best")

plt.show()

這裡寫圖片描述