pytorch基本運算-梯度運算:requires_grad_(True)和backward()

引言

前序學習進程中,已經對pytorch基本運算中的求導進行了基礎討論,相關文章鏈接為:

導數運算pytorch基本運算-導數和f-string-CSDN博客

實際上,求導是微分的進一步計算,要想求導的前一步其實是計算微分:

導數表達式:
f ′ ( x ) 或 d y d x f^{'}(x) 或 \frac{dy}{dx} f(x)dxdy?
?微分表達式:
f ′ ( x ) d x 或 d y = f ′ ( x ) d x f^{'}(x) dx 或 {dy=f^{'}(x) dx} f(x)dxdy=f(x)dx
導數是某一點處的變化率,微分是某一點附近的變化量。
如果一個函數在多個點進行導數求解,或者說子安多維度上進行導數計算,實際上就是在求梯度。

pytorch自動微分獲取梯度

為完整展示pytorch的梯度計算功能,將測試分為以下部分。

初始定義

首先是引入模塊,完成變量定義:

# 導入模塊
import torch
# 定義變量
x=torch.arange(3.0)
print('x=',x)

這里的輸出結果是:

x= tensor([0., 1., 2.])

需要說明的是,因為pytorch默認對浮點數進行求導,所以定義變量的時候,pyorch.arange()使用了3.0而不是整數3。
緊接著,需要對變量執行梯度運算。

梯度運算標定

梯度運算標定的目的是,聲明要對x進行梯度運算。任何沒有經過提前標定的量,都不能正常執行梯度運算。

# 標記需要對x進行梯度計算
z=x.requires_grad_(True)
print('z=',z)

梯度標定使用requires_grad_(True),就像對話一樣,需要求梯度_(需要)。
代碼運行的效果為:

z= tensor([0., 1., 2.], requires_grad=True)

下一步是定義一個函數。

函數定義

這里定義一個簡單函數:
f ( x ) = 2 x 2 f(x)=2x^{2} f(x)=2x2
具體定義代碼為:

# 點乘定義
m=2*torch.dot(x,x)
print('m=',m)

計算微分對函數開展才有意義,所以必須定義函數,這里只是一個示例,也可以是其他函數。
torch.dot()函數的計算規則為:對位相乘然后求和。
代碼運行效果為:

m= tensor(10., grad_fn=)

這里輸出了兩個部分:
第一部分是10,就是元素對位相乘后求和的效果(2X0X0+2X1X1+2X2X2=10)。
第二部分是grad_fn=,grad_fn的意思是grad_function,就是求導函數的意思,后面的MulBackward0是對求導函數的具體定義。
MulBackward0 表示這是一個乘法操作的梯度函數,具體拆開來:multiplication-backward,字面意思解釋:乘法-反向傳播。
這就是pytorch自動微分的核心機制:它可以自動測算求導函數的類型,比如這是一個自變量相乘的函數,并且指出要用哪種方法,比如這里要用反向傳播法。
到這一步還無法計算微分,只是通過輸出效果知道用反向傳播方法計算微分,然后就是正式使用反向傳播方法計算微分。

梯度計算

微分計算使用的代碼為:

# 執行梯度運算
n=m.backward()
k=x.grad
print('n=',n)
print('k=',k)

這里用了兩步,第一步是定義對函數m調用backward方法求倒數,然后具體是對x求導數,所獲得計算結果為:

n= None
k= tensor([0., 4., 8.])

n對應的其實是方法定義,k才是具體的對x的求導效果。

實際上到這一步,如何用pytorch直接計算導數已經非常清晰:先要標定梯度計算的變量,然后要對函數聲明梯度計算的方法,最后直接計算梯度。完整代碼為:

# 導入模塊
import torch
# 定義變量
x=torch.arange(3.0)
print('x=',x)
# 標記需要對x進行梯度計算
z=x.requires_grad_(True)
print('z=',z)
# 點乘定義
m=2*torch.dot(x,x)
print('m=',m)
# 執行梯度運算
n=m.backward()
k=x.grad
print('n=',n)
print('k=',k)

新的函數

未計算對新函數進行求導運算,需要提前將梯度清零,避免梯度計算效果彼此疊加,出現預料之外的效果。

梯度清零

代碼為:

# 梯度清零
kk=x.grad.zero_()
print('kk=',kk)

代碼運行效果為:

kk= tensor([0., 0., 0.])

定義新函數

代碼為:

# 定義新函數
hh=x.sum()
print('hh=',hh)

這里使用了求和函數sim(),代碼運行效果為:

hh= tensor(3., grad_fn=)

這里也輸出了兩個部分:
第一部分是3,就是元素求和的效果(0+1+2=3)。
第二部分是grad_fn=,grad_fn的意思是grad_function,就是求導函數的意思,后面的SumBackward0是對求導函數的具體定義。
SumBackward0 表示這是一個加法操作的梯度函數,具體拆開來:Sum-backward,字面意思解釋:加法-反向傳播。

導數計算

此時可以直接計算導數,代碼為:

# 定義用backward方法計算導數
nn=hh.backward()
print('nn=',nn)
# 導數計算
tt=x.grad
print('tt=',tt)

代碼運行效果為:

nn= None
tt= tensor([1., 1., 1.])

因為是各個變量直接疊加,所以每個變量前的系數都是1,所以導數運算的結果是[1.0,1.0,1.0].
此時的完整代碼為:

# 導入模塊
import torch
# 定義變量
x=torch.arange(3.0)
print('x=',x)
# 標記需要對x進行梯度計算
z=x.requires_grad_(True)
print('z=',z)
# 點乘定義
m=2*torch.dot(x,x)
print('m=',m)
# 執行梯度運算
n=m.backward()
k=x.grad
print('n=',n)
print('k=',k)
# 梯度清零
kk=x.grad.zero_()
print('kk=',kk)
# 定義新函數
hh=x.sum()
print('hh=',hh)
# 定義用backward方法計算導數
nn=hh.backward()
print('nn=',nn)
# 導數計算
tt=x.grad
print('tt=',tt)

完整的輸出效果為:

x= tensor([0., 1., 2.])
z= tensor([0., 1., 2.], requires_grad=True)
m= tensor(10., grad_fn=)
n= None
k= tensor([0., 4., 8.])
kk= tensor([0., 0., 0.])
hh= tensor(3., grad_fn=)
nn= None
tt= tensor([1., 1., 1.])

梯度清零操作的討論

前述有一個梯隊清零的操作,如果沒有這步操作,輸出效果會如何變化,這里直接給出完整代碼來測試。給出完整代碼為:

# 導入模塊
import torch
# 定義變量
x=torch.arange(3.0)
print('x=',x)
# 標記需要對x進行梯度計算
z=x.requires_grad_(True)
print('z=',z)
# 點乘定義
m=2*torch.dot(x,x)
print('m=',m)
# 執行梯度運算
n=m.backward()
k=x.grad
print('n=',n)
print('k=',k)
# 梯度清零
#kk=x.grad.zero_()
#print('kk=',kk)
# 定義新函數
hh=x.sum()
print('hh=',hh)
# 定義用backward方法計算導數
nn=hh.backward()
print('nn=',nn)
# 導數計算
tt=x.grad
print('tt=',tt)

此時的輸出效果為:

x= tensor([0., 1., 2.])
z= tensor([0., 1., 2.], requires_grad=True)
m= tensor(10., grad_fn=)
n= None
k= tensor([0., 4., 8.])
hh= tensor(3., grad_fn=)
nn= None
tt= tensor([1., 5., 9.])

這里可以看到sum()函數的梯度輸出為:[1.,5.,9.],這個結果的來源其實是:[0., 4., 8.]+[1., 1., 1.]=[1., 5., 9.]。
此處可見,及時將梯度清零很有必要。

總結

掌握了通過python+pytorch執行梯度運算的基本技巧。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83747.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83747.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83747.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

idea64.exe.vmoptions配置

這個idea64.exe.vmoptions文件是用于配置 IntelliJ IDEA(64位版本)運行時的 Java 虛擬機(JVM)參數。這些參數直接影響到 IDEA 的性能、內存使用、調試能力和行為。 下面是對文件中每一行配置的詳細解讀: -Xms2048m 作…

齊次變換矩陣相乘的復合變換:左乘與右乘的深度解析

在三維幾何變換中,齊次變換矩陣相乘是實現復雜變換的核心方法。本文將通過一個包含四個變換步驟的完整示例,深入探討齊次變換矩陣左乘和右乘的區別,并結合 Python sympy 庫的代碼實現,詳細闡述變換過程和結果差異。 二維齊次坐標的旋轉變換 在二維齊次坐標系中,一個點可以…

5g LDPC編譯碼-LDPC編碼

目錄 1、LDPC編碼基礎知識 2、5g的LDPC編碼 2.1 LDPC分塊: 2.2 LDCP編碼 2.3 校驗位的產生 1、LDPC編碼基礎知識 LDPC屬于線性分組碼,線性分組碼的基本知識如下: 編碼后的碼字是由初始二進制序列與生成矩陣在二進制域相乘后得到,生成矩陣與校驗矩陣,校驗矩陣與編碼后…

OpenVINO使用教程--resnet分類模型部署

OpenVINO使用教程--resnet分類模型部署 本節內容模型準備推理測試分析&總結本節內容 OpenVINO 根據AI技術類型將部署任務分成傳統模型模型部署和生成式AI模型部署,傳統模型指的是各種CNN小模型,這部分部署只需要OpenVINO包,具體安裝教程可以參考之前的章節:OpenVINO環境…

無字母數字webshell的命令執行

在Web安全領域,WebShell是一種常見的攻擊手段,通過它攻擊者可以遠程執行服務器上的命令,獲取敏感信息或控制系統。而無字母數字WebShell則是其中一種特殊形式,通過避免使用字母和數字字符,來繞過某些安全機制的檢測。 …

C++斯特林數在C++中的數學理論與計算實現1

一、 斯特林數概述 1.1 組合數學中的核心地位 斯特林數(Stirling Numbers)是組合數學中連接排列、組合與分劃問題的核心工具,分為兩類: 第一類斯特林數(Stirling Numbers of the First Kind)&#xff1a…

[C++] STL大家族之<map>(字典)容器(附洛谷)

map-目錄 使用方法頭文件與聲明定義基本操作 使用方法 頭文件與聲明定義 頭文件是: #include <map>我們這樣聲明一個字典: map</*key_type*/, /*value_type*/> /*map_name*/; // 例子: map<int, char> mp;這里稍作解釋: key_type是你每個鍵值對中的鍵的…

使用 Flutter 在 Windows 平臺開發 Android 應用

以下是完整的開發流程&#xff0c;包括環境搭建、代碼實現和應用發布&#xff0c;幫助你開發一個具有地圖顯示、TCP 通信功能的 Android 應用。 一、環境搭建 1. 安裝 Flutter SDK 從 Flutter 官網 下載最新穩定版 SDK解壓到本地目錄&#xff08;如 D:\flutter&#xff09;添…

【模板】埃拉托色尼篩法(埃氏篩)

一、算法簡介 在數論與編程競賽中&#xff0c;求解 [ 1 , n ] [1,n] [1,n] 范圍內的所有質數是常見的基礎問題。埃拉托色尼篩法&#xff08;Sieve of Eratosthenes&#xff09; 是一種古老而高效的算法&#xff0c;可以在 O ( n log ? log ? n ) O(n \log \log n) O(nlogl…

AI Agent實戰 - LangChain+Playwright構建火車票查詢Agent

本篇文章將帶你一步步構建一個智能火車票查詢 Agent&#xff1a;你只需要輸入自然語言指令&#xff0c;例如&#xff1a; “幫我查一下6月15號從上海到南京的火車票” Agent就能自動理解你的需求并使用 Playwright 打開 12306 官網查詢前 10 條車次信息&#xff0c;然后匯總結果…

RabbitMQ的交換機和隊列概念

&#x1f3ea; 場景&#xff1a;一個外賣平臺的后臺系統 假設你開了一家在線外賣平臺&#xff1a; 飯店是消息的生產者&#xff08;Producer&#xff09;顧客是消息的消費者&#xff08;Consumer&#xff09;你開的外賣平臺就是RabbitMQ消息系統 &#x1f501; 第一部分&…

德國馬克斯·普朗克數學研究所:幾何朗蘭茲猜想

2025年科學突破獎 4月5日在美國洛杉磯揭曉&#xff1a;數學突破獎&#xff1a;德國馬克斯普朗克數學研究所&#xff1a;幾何朗蘭茲猜想 德國馬克斯普朗克數學研究所&#xff08;Max Planck Institute for Mathematics, MPIM&#xff09;在幾何朗蘭茲猜想的研究中扮演了核心角色…

TerraFE 腳手架開發實戰系列(一):項目架構設計與技術選型

TerraFE 腳手架開發實戰系列&#xff08;一&#xff09;&#xff1a;項目架構設計與技術選型 前言 在前端開發中&#xff0c;項目初始化往往是一個重復且繁瑣的過程。每次新建項目都需要配置 webpack、安裝依賴、設置目錄結構等&#xff0c;這些重復性工作不僅浪費時間&#…

準確--CentOS 7.9在線安裝docker

一、安裝Docker前的準備工作 操作系統版本為CentOS 7.9&#xff0c;內核版本需要在3.10以上。確保能夠連通互聯網&#xff0c;為避免網絡異常&#xff0c;建議關閉Linux的防火墻&#xff08;生產環境下請根據實際情況設置防火墻出入站規則&#xff09;。 # 查看內核版本 sudo…

中興B860AV1.1強力降級固件包

中興B860AV1.1強力降級固件包 關于中興b860av1.1頑固盒子降級教程終極版 將附件解壓好以后&#xff0c;準備一個8G以下的U盤重新格式化為FAT32格式后&#xff0c;并插入電腦 將以下文件及文件夾一同復制到優盤主目錄下&#xff08;見下圖&#xff09; 全選并復制到U盤主目錄下&…

nacos-作為注冊中心與springcloud整合(三)

前一篇文章nacos-簡介和初體驗&#xff08;一&#xff09;我們已經在服務器部署了nacos應用了。 在另外一篇文章中nacos-作為配置中心與springcloud整合&#xff08;二&#xff09;已經作為配置中心整合到springcloud 接下來讓我們嘗試把nacos作為注冊中心和springcloud中整合&…

Seata的TC(事務協調器)高可用如何實現?

Seata的TC&#xff08;事務協調器&#xff09;確實運行在Seata服務進程中&#xff0c;其高可用實現和宕機恢復主要通過以下機制實現&#xff1a; 一、高可用架構 集群部署 多TC節點組成集群&#xff0c;通過注冊中心&#xff08;如Nacos&#xff09;實現服務發現采用Raft協議實…

Mac安裝docker desktop

一、背景 最近在學習Spring AI&#xff0c;于是在GitHub上找了個開源項目&#xff0c;個人覺得還是比較適合有Java基礎和AI基礎的同學學習的。GitHub地址如下&#xff1a; https://github.com/qifan777/dive-into-spring-ai 但是看了下運行環境需要 MySQL 8 Redis-Stack n…

【算法深練】二分答案:從「猜答案」到「精準求解」的解題思路

目錄 前言 二分求最小值 1283. 使結果不超過閾值的最小除數 2187. 完成旅途的最少時間 1011. 在 D 天內送達包裹的能力 875. 愛吃香蕉的珂珂 3296. 移山所需的最少秒數 475. 供暖器 2594. 修車的最少時間 1482. 制作 m 束花所需的最少天數 3048. 標記所有下標的最早秒…

基于RK3588,飛凌教育品牌推出嵌入式人工智能實驗箱EDU-AIoT ELF 2

在AIoT技術驅動產業變革的浪潮中&#xff0c;嵌入式人工智能已成為工業物聯網、智慧交通、智慧醫療等領域創新突破的關鍵引擎。飛凌嵌入式教育品牌ElfBoard立足產業前沿&#xff0c;重磅推出嵌入式人工智能實驗箱EDU-AIoT ELF 2&#xff0c;以“軟硬協同、產教融合”為設計理念…