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.]
"""
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.