pythorch 學習小記

大多數的代碼都來自https://morvanzhou.github.io/tutorials/machine-learning/torch
只是自己入門pytorch隨便記得東西,然後隨手扔上來(markdown都不用了,懶懶懶

tensor:
import torch
data = [[1,2], [3,4]]
tensor = torch.FloatTensor(data)
各種操作和numpy.array類似

Variable:
from torch.autograd import Variable
變量,裏面的主要元素就是tensor(type(Variable.data) == A_KIND_OF_TENSORS),但是一個variable是會記住自己是被哪些Variable計算出來的(variable = Variable(tensor, requires_grad=True)),所以當我們計算出最後一個Variable:loss時,就可以通過loss.backward(),來對梯度進行反向傳播。
然後loss.grad就是其對應的梯度,loss計算圖中的各個Variable中的grad成員也會自動變成其對應的參數,記得每次計算新的grad時,要把原來的梯度清0。(optimizer.zero_grad()可以自動完成這個操作,把所有Variable的grad成員數值變爲0,然後optimizer.step()則在每個Variable的grad都被計算出來後,更新每個Variable的數值

激勵函數:
import torch.nn.functional as F
F裏面存着各種激勵函數,進去一個Variable,出來一個Variable,最常用的當然就是F.relu(A_VARIABLE)

optimizer:
optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
qusetion:net.parameters()是哪裏來的,作用是什麼?
optimizer.zero_grad()可以把所有Variable的grad成員數值變爲0
optimizer.step()則可以用所有Variable的grad成員和lr的數值自動更新Variable的數值。
給Variable打上粗體是因爲之中Variable會被optimizer的相關函數更新,如果你把東西放在list或其它東西里,它們的梯度是不會被更新的!

loss function:
loss_func = torch.nn.MSELoss()

建立一個神經網絡:
class Net(torch.nn.Module):  # 繼承 torch 的 Module
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()     # 繼承 __init__ 功能
        # 定義每層用什麼樣的形式
        self.hidden = torch.nn.Linear(n_feature, n_hidden)   # 隱藏層線性輸出
        self.predict = torch.nn.Linear(n_hidden, n_output)   # 輸出層線性輸出

    def forward(self, x):   # 這同時也是 Module 中的 forward 功能
        # 正向傳播輸入值, 神經網絡分析出輸出值
        x = F.relu(self.hidden(x))      # 激勵函數(隱藏層的線性值)
        x = self.predict(x)             # 輸出值
        return x

net = Net(n_feature=1, n_hidden=10, n_output=1)

print(net)  # net 的結構"""
Net (
  (hidden): Linear (1 -> 10)
  (predict): Linear (10 -> 1)
)
"""

訓練一個網絡:
# optimizer 是訓練的工具optimizer = torch.optim.SGD(net.parameters(), lr=0.5)  # 傳入 net 的所有參數, 學習率loss_func = torch.nn.MSELoss()      # 預測值和真實值的誤差計算公式 (均方差)

for t in range(100):
    prediction = net(x)     # 餵給 net 訓練數據 x, 輸出預測值

    loss = loss_func(prediction, y)     # 計算兩者的誤差

    optimizer.zero_grad()   # 清空上一步的殘餘更新參數值
    loss.backward()         # 誤差反向傳播, 計算參數更新值
    optimizer.step()        # 將參數更新值施加到 net 的 parameters 上

快速搭建網絡:
之前寫的搭建方法適用於你可以對網絡進行各種各樣的自定義
接下來的方法,如果不需要什麼複雜的過程的話,只需要按下面的過程來構建就好了。
net2 = torch.nn.Sequential(
    torch.nn.Linear(1, 10),
    torch.nn.ReLU(),
    torch.nn.Linear(10, 1)
)

保存網絡:
torch.save(net1, 'net.pkl') # 保存整個網絡
torch.save(net1.state_dict(), 'net_params.pkl') # 只保存網絡中的參數 (速度快, 佔內存少)

提取網絡:
提取整個神經網絡, 網絡大的時候可能會比較慢.
def restore_net():
    # restore entire net1 to net2
    net2 = torch.load('net.pkl')
    prediction = net2(x)
只提取網絡參數
def restore_params():
    # 新建 net3
    net3 = torch.nn.Sequential(
        torch.nn.Linear(1, 10),
        torch.nn.ReLU(),
        torch.nn.Linear(10, 1)
    )

    # 將保存的參數複製到 net3
    net3.load_state_dict(torch.load('net_params.pkl'))
    prediction = net3(x)


批處理:
# 把 dataset 放入 DataLoaderloader = Data.DataLoader(
    dataset=torch_dataset,      # torch TensorDataset format
    batch_size=BATCH_SIZE,      # mini batch size
    shuffle=True,               # 要不要打亂數據 (打亂比較好)
    num_workers=2,              # 多線程來讀數據)

for epoch in range(3):   # 訓練所有!整套!數據 3 次
    for step, (batch_x, batch_y) in enumerate(loader):  # 每一步 loader 釋放一小批數據用來學習
        # 假設這裏就是你訓練的地方...

        # 打出來一些數據
        print('Epoch: ', epoch, '| Step: ', step, '| batch x: ',
              batch_x.numpy(), '| batch y: ', batch_y.numpy())

"""
Epoch:  0 | Step:  0 | batch x:  [ 6.  7.  2.  3.  1.] | batch y:  [  5.   4.   9.   8.  10.]
Epoch:  0 | Step:  1 | batch x:  [  9.  10.   4.   8.   5.] | batch y:  [ 2.  1.  7.  3.  6.]
Epoch:  1 | Step:  0 | batch x:  [  3.   4.   2.   9.  10.] | batch y:  [ 8.  7.  9.  2.  1.]
Epoch:  1 | Step:  1 | batch x:  [ 1.  7.  8.  5.  6.] | batch y:  [ 10.   4.   3.   6.   5.]
Epoch:  2 | Step:  0 | batch x:  [ 3.  9.  2.  6.  7.] | batch y:  [ 8.  2.  9.  5.  4.]
Epoch:  2 | Step:  1 | batch x:  [ 10.   4.   8.   1.   5.] | batch y:  [  1.   7.   3.  10.   6.]
"""
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章