一、什麼是張量?

在PyTorch中,張量(Tensor) 是存儲和操作數據的基本單位,類似於NumPy中的數組,但支持GPU加速,並且是神經網絡計算的核心數據結構。你可以把張量想象成一個“容器”,裏面裝着數字(如整數、浮點數),並且可以對這個容器進行各種數學操作。

二、創建張量

要開始使用張量,首先需要學會創建它。PyTorch提供了多種方式創建張量,以下是最常用的幾種:

  1. 從Python列表/NumPy數組創建
    使用 torch.tensor()torch.as_tensor() 直接從數據創建:
   import torch
   import numpy as np

   # 從列表創建
   data_list = [1, 2, 3, 4]
   tensor_list = torch.tensor(data_list)  # 結果:tensor([1, 2, 3, 4])

   # 從NumPy數組創建
   np_array = np.array([1, 2, 3])
   tensor_np = torch.as_tensor(np_array)  # 結果:tensor([1, 2, 3])
  1. 使用構造函數創建
    - torch.zeros(*size):創建全0張量,size 是形狀元組(如 (2, 3) 表示2行3列)。
    - torch.ones(*size):創建全1張量。
    - torch.rand(*size):創建隨機數張量(元素在 [0, 1) 之間)。
   zeros_tensor = torch.zeros(2, 3)  # 2行3列全0
   ones_tensor = torch.ones(1, 4)    # 1行4列全1
   rand_tensor = torch.rand(3, 3)    # 3x3隨機數矩陣

三、張量的基本屬性

創建張量後,需要了解它的基本屬性以便後續操作:
- 形狀(shape):用 .shape.size() 查看,返回一個元組。
- 數據類型(dtype):用 .dtype 查看,如 torch.float32(默認)、torch.int64 等。
- 設備(device):用 .device 查看,默認是CPU,可通過 .to('cuda') 轉移到GPU。

tensor = torch.rand(2, 3)
print(tensor.shape)   # torch.Size([2, 3])
print(tensor.dtype)   # torch.float32
print(tensor.device)  # cpu

# 轉換數據類型和設備
tensor = tensor.to(torch.float64).to('cuda')  # 先轉double類型,再移到GPU

四、張量操作

張量的操作是PyTorch的核心,掌握這些操作才能靈活處理數據。

1. 算術操作

張量支持常見的算術運算,如加減乘除、取反等:
- 加法+torch.add()
- 減法-torch.sub()
- 乘法*torch.mul()(注意:矩陣乘法用 @torch.matmul()
- 除法/torch.div()

a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])

# 加法
print(a + b)        # tensor([5, 7, 9])
print(torch.add(a, b))  # 同上

# 矩陣乘法(示例:2x2 * 2x2)
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5, 6], [7, 8]])
print(a @ b)        # tensor([[19, 22], [43, 50]])
2. 索引與切片

張量的索引和切片與Python列表類似,支持多維索引:

tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])

# 取第一行(維度0)
print(tensor[0])                # tensor([1, 2, 3])
# 取第二列(維度1)
print(tensor[:, 1])             # tensor([2, 5])
# 取第1-2行、第0-1列
print(tensor[0:2, 0:2])         # tensor([[1, 2], [4, 5]])
3. 變形操作

用於調整張量的維度(保持元素總數不變):
- reshape():改變形狀,返回新張量(若形狀不合法則報錯)。
- squeeze():移除維度爲1的軸(如 (1, 3, 1)(3,))。
- unsqueeze():增加維度爲1的軸(如 (3,)(1, 3))。

tensor = torch.rand(1, 2, 1, 4)  # 形狀:(1,2,1,4)
print(tensor.shape)  # torch.Size([1, 2, 1, 4])

# 移除維度1的軸
squeezed = tensor.squeeze()  # 形狀:(2, 4)
print(squeezed.shape)  # torch.Size([2, 4])

# 增加維度爲1的軸(在維度1處插入)
unsqueezed = tensor.unsqueeze(1)  # 形狀:(1,1,2,1,4)
print(unsqueezed.shape)  # torch.Size([1, 1, 2, 1, 4])
4. 拼接與拆分
  • torch.cat():按指定維度拼接多個張量(需保持其他維度一致)。
  • torch.stack():新增一個維度拼接(需所有維度一致)。
  • torch.split() / torch.chunk():拆分張量爲多個部分。
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5, 6], [7, 8]])

# 按維度0拼接(上下合併)
cat_dim0 = torch.cat([a, b], dim=0)  # 形狀:(4, 2)
print(cat_dim0)
# 按維度1拼接(左右合併)
cat_dim1 = torch.cat([a, b], dim=1)  # 形狀:(2, 4)
print(cat_dim1)

# 拆分:按每個部分大小拆分爲2份
split_tensor = torch.cat([a, b], dim=0)
split_parts = torch.split(split_tensor, split_size_or_sections=2, dim=0)
print(split_parts)  # (tensor([[1,2],[3,4]]), tensor([[5,6],[7,8]]))

五、自動求導(Autograd)

自動求導是PyTorch實現神經網絡反向傳播的核心,用於自動計算梯度。

1. 核心概念
  • requires_grad:張量屬性,設爲 True 表示需要追蹤其梯度。
  • 計算圖:記錄張量操作的計算流程,用於反向傳播時自動計算梯度。
  • backward():對計算圖中的葉子節點調用,觸發梯度計算。
  • grad:張量的梯度屬性,僅對 requires_grad=True 的張量有效。
2. 自動求導示例

以簡單函數 y = x² 爲例,演示如何計算梯度:

# 創建需要求導的張量,requires_grad=True
x = torch.tensor(3.0, requires_grad=True)  # x=3.0,需要追蹤梯度

# 構建計算圖:y = x²
y = x ** 2  

# 反向傳播:計算梯度(y對x的導數)
y.backward()  

# 查看梯度:x.grad = dy/dx = 2x = 6
print(x.grad)  # tensor(6.)
3. 注意事項
  • 非葉子節點梯度:中間變量(非原始張量)的梯度在 backward() 後會被釋放,如需保留需用 retain_graph=True
  • 累加梯度:多次調用 backward() 時,梯度會累加,需手動清空(x.grad.zero_())。
  • detach():分離張量,阻止其繼續參與梯度計算(返回無梯度的新張量)。
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2
z = y ** 2  # 計算圖:z = (x²)² = x⁴

# 先對y求導(此時x的梯度會被計算)
y.backward()
print(x.grad)  # tensor(4.) (因爲dy/dx=2x=4,此時z未參與計算)

# 若要計算z對x的梯度,需重新反向傳播(需設置retain_graph=True保留計算圖)
z.backward(retain_graph=True)
print(x.grad)  # tensor(16.) (4+12=16,因爲grad是累加的)

六、總結

  • 張量是PyTorch數據的基本單位,支持多種創建方式和操作(算術、索引、變形等)。
  • 自動求導通過 requires_gradbackward() 實現梯度計算,是神經網絡訓練的核心。
  • 實踐中需注意張量形狀匹配、梯度累加、設備轉移等細節,多動手嘗試不同操作才能熟練掌握。

通過以上內容,你已掌握PyTorch基礎的張量操作和自動求導,爲後續學習神經網絡打下基礎!

小夜