1. 程式人生 > 其它 >深度學習初體驗

深度學習初體驗

程式碼練習

一.pytorch 基礎練習

1.定義資料

用tensor就可以支援各種各樣型別的資料,不再需要對不同的資料型別分別記憶。

2.定義操作

用Tensor進行各種運算的,都是Function,即也不需要呼叫額外的函式

3.總結

初次接觸,感覺該語言使用起來更簡潔方便。

二.螺旋資料分類

1.初始化生成樣本

import random
import torch
from torch import nn, optim
import math
from IPython import display
from plot_lib import plot_data, plot_model, set_default

# 因為colab是支援GPU的,torch 將在 GPU 上執行
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('device: ', device)

# 初始化隨機數種子。神經網路的引數都是隨機初始化的,
# 不同的初始化引數往往會導致不同的結果,當得到比較好的結果時我們通常希望這個結果是可以復現的,
# 因此,在pytorch中,通過設定隨機數種子也可以達到這個目的
seed = 12345
random.seed(seed)
torch.manual_seed(seed)

N = 1000  # 每類樣本的數量
D = 2  # 每個樣本的特徵維度
C = 3  # 樣本的類別
H = 100  # 神經網路裡隱層單元的數量

初始化重要引數

X = torch.zeros(N * C, D).to(device)
Y = torch.zeros(N * C, dtype=torch.long).to(device)
for c in range(C):
    index = 0
    t = torch.linspace(0, 1, N) # 在[0,1]間均勻的取10000個數,賦給t
    # 下面的程式碼不用理解太多,總之是根據公式計算出三類樣本(可以構成螺旋形)
    # torch.randn(N) 是得到 N 個均值為0,方差為 1 的一組隨機數,注意要和 rand 區分開
    inner_var = torch.linspace( (2*math.pi/C)*c, (2*math.pi/C)*(2+c), N) + torch.randn(N) * 0.2
    
    # 每個樣本的(x,y)座標都儲存在 X 裡
    # Y 裡儲存的是樣本的類別,分別為 [0, 1, 2]
    for ix in range(N * c, N * (c + 1)):
        X[ix] = t[index] * torch.FloatTensor((math.sin(inner_var[index]), math.cos(inner_var[index])))
        Y[ix] = c
        index += 1

print("Shapes:")
print("X:", X.size())
print("Y:", Y.size())

初始化X、Y

plot_data(X, Y)

2.構建模型分類

learning_rate = 1e-3
lambda_l2 = 1e-5

# nn 包用來建立線性模型
# 每一個線性模型都包含 weight 和 bias
model = nn.Sequential(
    nn.Linear(D, H),
    nn.Linear(H, C)
)
model.to(device) # 把模型放到GPU上

# nn 包含多種不同的損失函式,這裡使用的是交叉熵(cross entropy loss)損失函式
criterion = torch.nn.CrossEntropyLoss()

# 這裡使用 optim 包進行隨機梯度下降(stochastic gradient descent)優化
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, weight_decay=lambda_l2)

# 開始訓練
for t in range(1000):
    # 把資料輸入模型,得到預測結果
    y_pred = model(X)
    # 計算損失和準確率
    loss = criterion(y_pred, Y)
    score, predicted = torch.max(y_pred, 1)
    acc = (Y == predicted).sum().float() / len(Y)
    print('[EPOCH]: %i, [LOSS]: %.6f, [ACCURACY]: %.3f' % (t, loss.item(), acc))
    display.clear_output(wait=True)

    # 反向傳播前把梯度置 0 
    optimizer.zero_grad()
    # 反向傳播優化 
    loss.backward()
    # 更新全部引數
    optimizer.step()
print(model)
plot_model(X, Y, model)

在上述的線性模型分類中加入啟用函式ReLu() ,構建兩層神經網路分類:

model = nn.Sequential(
    nn.Linear(D, H),
    nn.ReLU(),
    nn.Linear(H, C)
)
model.to(device)

可以看到,分類的準確率極大地提高了。

3.總結

通過本次練習,體會到了深度學習中模型的重要性,一個好的模型,使得對同樣的資料,最後得到的準確率大大提高,以ReLu函式為例,通過單側抑制,使得原本的線性模型更好地貼合螺旋資料,進而得到較好的分類結果。