pytorch自動求導實現感知機模型

2021-10-02 02:46:00 字數 3531 閱讀 6374

感知機理論知識鏈結。

#!/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。如果乙個節點根本就不需要更新梯度,...