感知機理論知識鏈結。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""created on 2019/12/31 21:17
@author: phil
"""import torch.nn as nn
import torch
import numpy as np
import torch.nn.functional as f
import torch.optim as optim
# 設定隨機種子
torch.manual_seed(42)
class
perceptronmodel
(nn.module)
:# 利用pytorch的自動求導機制實現感知機模型
def__init__
(self, learning_rate, max_iter=
1000):
super()
.__init__(
) self.learning_rate = learning_rate # 學習率
self.max_iter = max_iter # 最大迭代次數
# 模型引數
self.weight =
none
self.bias =
none
deffit
(self, x, y, method=
"grad"):
# 引數method指定引數更新的方法
n, m = x.shape
# 初始化模型引數
self.weight = torch.zeros(m, dtype=torch.float32, requires_grad=
true
) self.bias = torch.zeros(
1, dtype=torch.float32, requires_grad=
true
)# 將輸入的ndarray轉換為tensor
x = torch.from_numpy(x)
.float()
y = torch.from_numpy(y)
.float()
for i in
range
(self.max_iter)
:# 標記本輪迭代是否遇到錯分類樣本
has_error =
0# 遍歷訓練樣本
for idx in
range
(n):
xi = x[idx,:]
yi = y[idx]
# 計算線性函式輸出值
out = torch.add(torch.
sum(self.weight * xi)
, self.bias)
if out * yi <=0:
# 分類錯誤則更新
has_error =
1# 標記本輪迴圈遇到了錯誤樣本
loss = torch.
max(torch.tensor(
0, dtype=torch.float32),-
1* out * yi)
if method ==
"grad"
:# 直接求導,也就是直接算出dloss/dweight,dloss/dbiad
gradw = torch.autograd.grad(loss, self.weight, retain_graph=
true
) gradb = torch.autograd.grad(loss, self.bias, retain_graph=
true
)with torch.no_grad():
# 注意這裡更新引數時對引數的計算無需求導
self.weight -= self.learning_rate * gradw[0]
self.bias -= self.learning_rate * gradb[0]
if method ==
"backward"
:# 誤差反向傳播求導,直接呼叫backward計算出所有葉節點的梯度
loss.backward(
)with torch.no_grad():
self.weight -= self.learning_rate * self.weight.grad
self.bias -= self.learning_rate * self.bias.grad
# 梯度重置為0
self.weight.grad.zero_(
) self.bias.grad.zero_(
)if method ==
"optimizer"
:# 利用優化器完成引數的更新
# 1. 誤差反向傳播,也就是計算出所有計算圖中各個結點的梯度
loss.backward(
)# 2. 定義優化器
optimizer = optim.sgd(
(self.weight, self.bias)
, lr=self.learning_rate)
# 3. 根據上一步計算出的梯度更新
optimizer.step(
)# 4. 將梯度清空
optimizer.zero_grad(
)break
if has_error ==0:
# 本輪迭代所有樣本都分類正確,終止迴圈
break
defpredict
(self, x)
:# 每個樣本計算出的函式值
f_value = torch.
sum(self.weight * x, dim=1)
+ self.bias
# 計算對應的符號函式值,正數為1,負數為-1,0為0
pred = f.relu(f_value)
pred[pred ==0]
=1return pred
if __name__ ==
"__main__"
: x = np.array([[
3,3]
,[4,
3],[
1,1]
])y = np.array([1
,1,-
1]) model = perceptronmodel(learning_rate=1)
methods =
["grad"
,"backward"
,"optimizer"
]for method in methods:
model.fit(x, y, method)
print
("方法:"
+method+
" 引數為:"
, model.weight.data, model.bias.data)
PyTorch自動求導
當目標張量為標量時,backward 無需傳入引數。import torch如果需要對tensor求導,requires grad要設定為true。定義輸入張量x x torch.tensor 2 初始化權重引數w,偏置b,設定requires grad為true,使用自動求導 w torch.ra...
pytorch自動求導數機制
如果有乙個單一的輸入操作需要梯度,它的輸出也需要梯度 相反,只有所有輸入都不需要梯度,輸出才不需要。如果其中所有的變數都不需要梯度進行,反向傳播計算不會在子圖中執行。import torch from torch.autograd import variable x variable torch.r...
Pytorch02 自動求導機制
不同於靜態計算圖中網路結構一開始就被預設好,動態計算圖中乙個節點只有被執行到且requires gard true時,才被加入計算圖。深入淺出動態計算圖 作用 從loss向前對葉節點鏈式求導,計算得到的引數儲存在每個葉節點的grad中。不需要更新梯度的tensor。如果乙個節點根本就不需要更新梯度,...