Pytorch?autograd與邏輯回歸的實(shí)現(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é)點(diǎn)的結(jié)點(diǎn), 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é)點(diǎn)不可執(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é)點(diǎn)不能執(zhí)行in place,因?yàn)榉聪騻鞑r會用到葉子節(jié)點(diǎn)張量的值,如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ù)幾率。
機(jī)器學(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)練過程。
邏輯回歸的實(shí)現(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
實(shí)現(xiàn)一個邏輯回歸步驟如上。后續(xù)會慢慢解釋。
以上就是Pytorch autograd與邏輯回歸的實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于Pytorch autograd邏輯回歸的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Python實(shí)現(xiàn)文本轉(zhuǎn)語音(TTS)并播放音頻
在開發(fā)涉及語音交互或需要語音提示的應(yīng)用時,文本轉(zhuǎn)語音(TTS)技術(shù)是一個非常實(shí)用的工具,下面我們來看看如何使用gTTS和playsound庫將文本轉(zhuǎn)換為語音并播放音頻文件吧2025-03-03Python實(shí)現(xiàn)將Excel內(nèi)容插入到Word模版中
前段時間因?yàn)樾枰幚硪淮蠖羊?yàn)收單,都是一些簡單的復(fù)制粘貼替換工作,于是就想到用python進(jìn)行處理。本文分享了用python將excel文件單元格內(nèi)容插入到word模版中并保存為新文件的辦法,希望對大家有所幫助2023-03-03pyppeteer執(zhí)行js繞過webdriver監(jiān)測方法下
這篇文章主要為大家介紹了pyppeteer上執(zhí)行js并繞過webdriver監(jiān)測常見方法的上篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04Python開發(fā)寶典CSV JSON數(shù)據(jù)處理技巧詳解
在Python中處理CSV和JSON數(shù)據(jù)時,需要深入了解這兩種數(shù)據(jù)格式的讀取、寫入、處理和轉(zhuǎn)換方法,下面將詳細(xì)介紹如何在Python中處理CSV和JSON數(shù)據(jù),并提供一些示例和最佳實(shí)踐2023-11-11對python:循環(huán)定義多個變量的實(shí)例詳解
今天小編就為大家分享一篇對python:循環(huán)定義多個變量的實(shí)例詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01如何用python開發(fā)Zeroc Ice應(yīng)用
這篇文章主要介紹了如何用python開發(fā)Zeroc Ice應(yīng)用,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01