Pytorch?autograd與邏輯回歸的實現(xiàn)詳解
引言
文章和代碼已經(jīng)歸檔至【Github倉庫:https://github.com/timerring/dive-into-AI 】
autograd 自動求導(dǎo)系統(tǒng)
torch.autograd
autograd
torch.autograd.backward
torch.autograd.backward ( tensors, grad_tensors=None,retain_graph=None,create_graph=False)
功能:自動求取梯度
- tensors : 用于求導(dǎo)的張量,如 loss
- retain\_graph : 保存計算圖
- create\_graph:創(chuàng)建導(dǎo)數(shù)計算圖,用于高階求導(dǎo)
- grad\_tensors :多梯度權(quán)重(用于設(shè)置權(quán)重)

注意:張量類中的backward方法,本質(zhì)上是調(diào)用的torch.autogtad.backward。
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward(retain_graph=True) # 可以保存梯度圖
# print(w.grad)
y.backward() # 可以求兩次梯度使用grad\_tensors可以設(shè)置每個梯度的權(quán)重。
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x) # retain_grad()
b = torch.add(w, 1)
y0 = torch.mul(a, b) # y0 = (x+w) * (w+1)
y1 = torch.add(a, b) # y1 = (x+w) + (w+1) dy1/dw = 2
loss = torch.cat([y0, y1], dim=0) # [y0, y1]
grad_tensors = torch.tensor([1., 2.])
loss.backward(gradient=grad_tensors) # gradient設(shè)置權(quán)重
print(w.grad)tensor([9.])
這個結(jié)果是由每一部分的梯度乘它對應(yīng)部分的權(quán)重得到的。
torch.autograd.grad
torch.autograd.grad (outputs, inputs, grad_outputs=None,retain_graph= None, create_graph=False)
功能:求取梯度
- outputs : 用于求導(dǎo)的張量,如 loss
- inputs : 需要梯度的 張量
- create\_graph: 創(chuàng)建導(dǎo)數(shù)計算圖,用于高階求導(dǎo)
- retain\_graph : 保存計算圖
- grad\_outputs :多梯度權(quán)重
x = torch.tensor([3.], requires_grad=True)
y = torch.pow(x, 2) # y = x**2
# grad_1 = dy/dx
grad_1 = torch.autograd.grad(y, x, create_graph=True)
print(grad_1)
# grad_2 = d(dy/dx)/dx
grad_2 = torch.autograd.grad(grad_1[0], x, create_graph=True)
print(grad_2) # 求二階導(dǎo)
grad_3 = torch.autograd.grad(grad_2[0], x)
print(grad_3)
print(type(grad_3))(tensor([6.], grad_fn=<MulBackward0>),)
(tensor([2.], grad_fn=<MulBackward0>),)
(tensor([0.]),)
<class 'tuple'>
注意:由于是元組類型,因此再次使用求導(dǎo)的時候需要訪問里面的內(nèi)容。
1.梯度不自動清零
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(4):
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward()
print(w.grad)
# If not zeroed, the errors from each backpropagation add up.
# This underscore indicates in-situ operation
grad.zero_()tensor([5.])
tensor([5.])
tensor([5.])
tensor([5.])
2.依賴于葉子結(jié)點的結(jié)點, requires\_grad 默認(rèn)為 True
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
# It can be seen that the attributes of the leaf nodes are all set to True
print(a.requires_grad, b.requires_grad, y.requires_grad)True True True
3.葉子結(jié)點不可執(zhí)行 in place
什么是in place?
試比較:
a = torch.ones((1, )) print(id(a), a) a = a + torch.ones((1, )) print(id(a), a) a += torch.ones((1, )) print(id(a), a) # After executing in place, the stored address does not change
2413216666632 tensor([1.])
2413216668472 tensor([2.])
2413216668472 tensor([3.])
葉子節(jié)點不能執(zhí)行in place,因為反向傳播時會用到葉子節(jié)點張量的值,如w。而取值是按照w的地址取得,因此如果w執(zhí)行inplace,則更換了w的值,導(dǎo)致反向傳播錯誤。
邏輯回歸 Logistic Regression
邏輯回歸是線性的二分類模型
模型表達(dá)式:
$\begin{array}{c}
y=f(W X+b)\
f(x)=\frac{1}{1+e^{-x}}
\end{array}$
f(x) 稱為Sigmoid函數(shù),也稱為Logistic函數(shù)
$\text { class }=\left{\begin{array}{ll}
0, & 0.5>y \
1, & 0.5 \leq y
\end{array}\right.$

邏輯回歸
$\begin{array}{c}
y=f(W X+b) \
\quad=\frac{1}{1+e^{-(W X+b)}} \
f(x)=\frac{1}{1+e^{-x}}
\end{array}$
線性回歸是分析自變量 x 與 因變量 y( 標(biāo)量 ) 之間關(guān)系的方法
邏輯回歸是分析自變量 x 與 因變量 y( 概率 ) 之間關(guān)系的方法
邏輯回歸也稱為對數(shù)幾率回歸(等價)。
$\frac{y}{1-y}$表示對數(shù)幾率。表示樣本x為正樣本的可能性。
證明等價:
$\begin{array}{l}
\ln \frac{y}{1-y}=W X+b \
\frac{y}{1-y}=e^{W X+b} \
y=e^{W X+b}-y * e^{W X+b} \
y\left(1+e^{W X+b}\right)=e^{W X+b} \
y=\frac{e^{W X+b}}{1+e^{W X+b}}=\frac{1}{1+e^{-(W X+b)}}
\end{array}$
線性回歸
自變量:X
因變量:y
關(guān)系:y=????+??
本質(zhì)就是用WX+b擬合y。
對數(shù)回歸
lny=????+??
就是用????+??擬合lny。
同理,對數(shù)幾率回歸就是用WX+b擬合對數(shù)幾率。
機器學(xué)習(xí)模型訓(xùn)練步驟

- 數(shù)據(jù)采集,清洗,劃分和預(yù)處理:經(jīng)過一系列的處理使它可以直接輸入到模型。
- 模型:根據(jù)任務(wù)的難度選擇簡單的線性模型或者是復(fù)雜的神經(jīng)網(wǎng)絡(luò)模型。
- 損失函數(shù):根據(jù)不同的任務(wù)選擇不同的損失函數(shù),例如在線性回歸中采用均方差損失函數(shù),在分類任務(wù)中可以選擇交叉熵。有了Loss就可以求梯度。
- 得到梯度可以選擇某一種優(yōu)化方式,即優(yōu)化器。采用優(yōu)化器更新權(quán)值。
- 最后再進(jìn)行迭代訓(xùn)練過程。
邏輯回歸的實現(xiàn)
# -*- coding: utf-8 -*-
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np
torch.manual_seed(10)
# ============================ step 1/5 Generate data ============================
sample_nums = 100
mean_value = 1.7
bias = 1
n_data = torch.ones(sample_nums, 2)
x0 = torch.normal(mean_value * n_data, 1) + bias # 類別0 數(shù)據(jù) shape=(100, 2)
y0 = torch.zeros(sample_nums) # 類別0 標(biāo)簽 shape=(100, 1)
x1 = torch.normal(-mean_value * n_data, 1) + bias # 類別1 數(shù)據(jù) shape=(100, 2)
y1 = torch.ones(sample_nums) # 類別1 標(biāo)簽 shape=(100, 1)
train_x = torch.cat((x0, x1), 0)
train_y = torch.cat((y0, y1), 0)
# ============================ step 2/5 Select Model ============================
class LR(nn.Module):
def __init__(self):
super(LR, self).__init__()
self.features = nn.Linear(2, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.features(x)
x = self.sigmoid(x)
return x
lr_net = LR() # Instantiate a logistic regression model
# ============================ step 3/5 Choose a loss function ============================
# Select the cross-entropy function for binary classification
loss_fn = nn.BCELoss()
# ============================ step 4/5 Choose an optimizer ============================
lr = 0.01 # Learning rate
optimizer = torch.optim.SGD(lr_net.parameters(), lr=lr, momentum=0.9)
# ============================ step 5/5 model training ============================
for iteration in range(1000):
# forward propagation
y_pred = lr_net(train_x)
# calculate loss
loss = loss_fn(y_pred.squeeze(), train_y)
# backpropagation
loss.backward()
# update parameters
optimizer.step()
# clear gradient
optimizer.zero_grad()
# drawing
if iteration % 20 == 0:
mask = y_pred.ge(0.5).float().squeeze() # Classify with a threshold of 0.5
correct = (mask == train_y).sum() # Calculate the number of correctly predicted samples
acc = correct.item() / train_y.size(0) # Calculate classification accuracy
plt.scatter(x0.data.numpy()[:, 0], x0.data.numpy()[:, 1], c='r', label='class 0')
plt.scatter(x1.data.numpy()[:, 0], x1.data.numpy()[:, 1], c='b', label='class 1')
w0, w1 = lr_net.features.weight[0]
w0, w1 = float(w0.item()), float(w1.item())
plot_b = float(lr_net.features.bias[0].item())
plot_x = np.arange(-6, 6, 0.1)
plot_y = (-w0 * plot_x - plot_b) / w1
plt.xlim(-5, 7)
plt.ylim(-7, 7)
plt.plot(plot_x, plot_y)
plt.text(-5, 5, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.title("Iteration: {}\nw0:{:.2f} w1:{:.2f} b: {:.2f} accuracy:{:.2%}".format(iteration, w0, w1, plot_b, acc))
plt.legend()
plt.show()
plt.pause(0.5)
if acc > 0.99:
break實現(xiàn)一個邏輯回歸步驟如上。后續(xù)會慢慢解釋。
以上就是Pytorch autograd與邏輯回歸的實現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于Pytorch autograd邏輯回歸的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Python實現(xiàn)文本轉(zhuǎn)語音(TTS)并播放音頻
在開發(fā)涉及語音交互或需要語音提示的應(yīng)用時,文本轉(zhuǎn)語音(TTS)技術(shù)是一個非常實用的工具,下面我們來看看如何使用gTTS和playsound庫將文本轉(zhuǎn)換為語音并播放音頻文件吧2025-03-03
Python實現(xiàn)將Excel內(nèi)容插入到Word模版中
前段時間因為需要處理一大堆驗收單,都是一些簡單的復(fù)制粘貼替換工作,于是就想到用python進(jìn)行處理。本文分享了用python將excel文件單元格內(nèi)容插入到word模版中并保存為新文件的辦法,希望對大家有所幫助2023-03-03
pyppeteer執(zhí)行js繞過webdriver監(jiān)測方法下
這篇文章主要為大家介紹了pyppeteer上執(zhí)行js并繞過webdriver監(jiān)測常見方法的上篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Python開發(fā)寶典CSV JSON數(shù)據(jù)處理技巧詳解
在Python中處理CSV和JSON數(shù)據(jù)時,需要深入了解這兩種數(shù)據(jù)格式的讀取、寫入、處理和轉(zhuǎn)換方法,下面將詳細(xì)介紹如何在Python中處理CSV和JSON數(shù)據(jù),并提供一些示例和最佳實踐2023-11-11
如何用python開發(fā)Zeroc Ice應(yīng)用
這篇文章主要介紹了如何用python開發(fā)Zeroc Ice應(yīng)用,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01

