PyTorch學習(1):張量(Tensor)核心操作詳解

PyTorch學習(1):張量(Tensor)核心操作詳解

一、張量(Tensor)核心操作詳解

張量是PyTorch的基礎數據結構,類似于NumPy的ndarray,但支持GPU加速和自動微分。

1. 張量創建與基礎屬性
import torch# 創建張量
a = torch.tensor([1, 2, 3])  # 從列表中創建
print(a)
b = torch.zeros(2, 3)   # 2*3零矩陣
print(b)
c = torch.ones_like(b)   # 與b同形的全1矩陣
print(c)
d = torch.rand(3, 4)  # 3*4隨機矩陣
print(d)
e = torch.arange(0, 10, 2)  # [0,2,4,6,8]
print(e)# 關鍵屬性查看
print(f"形狀: {d.shape}")  # torch.Size([3, 4])
print(f"數據類型:{d.dtype}")  # torch.float32
print(f"存儲設備: {d.device}") # cpu 或 cuda:0

2. 張量運算與廣播機制
x = torch.tensor([[1, 2], [3, 4]])
y = torch.tensor([[5], [6]])
print(x)
print(y)# 基本計算
add =x + y   # 廣播加法:[[6,7], [9,10]]
mul =x * 2   # 標量乘法:[[2,4], [6,8]]
print(add)
print(mul)# 高級運算
sum_x =torch.sum(x,dim=0)  # 沿列求和:[4,6]
max_val,max_idx=torch.max(x,dim=1) # 每行最大值和索引
exp_x =torch.exp(x)  # 指數運算
print(sum_x)
print(max_val,max_idx)
print(exp_x)

3. 形狀操作與內存管理
z = torch.arange(12)
print(z)# 形狀變換(不復制數據)
z_view =z.view(3,4)  # 視圖變形,3*4矩陣
print(z_view)
z_reshape = z.reshape(2,6)
print(z_reshape)# 內部復制
z_clone = z.clone()  # 顯性復制數據
z_transpone =z_view.T # 轉置(共享數據)
print(z_clone)
print(z_transpone)# 維度操作
print(f"原始形狀:{z.shape}")
unsqueezed = z.unsqueeze(0) # 增加維度:形狀從(12,)變成(1,12)
print(f"增加維度后的形狀:{unsqueezed.shape}")
print(unsqueezed)squeezed = unsqueezed.squeeze(0) # 壓縮維度:shape(12)
print(f"壓縮維度后的形狀:{squeezed.shape}")

4. 與NumPy互操作
import numpy as np# Tensor → NumPy
tensor = torch.rand(2,3)
print (tensor)
numpy_array = tensor.numpy() # 共享內存(CPU張量)
print (numpy_array)# NumPy → Tensor
np_arr = np.array([[1,2],[3,4]])
print (np_arr)
new_tensor = torch.from_numpy(np_arr)  # 共享內存
print (new_tensor)# 顯式內存復制
safe_tensor = torch.tensor(np_arr)
print (safe_tensor)

5、檢查設備

# 檢測GPU可用性
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

二、動態計算圖與自動微分(Autograd)

1. 計算圖基本原理

PyTorch使用動態計算圖,運算時實時構建計算圖,示例1:

# 創建需要跟蹤梯度的張量
x = torch.tensor(2.0,requires_grad=True)
print(x)# 定義一個簡單的函數 y = x^2
y = x ** 2# 計算 y 關于 x 的梯度
y.backward()  # 執行反向傳播# 查看梯度值 dy/dx = 2x = 2*2 = 4
print(x.grad)  # 輸出: tensor(4.)

  1. torch.tensor(2.0)
    創建一個值為 2.0 的標量張量(即單元素張量),數據類型默認是torch.float32

  2. requires_grad=True
    這是一個關鍵參數,它告訴 PyTorch 需要跟蹤這個張量的所有操作,以便之后進行自動求導。設置為True后,PyTorch 會構建一個計算圖,記錄所有依賴于x的操作,從而在需要時通過反向傳播(backpropagation)自動計算梯度。

在這個例子中,由于xrequires_grad=True,PyTorch 記錄了y = x2的計算過程,并在調用y.backward()時自動計算了梯度dy/dx,結果存儲在x.grad中。

為什么需要這樣做?

在深度學習中,梯度是優化模型參數的關鍵。例如,在神經網絡訓練時,我們需要計算損失函數對模型參數的梯度,以便使用梯度下降等優化算法更新參數。通過將requires_grad設置為True,PyTorch 會自動記錄所有對該張量的操作,從而在調用backward()方法時計算梯度。

這種自動計算梯度的能力是深度學習框架(如 PyTorch、TensorFlow)的核心優勢之一,它讓我們無需手動推導復雜模型的導數公式,就能高效訓練神經網絡。

PyTorch使用動態計算圖,運算時實時構建計算圖,示例2:

# 創建需要跟蹤梯度的張量
x = torch.tensor(2.0, requires_grad=True)
# 定義一個函數 y = x**3 + 2*x + 1
y = x**3 + 2*x + 1
# 再進行函數
z = torch.sin(y)z.backward()  # 反向傳播自動計算梯度print(x.grad)  # dz/dx = dz/dy * dy/dx = cos(y)*(3x2+2)

2. 梯度計算模式

這是更靈活的顯式梯度計算方式,適用于復雜場景

# 示例:計算偏導數
u = torch.tensor(1.0, requires_grad=True)
v = torch.tensor(2.0, requires_grad=True)
f = u**2 + 3*v# 計算梯度
grads = torch.autograd.grad(f, [u, v])  # (df/du, df/dv)
print(grads)  # (tensor(2.), tensor(3.))
  • requires_grad=True?告訴 PyTorch 跟蹤這些張量的所有操作,以便后續計算梯度。
  • \(u = 1.0\)?和?\(v = 2.0\)?是初始值,用于計算梯度的具體數值。

定義了一個二元函數?\(f(u, v) = u^2 + 3v\)。在深度學習中,這類似一個損失函數,我們需要計算它對參數的梯度。


?

核心區別
操作用途結果存儲適用場景
z.backward()計算?z?對所有?requires_grad=True?的葉子節點張量的梯度,并累積到?.grad?屬性中。梯度存儲在葉子節點的?.grad?屬性中。標準的反向傳播(如訓練神經網絡)。
torch.autograd.grad(f, [u, v])顯式計算?f?對指定張量?[u, v]?的梯度,返回梯度張量組成的元組。梯度作為元組直接返回,不修改原有張量。需要自定義梯度計算路徑(如多輸出模型)
3. 梯度控制技巧
import torch
import torch.optim as optim# 初始化參數
x = torch.tensor(2.0, requires_grad=True)
w = torch.tensor(3.0, requires_grad=True)
b = torch.tensor(1.0, requires_grad=True)# 創建優化器
optimizer = optim.SGD([x, w, b], lr=0.01)# 1. 梯度累積清零
optimizer.zero_grad()  # 訓練循環中必須的操作
print(f"初始梯度 x.grad: {x.grad}")  # 輸出: None# 前向傳播
y = x * w + b
loss = (y - 10)**2  # 假設目標值為10# 反向傳播
loss.backward()
print(f"第一次反向傳播后 x.grad: {x.grad}")  # 輸出: tensor(12.)# 再次反向傳播(梯度會累積)
loss.backward()
print(f"第二次反向傳播后 x.grad: {x.grad}")  # 輸出: tensor(24.)# 梯度清零
optimizer.zero_grad()
print(f"optimizer.zero_grad() 后 x.grad: {x.grad}")  # 輸出: tensor(0.)# 2. 凍結梯度
with torch.no_grad():z = x * 2  # 不會追蹤計算歷史
print(f"z.requires_grad: {z.requires_grad}")  # 輸出: False# 3. 分離計算圖
a = x * w
detached = a.detach()  # 創建無梯度關聯的副本
print(f"detached.requires_grad: {detached.requires_grad}")  # 輸出: False# 4. 修改requires_grad
x.requires_grad_(False)  # 關閉梯度追蹤
print(f"修改后 x.requires_grad: {x.requires_grad}")  # 輸出: False# 驗證修改后的效果
try:y = x ** 2y.backward()  # 會報錯,因為x.requires_grad=False
except RuntimeError as e:print(f"錯誤: {e}")  # 輸出: element 0 of tensors does not require grad and does not have a grad_fn
總結對比表

optimizer.zero_grad()  # 訓練循環中必須的操作
torch.no_grad() # 梯度清零
操作作用范圍是否影響原張量是否釋放內存典型場景
optimizer.zero_grad()優化器管理的所有參數是(梯度清零)每個訓練迭代前
torch.no_grad()上下文內的所有計算推理階段、無需梯度的計算
a.detach()單個張量否(創建新張量)截斷梯度流、固定部分網絡
x.requires_grad_(False)單個張量是(原地修改)凍結預訓練模型參數
代碼說明:
  1. 梯度累積清零

    • 兩次調用?loss.backward()?會累積梯度
    • optimizer.zero_grad()?將梯度重置為零
  2. 凍結梯度

    • with torch.no_grad()?塊內的計算不會追蹤梯度
    • 輸出張量?z?的?requires_grad?為?False
  3. 分離計算圖

    • a.detach()?創建與計算圖分離的新張量
    • 修改分離后的張量不會影響原梯度計算
  4. 修改 requires_grad

    • x.requires_grad_(False)?原地修改張量屬性
    • 后續嘗試對?x?進行反向傳播會報錯
注意事項:
  • 實際訓練中,optimizer.zero_grad()?應在每個訓練迭代開始時調用
  • torch.no_grad()?常用于推理階段以提高性能
  • detach()?適用于需要固定部分網絡參數的場景
  • 修改?requires_grad?是永久性的,需謹慎操作
4. 梯度檢查(調試技巧)
import torch
def grad_check():x = torch.tensor(3.0, requires_grad=True)y = x ** 2# 理論梯度y.backward()analytic_grad = x.grad.item()# 數值梯度(修正:使用 x.item() 而非硬編碼 3.0)eps = 1e-5y1 = (x.item() + eps) ** 2y2 = (x.item() - eps) ** 2numeric_grad = (y1 - y2) / (2 * eps)print(f"解析梯度: {analytic_grad:.6f}, 數值梯度: {numeric_grad:.6f}")assert abs(analytic_grad - numeric_grad) < 1e-6# 調用函數
grad_check()

這段代碼實現了一個簡單的 ** 梯度驗證(Gradient Check)** 功能,用于驗證 PyTorch 自動微分計算的梯度是否與數值計算的梯度一致。

1. 定義測試函數和輸入
x = torch.tensor(3.0, requires_grad=True)
y = x ** 2
2. 計算解析梯度(Analytical Gradient)
y.backward()
analytic_grad = x.grad.item()

3. 計算數值梯度(Numerical Gradient)
eps = 1e-5
y1 = (x.item() + eps) ** 2
y2 = (x.item() - eps) ** 2
numeric_grad = (y1 - y2) / (2 * eps)

4. 驗證結果

print(f"解析梯度: {analytic_grad:.6f}, 數值梯度: {numeric_grad:.6f}")
assert abs(analytic_grad - numeric_grad) < 1e-6

打印結果:解析梯度: 6.000000, 數值梯度: 6.000000

關鍵知識點

  1. 自動微分(Autograd): PyTorch 通過跟蹤計算圖自動計算梯度,無需手動推導公式。

  2. 數值微分: 數值方法是驗證梯度計算正確性的重要工具,但計算效率低,僅用于測試。

  3. 梯度驗證的重要性: 在實現復雜模型(如自定義層或損失函數)時,梯度驗證能幫助發現反向傳播中的錯誤。

潛在問題與改進

  1. 步長?\(\epsilon\)?的選擇: 太小會導致數值誤差(如浮點數舍入),太大會降低近似精度。

  2. 多維張量支持: 當前代碼僅支持標量輸入,擴展到多維張量需為每個元素計算數值梯度。

  3. 高階導數驗證: 對于二階或更高階導數,需使用更復雜的數值方法。

這個簡單的驗證函數是深度學習開發中的重要調試工具,特別是在實現自定義操作或優化算法時。

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

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

相關文章

Docker部署Spark大數據組件:配置log4j日志

上一篇《Docker部署Spark大數據組件》中&#xff0c;日志是輸出到console的&#xff0c;如果有將日志輸出到文件的需要&#xff0c;需要進一步配置。 配置將日志同時輸出到console和file 1、停止spark集群 docker-compose down -v 2、使用自帶log4j日志配置模板配置 cp -f …

Nginx Lua模塊(OpenResty)實戰:動態化、智能化你的Nginx,實現復雜Web邏輯 (2025)

更多服務器知識&#xff0c;盡在hostol.com 嘿&#xff0c;各位Nginx的“鐵桿粉絲”和“配置大師”們&#xff01;咱們都知道&#xff0c;Nginx以其超凡的性能、穩定性和豐富的模塊化功能&#xff0c;在Web服務器、反向代理、負載均衡等領域獨步青云&#xff0c;簡直是服務器軟…

一、CentOS7通過kubeadm安裝K8S 1.20.1版本

一、準備機器 所有節點執行 準備3臺虛擬機&#xff08;2核4G&#xff0c;CentOS 7&#xff09;&#xff0c;配置如下&#xff1a; hostnamectl set-hostname k8s-master # 在Master節點執行 hostnamectl set-hostname k8s-node1 # Worker1節點執行 hostnamectl set-hostna…

AgenticSeek,開源本地通用AI Agent,自主執行任務

AgenticSeek是一款完全本地化的開源AI助手&#xff0c;作為Manus的開源替代品&#xff0c;專為保護用戶隱私而設計。它能夠在本地設備上執行多種任務&#xff0c;包括網頁瀏覽、代碼編寫和復雜項目的規劃&#xff0c;確保所有操作和數據均在用戶的設備上完成。 AgenticSeek是什…

C 語言學習筆記(指針6)

內容提要 內存操作 內存操作的函數 內存操作 我們對于內存操作需要依賴于string.h頭文件中相關的庫函數。 內存的庫函數 內存填充 頭文件&#xff1a;#include <string.h>函數原型 void* memset(void* s, int c, size_t)函數功能&#xff1a;將內存塊s的前n個字節…

Grafana-Gauge儀表盤

儀表盤是一種單值可視化。 可讓您快速直觀地查看某個值落在定義的或計算出的最小和最大范圍內的位置。 通過重復選項&#xff0c;您可以顯示多個儀表盤&#xff0c;每個對應不同的序列、列或行。 支持的數據格式 單值 數據集中只有一個值&#xff0c;會生成一個顯示數值的…

解決Vue項目依賴錯誤:使用electron-vite重建

文章目錄 開端解決方案&#xff1a;使用 electron-vite Vue 重建項目1. 環境準備2. 創建新項目3. 安裝依賴并啟動項目 開端 在開發過程中&#xff0c;我遇到了一個令人頭疼的錯誤提示&#xff1a; 0:0 error Parsing error: Cannot find module vue/cli-plugin-babel/preset…

WPF prism

Prism Prism.Dryloc 包 安裝 Nuget 包 - Prism.DryIoc 1. 修改 App.xaml 修改 App.xaml 文件&#xff0c;添加 prism 命名空間, 繼承由 Application → PrismApplication&#xff0c;刪除默認啟動 url, StartupUri“MainWindow.xaml” <dryioc:PrismApplicationx:Class…

循序漸進PersistentVolumes與PersistentVolumeClaim

文章目錄 靜態配置&#xff08;Static Provisioning&#xff09;&#xff1a;Persistent volume(PV)Local 示例&#xff1a;NFS 示例&#xff1a;檢查pvPV 的常見狀態說明Persistent volume claim(PVC)1. local PVC示例:2.NFS PVC示例:3. 檢查PVC: 掛載靜態供應卷驗證靜態供應卷…

【連接器專題】SD卡座規格書審查需要審哪些方面?

在審查SD卡座規格書時,我們需要考慮哪些方面? 首先在拿到一份SD卡座的詳細規格書時,一般供應商給到的規格書中包括了一些基礎信息、產品圖紙信息、技術參數信息,同時有些供應商會給出產品可靠性測試報告。因此我們會從這幾個要素去看規格書。 基礎信息 基礎信息一般會給變更…

投稿 IEEE Transactions on Knowledge and Data Engineering 注意事項

投稿 IEEE Transactions on Knowledge and Data Engineering 注意事項 要IEEE overleaf 模板私信,我直接給我自己論文,便于編輯 已經投稿完成了,有一些小坑 準備工作 注冊IEEE賬戶:若沒有IEEE賬戶,需前往IEEE官網注冊。注冊成功后,可用于登錄投稿系統。現在新的系統,…

JS入門——三種輸入方式

JS入門——三種輸入方式 一、方式一&#xff1a;直接在警告框彈出(window可以省略) <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script><!-- 方式一直接在警告框彈…

WordPress免費網站模板下載

大背景圖免費wordpress建站模板 這個wordpress模板設計以簡約和專業為主題&#xff0c;旨在為用戶提供清晰、直觀的瀏覽體驗。以下是對其風格、布局和設計理念的詳細介紹&#xff1a; 風格 簡約現代&#xff1a;整體設計采用簡約風格&#xff0c;使用了大量的白色和灰色調&am…

AUTOSAR CP全新系統化培訓上線!從底層到應用,三步階梯,五大學習維度構建完整知識體系

AUTOSAR組織 AUTOSAR官方全新推出「AUTOSAR CP全棧賦能計劃」&#xff0c;從架構全景到模塊細節&#xff0c;自底向上、由淺入深&#xff0c;覆蓋MCAL至SWC全層級&#xff0c;融合通信、診斷、安全等六大核心Feature&#xff0c;帶您穿透復雜理論&#xff0c;直擊AUTOSAR開發本…

Java網絡編程與Socket安全權限詳解

Socket安全權限控制 Java通過java.net.SocketPermission類實現對網絡套接字訪問的細粒度控制。該權限管理機制通常在Java策略文件中配置,其標準授權語法格式如下: grant {permission java.net.SocketPermission"target", "actions"; };目標主機與端口規…

基于本地化大模型的智能編程助手全棧實踐:從模型部署到IDE深度集成學習心得

近年來&#xff0c;隨著ChatGPT、Copilot等AI編程工具的爆發式增長&#xff0c;開發者生產力獲得了前所未有的提升。然而&#xff0c;云服務的延遲、隱私顧慮及API調用成本促使我探索一種更自主可控的方案&#xff1a;基于開源大模型構建本地化智能編程助手。本文將分享我構建本…

視頻監控匯聚平臺EasyCVR安防小知識:如何通過視頻融合平臺解決信息孤島問題?

一、項目背景與需求分析? 隨著數字化技術發展與網絡帶寬升級&#xff0c;視頻技術應用場景不斷拓展&#xff0c;視頻監控、記錄儀等多樣化產品構建起龐大體系。但這些獨立系統彼此割裂&#xff0c;形成信息孤島。 在系統集成項目中&#xff0c;視頻系統深度融合已成必然趨勢…

如何在 Windows 和 Mac 上擦拭和清潔希捷外置硬盤

希捷外置硬盤廣泛用于存儲目的&#xff0c;但有時您可能出于多種目的需要擦除或清潔希捷外置硬盤&#xff0c;例如轉售、重復使用、捐贈等。為了釋放硬盤上的存儲空間或確保沒有人可以從硬盤中恢復您的信息&#xff0c;擦除硬盤是必要的步驟。無論您使用的是 Windows 還是 Mac&…

SAP saml2 元數據 HTTP 錯誤

使?事務 SAML2 或 SAML2_IDP 在 ABAP 系統中配置 SAML 2.0 時&#xff0c; Web 頁?返回 403 已禁?、 404 未找到 或 500 服務器內部錯誤。 在事務 SAML2 中下載元數據時&#xff0c; ?頁返回 403 已禁?、 404 未找到或 500 服務器內部錯誤。 在事務 SAML2_IDP 中下載…

powershell 中 invoke-expression 報錯解決

打開powershell就出現這個報錯&#xff1a; 網上搜了也沒有很好的解決辦法&#xff0c;抱著一點點期待&#xff0c;問了豆包 根據豆包的指示&#xff0c;在終端執行以下 幾個命令&#xff0c;報錯解決了&#xff08;開心萬歲&#xff09; # 移除多余的引號和空路徑 $pathArra…