Langchain系列文章目錄
01-玩轉LangChain:從模型調用到Prompt模板與輸出解析的完整指南
02-玩轉 LangChain Memory 模塊:四種記憶類型詳解及應用場景全覆蓋
03-全面掌握 LangChain:從核心鏈條構建到動態任務分配的實戰指南
04-玩轉 LangChain:從文檔加載到高效問答系統構建的全程實戰
05-玩轉 LangChain:深度評估問答系統的三種高效方法(示例生成、手動評估與LLM輔助評估)
06-從 0 到 1 掌握 LangChain Agents:自定義工具 + LLM 打造智能工作流!
07-【深度解析】從GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
PyTorch系列文章目錄
機器學習系列文章目錄
深度學習系列文章目錄
01-【深度學習-Day 1】為什么深度學習是未來?一探究竟AI、ML、DL關系與應用
02-【深度學習-Day 2】圖解線性代數:從標量到張量,理解深度學習的數據表示與運算
文章目錄
- Langchain系列文章目錄
- PyTorch系列文章目錄
- 機器學習系列文章目錄
- 深度學習系列文章目錄
- 前言
- 一、數據在深度學習中的表示:從標量到張量
- 1.1 標量 (Scalar)
- 1.1.1 什么是標量?
- 1.1.2 深度學習中的標量示例
- 1.1.3 Python 表示
- 1.2 向量 (Vector)
- 1.2.1 什么是向量?
- 1.2.2 深度學習中的向量示例
- 1.2.3 Python (NumPy) 表示
- 1.3 矩陣 (Matrix)
- 1.3.1 什么是矩陣?
- 1.3.2 深度學習中的矩陣示例
- 1.3.3 Python (NumPy) 表示
- 1.4 張量 (Tensor)
- 1.4.1 什么是張量?
- 1.4.2 深度學習中的張量示例
- 1.4.3 Python (NumPy/Frameworks) 表示
- 二、線性代數核心運算
- 2.1 基本元素級運算 (Element-wise Operations)
- 2.1.1 加法與減法 (Addition & Subtraction)
- 2.1.2 標量乘法 (Scalar Multiplication)
- 2.1.3 哈達瑪積 (Hadamard Product / Element-wise Product)
- 2.2 轉置 (Transpose)
- 2.2.1 向量轉置 (Vector Transpose)
- 2.2.2 矩陣轉置 (Matrix Transpose)
- 2.3 點積/內積 (Dot Product / Inner Product) 與 矩陣乘法 (Matrix Multiplication)
- 2.3.1 向量點積 (Vector Dot Product)
- 2.3.2 矩陣乘法 (Matrix Multiplication)
- 三、實踐:NumPy 實現
- 四、常見問題與提示
- 4.1 維度不匹配 (Dimension Mismatch)
- 4.2 區分哈達瑪積與矩陣乘法
- 4.3 理解張量的軸 (Understanding Tensor Axes)
- 五、總結
前言
大家好!歡迎來到深度學習系列博客的第二篇。在上一篇中,我們初步了解了深度學習是什么以及它的重要性。從今天開始,我們將深入學習構建深度學習模型所必需的基礎知識。而其中,線性代數扮演著至關重要的角色。
你可能會問:“為什么需要線性代數?” 簡單來說,深度學習本質上是對數據進行一系列復雜的變換和計算。而線性代數正是描述和操作這些數據(通常以數組形式存在)的強大數學語言。無論是輸入數據(如圖像像素、文本詞語)、模型參數(權重和偏置),還是中間計算結果,都可以用線性代數中的概念(向量、矩陣、張量)來表示。理解線性代數的核心概念和運算,是你看懂模型原理、高效實現算法、甚至排查錯誤的關鍵。
本篇文章將聚焦于深度學習中最常用、最核心的線性代數知識點,力求用通俗易懂的語言和實例,幫助你掃清障礙,為后續學習打下堅實基礎。我們將涵蓋:
- 數據表示:標量、向量、矩陣、張量是什么,它們如何表示深度學習中的數據?
- 核心運算:加減法、標量乘法、轉置、點積、矩陣乘法等基本操作及其意義。
- 實踐應用:如何使用強大的 Python 庫 NumPy 來執行這些運算。
不必擔心復雜的證明和推導,我們的目標是理解概念并知道如何在實踐中運用它們。讓我們一起開始吧!
一、數據在深度學習中的表示:從標量到張量
在深度學習的世界里,我們處理的所有信息,無論是圖像、文本、聲音還是表格數據,最終都需要轉化為機器能夠理解和處理的數字形式。線性代數提供了一套優雅而高效的結構來組織這些數字。
1.1 標量 (Scalar)
1.1.1 什么是標量?
標量是最簡單的數據結構,它就是一個單獨的數字。可以把它想象成一個零維的數組。
1.1.2 深度學習中的標量示例
- 損失值 (Loss Value): 在模型訓練中,衡量模型預測與真實值差距的損失函數通常輸出一個標量值。
- 學習率 (Learning Rate): 控制模型參數更新幅度的超參數,是一個標量。
- 樣本標簽 (某些情況): 對于回歸任務,單個樣本的標簽可能是一個標量(例如預測房價)。
- 偏置項 (Bias): 神經網絡層中的偏置通常是一個標量(雖然實踐中為了廣播機制,常表示為向量或更高維張量)。
1.1.3 Python 表示
在 Python 中,標量通常用基本的數字類型 int
或 float
表示。
# 標量示例
learning_rate = 0.001
loss = 0.54
integer_scalar = 10print(f"Type of learning_rate: {type(learning_rate)}")
print(f"Type of integer_scalar: {type(integer_scalar)}")
1.2 向量 (Vector)
1.2.1 什么是向量?
向量是一組有序排列的數字,可以看作是一個一維數組。它有方向和大小。在線性代數中,向量通常默認指列向量(一列多行),但有時也表示為行向量(一行多列)。
1.2.2 深度學習中的向量示例
- 特征向量 (Feature Vector): 一個數據樣本(如用戶、圖片)的多個特征可以用一個向量表示。例如,一個用戶的特征向量可能包含年齡、性別(編碼后)、購買次數等
[25, 1, 15]
。 - 詞嵌入 (Word Embedding): 在自然語言處理中,每個詞可以被表示為一個稠密的數值向量,捕捉其語義信息。
- 神經網絡的輸出 (某些情況): 對于多分類任務,模型最后一層(Softmax之前)的輸出通常是一個向量,每個元素代表對應類別的得分。
- 偏置向量 (Bias Vector): 神經網絡層中的偏置項,通常表示為一個向量,其長度等于該層神經元的數量。
1.2.3 Python (NumPy) 表示
我們通常使用 NumPy 庫來創建和操作向量。
import numpy as np# 創建一個行向量 (實際上NumPy創建的是一維數組,沒有嚴格區分行列)
feature_vector = np.array([25, 1, 15])
print(f"Feature Vector (1D array): {feature_vector}")
print(f"Shape: {feature_vector.shape}") # 輸出 (3,) 表示一維,3個元素# 可以顯式創建行向量 (1xN 矩陣)
row_vector = np.array([[25, 1, 15]])
print(f"Row Vector (2D array): {row_vector}")
print(f"Shape: {row_vector.shape}") # 輸出 (1, 3)# 創建列向量 (Nx1 矩陣)
column_vector = np.array([[25], [1], [15]])
print(f"Column Vector (2D array): \n{column_vector}")
print(f"Shape: {column_vector.shape}") # 輸出 (3, 1)
注意: NumPy 的一維數組在進行某些運算(如矩陣乘法)時,會根據上下文自動判斷是行向量還是列向量,這有時會帶來便利,但也可能導致混淆。在嚴格的數學表達中,區分行向量和列向量很重要。
1.3 矩陣 (Matrix)
1.3.1 什么是矩陣?
矩陣是一個二維數組,由數字排列成的矩形網格構成,包含行 (rows) 和列 (columns)。一個矩陣的大小由其行數和列數定義,例如一個 m × n m \times n m×n 矩陣有 m m m 行 n n n 列。
1.3.2 深度學習中的矩陣示例
- 灰度圖像: 一個灰度圖像可以表示為一個矩陣,每個元素代表對應像素的亮度值(例如 0-255)。
- 數據批次 (Batch of Data): 在訓練時,我們通常一次處理一小批數據。如果每個數據樣本是一個特征向量,那么一個批次的數據就可以表示為一個矩陣,其中每一行是一個樣本的特征向量。
- 權重矩陣 (Weight Matrix): 神經網絡中連接兩層的權重通常組織成一個矩陣。如果輸入層有 n n n 個神經元,輸出層有 m m m 個神經元,那么它們之間的權重可以表示為一個 m × n m \times n m×n 或 n × m n \times m n×m 的矩陣(取決于約定)。
- 混淆矩陣 (Confusion Matrix): 用于評估分類模型性能,顯示預測類別與真實類別的對應關系。
1.3.3 Python (NumPy) 表示
import numpy as np# 創建一個 3x2 的矩陣 (3 行 2 列)
matrix_A = np.array([[1, 2],[3, 4],[5, 6]])
print(f"Matrix A:\n{matrix_A}")
print(f"Shape: {matrix_A.shape}") # 輸出 (3, 2)# 模擬一個數據批次,假設有 2 個樣本,每個樣本有 4 個特征
data_batch = np.array([[0.1, 0.5, -0.2, 1.0],[-0.4, 0.8, 0.0, 0.3]])
print(f"\nData Batch:\n{data_batch}")
print(f"Shape: {data_batch.shape}") # 輸出 (2, 4)
1.4 張量 (Tensor)
1.4.1 什么是張量?
張量是線性代數中數據結構的一般化形式,可以看作是多維數組。它是標量、向量、矩陣的自然擴展:
- 0 階張量 (0D Tensor): 標量 (Scalar)
- 1 階張量 (1D Tensor): 向量 (Vector)
- 2 階張量 (2D Tensor): 矩陣 (Matrix)
- 3 階及以上張量 (nD Tensor): 高維數組
張量的“階” (rank) 或“維數” (number of dimensions/axes) 指的是其索引的數量。例如,一個 3 階張量需要 3 個索引來定位其中的一個元素,如 T i j k T_{ijk} Tijk?。
1.4.2 深度學習中的張量示例
張量是深度學習框架(如 TensorFlow, PyTorch)處理數據的標準方式。
- 彩色圖像: 一張彩色圖像通常表示為 3 階張量,維度通常是 (高度, 寬度, 通道數)。例如,一張 256x256 像素的 RGB 圖像可以表示為 ( 256 , 256 , 3 ) (256, 256, 3) (256,256,3) 的張量。
- 圖像批次: 一批彩色圖像則是一個 4 階張量,維度通常是 (批次大小, 高度, 寬度, 通道數)。例如,一批 32 張 256x256 的 RGB 圖像是 ( 32 , 256 , 256 , 3 ) (32, 256, 256, 3) (32,256,256,3) 的張量。
- 視頻數據: 可以表示為 5 階張量 (批次大小, 幀數, 高度, 寬度, 通道數)。
- 自然語言處理 (NLP): 一批句子(每個句子由詞嵌入向量序列組成)可以表示為 3 階張量 (批次大小, 序列長度, 嵌入維度)。
- 循環神經網絡 (RNN) 的隱藏狀態: 隨時間步變化的隱藏狀態序列也可以用張量表示。
1.4.3 Python (NumPy/Frameworks) 表示
NumPy 以及深度學習框架都原生支持張量操作。
import numpy as np# 創建一個 3 階張量 (例如,模擬一個 2x3x2 的張量)
tensor_3d = np.array([[[1, 2], [3, 4], [5, 6]],[[7, 8], [9, 10], [11, 12]]])
print(f"3D Tensor:\n{tensor_3d}")
print(f"Shape: {tensor_3d.shape}") # 輸出 (2, 3, 2)
print(f"Number of dimensions (rank): {tensor_3d.ndim}") # 輸出 3# 訪問元素
print(f"Element at index (0, 1, 1): {tensor_3d[0, 1, 1]}") # 輸出 4
理解這些基本的數據結構是進行后續線性代數運算和理解深度學習模型的基礎。
二、線性代數核心運算
掌握了數據的表示方法后,下一步就是了解如何對這些數據進行運算。這些運算構成了深度學習模型中信息流動和轉換的基礎。
2.1 基本元素級運算 (Element-wise Operations)
元素級運算指的是對兩個具有相同形狀的張量(向量、矩陣或更高維張量)的對應元素執行某種運算,生成一個形狀完全相同的結果張量。
2.1.1 加法與減法 (Addition & Subtraction)
- 規則: 兩個張量必須具有完全相同的形狀。對應位置的元素進行相加或相減。
- 公式: 若 C = A + B C = A + B C=A+B, 則 C i j = A i j + B i j C_{ij} = A_{ij} + B_{ij} Cij?=Aij?+Bij?。減法同理。
- 應用: 融合信息(如殘差連接 ResNet 中的 X + F ( X ) X + F(X) X+F(X)),調整數值。
import numpy as npA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 加法
C_add = A + B
print(f"A + B:\n{C_add}")
# 輸出:
# [[ 6 8]
# [10 12]]# 減法
C_sub = A - B
print(f"\nA - B:\n{C_sub}")
# 輸出:
# [[-4 -4]
# [-4 -4]]# 形狀不同會報錯
# C = np.array([1, 2])
# try:
# A + C
# except ValueError as e:
# print(f"\nError when adding A and C: {e}")
2.1.2 標量乘法 (Scalar Multiplication)
- 規則: 將一個標量與一個張量(向量、矩陣等)相乘。張量中的每個元素都乘以該標量。結果張量的形狀與原張量相同。
- 公式: 若 C = s × A C = s \times A C=s×A, 則 C i j = s × A i j C_{ij} = s \times A_{ij} Cij?=s×Aij?。
- 應用: 縮放數值(如調整梯度、應用學習率)。
import numpy as npA = np.array([[1, 2], [3, 4]])
scalar = 10C_scalar_mul = scalar * A # 或者 A * scalar
print(f"scalar * A:\n{C_scalar_mul}")
# 輸出:
# [[10 20]
# [30 40]]
2.1.3 哈達瑪積 (Hadamard Product / Element-wise Product)
- 規則: 對兩個相同形狀的張量,將對應位置的元素相乘。結果張量的形狀也相同。注意:這與后面要講的矩陣乘法完全不同!
- 公式: 若 C = A ⊙ B C = A \odot B C=A⊙B, 則 C i j = A i j × B i j C_{ij} = A_{ij} \times B_{ij} Cij?=Aij?×Bij?。
- 應用: 在某些神經網絡結構中用于門控機制(如 LSTM 中的門計算),或者對特征進行加權。
import numpy as npA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 哈達瑪積 (在 NumPy 中使用 * 運算符)
C_hadamard = A * B
print(f"A * B (Hadamard Product):\n{C_hadamard}")
# 輸出:
# [[ 5 12]
# [21 32]]
關鍵區分: 在 NumPy 中,*
運算符默認執行的是元素級乘法(哈達瑪積)。
2.2 轉置 (Transpose)
轉置是一種重要的矩陣操作,它將矩陣的行和列進行互換。
2.2.1 向量轉置 (Vector Transpose)
- 將行向量轉換為列向量,或將列向量轉換為行向量。
- 對于 NumPy 的一維數組,
.T
屬性對其本身沒有效果,因為它沒有嚴格的行列區分。需要先將其視為二維數組(矩陣)。
import numpy as np# NumPy 一維數組
vec = np.array([1, 2, 3])
print(f"Original vec shape: {vec.shape}, Transposed vec.T: {vec.T}, Shape: {vec.T.shape}")
# 輸出: Original vec shape: (3,), Transposed vec.T: [1 2 3], Shape: (3,)# 顯式創建行向量 (1xN 矩陣)
row_vec = np.array([[1, 2, 3]]) # Shape (1, 3)
col_vec = row_vec.T
print(f"\nRow vector shape: {row_vec.shape}")
print(f"Transposed to column vector:\n{col_vec}")
print(f"Column vector shape: {col_vec.shape}") # Shape (3, 1)
2.2.2 矩陣轉置 (Matrix Transpose)
- 規則: 將矩陣 A A A 的第 i i i 行變成結果矩陣 A T A^T AT 的第 i i i 列,或者說將 A A A 的第 j j j 列變成 A T A^T AT 的第 j j j 行。如果 A A A 是一個 m × n m \times n m×n 矩陣,那么它的轉置 A T A^T AT 是一個 n × m n \times m n×m 矩陣。
- 公式: ( A T ) i j = A j i (A^T)_{ij} = A_{ji} (AT)ij?=Aji?。
- 應用: 改變矩陣維度以滿足乘法要求,某些數學推導和公式表達,數據重塑。
import numpy as npA = np.array([[1, 2, 3],[4, 5, 6]]) # Shape (2, 3)A_T = A.T
print(f"Original Matrix A (shape {A.shape}):\n{A}")
print(f"\nTransposed Matrix A_T (shape {A_T.shape}):\n{A_T}")
# 輸出:
# Original Matrix A (shape (2, 3)):
# [[1 2 3]
# [4 5 6]]
#
# Transposed Matrix A_T (shape (3, 2)):
# [[1 4]
# [2 5]
# [3 6]]
2.3 點積/內積 (Dot Product / Inner Product) 與 矩陣乘法 (Matrix Multiplication)
點積和矩陣乘法是線性代數中極其重要的運算,是神經網絡中信息傳遞和轉換的核心。
2.3.1 向量點積 (Vector Dot Product)
- 規則: 兩個長度相同的向量 a \mathbf{a} a 和 b \mathbf{b} b 的點積,是它們對應元素的乘積之和。結果是一個標量。
- 公式: a ? b = ∑ i = 1 n a i b i = a 1 b 1 + a 2 b 2 + ? + a n b n \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1 b_1 + a_2 b_2 + \dots + a_n b_n a?b=i=1∑n?ai?bi?=a1?b1?+a2?b2?+?+an?bn?
- 幾何意義 (初步了解): 點積可以衡量兩個向量的相似性或對齊程度。如果兩個向量方向大致相同,點積為正且較大;如果方向相反,點積為負;如果相互垂直,點積為 0。它也與向量投影有關。
- 應用: 計算加權和(神經網絡神經元的計算核心之一),衡量向量相似度,計算向量長度(向量與其自身的點積的平方根)。
import numpy as npa = np.array([1, 2, 3])
b = np.array([4, 5, 6])# 計算點積
dot_product = np.dot(a, b)
# 或者使用 @ 運算符 (Python 3.5+)
# dot_product_at = a @ b
print(f"Dot product of a and b: {dot_product}")
# 輸出: Dot product of a and b: 32 (1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32)
2.3.2 矩陣乘法 (Matrix Multiplication)
- 規則: 兩個矩陣 A A A (形狀 m × n m \times n m×n) 和 B B B (形狀 n × p n \times p n×p) 的乘積 C = A B C = AB C=AB 是一個 m × p m \times p m×p 的矩陣。 C C C 中的每個元素 C i j C_{ij} Cij? 是 A A A 的第 i i i 行與 B B B 的第 j j j 列的點積。
- 維度兼容性: 要進行矩陣乘法 A B AB AB,第一個矩陣 A A A 的列數 ( n n n) 必須等于第二個矩陣 B B B 的行數 ( n n n)。
- 公式: C i j = ∑ k = 1 n A i k B k j C_{ij} = \sum_{k=1}^{n} A_{ik} B_{kj} Cij?=k=1∑n?Aik?Bkj?
- 重要特性: 矩陣乘法不滿足交換律,即 A B ≠ B A AB \neq BA AB=BA (除非在特殊情況下)。
- 應用: 線性變換(旋轉、縮放、投影),神經網絡中的層與層之間的計算(輸入通過權重矩陣變換得到輸出),狀態轉移。
import numpy as npA = np.array([[1, 2],[3, 4]]) # Shape (2, 2)
B = np.array([[5, 6, 7],[8, 9, 10]]) # Shape (2, 3)# 矩陣乘法 C = AB
# A的列數(2) == B的行數(2),可以相乘
# 結果 C 的形狀是 (A的行數, B的列數) = (2, 3)
C_matmul = np.dot(A, B)
# 或者使用 @ 運算符
# C_matmul_at = A @ Bprint(f"Matrix A (shape {A.shape}):\n{A}")
print(f"Matrix B (shape {B.shape}):\n{B}")
print(f"\nMatrix Multiplication C = AB (shape {C_matmul.shape}):\n{C_matmul}")
# 輸出:
# Matrix A (shape (2, 2)):
# [[1 2]
# [3 4]]
# Matrix B (shape (2, 3)):
# [[ 5 6 7]
# [ 8 9 10]]
#
# Matrix Multiplication C = AB (shape (2, 3)):
# [[21 24 27] # C[0,0] = A[0,:] dot B[:,0] = [1,2] dot [5,8] = 1*5+2*8=21
# [47 54 61]] # C[1,0] = A[1,:] dot B[:,0] = [3,4] dot [5,8] = 3*5+4*8=47
# ...以此類推計算其他元素
我們可以用一個簡單的圖示來說明矩陣乘法中元素的計算過程:
graph LRsubgraph Matrix A (m x n)direction TBA_row_i("Row i: [A<sub>i1</sub>, A<sub>i2</sub>, ..., A<sub>in</sub>]")endsubgraph Matrix B (n x p)direction TBB_col_j("Column j: <br>[B<sub>1j</sub>]<br>[B<sub>2j</sub>]<br>...<br>[B<sub>nj</sub>]")endsubgraph Result Matrix C (m x p)C_ij("Element C<sub>ij</sub>")endA_row_i -- 點積 (Dot Product) --> C_ij;B_col_j -- 點積 (Dot Product) --> C_ij;note for C_ij "$$C_{ij} = A_{i1}B_{1j} + A_{i2}B_{2j} + \dots + A_{in}B_{nj} = \sum_{k=1}^{n} A_{ik}B_{kj}$$"
掌握這些核心運算是理解神經網絡如何處理信息的關鍵一步。
三、實踐:NumPy 實現
理論學習固然重要,但動手實踐更能加深理解。Python 的 NumPy 庫是進行科學計算,特別是線性代數運算的標準庫。下面我們用 NumPy 來實踐前面介紹的概念和運算。
import numpy as np# 確保前面的導入已執行print("--- 3.1 創建標量、向量、矩陣、張量 ---")
# 標量 (雖然 NumPy 中通常用 0 維數組表示,但直接用 Python 類型更常見)
scalar_val = 10
print(f"Scalar: {scalar_val}, Type: {type(scalar_val)}")# 向量 (1D Array)
vector_v = np.array([1.0, 2.5, -3.0])
print(f"\nVector v: {vector_v}")
print(f"Shape: {vector_v.shape}") # (3,)# 矩陣 (2D Array)
matrix_M = np.array([[1, 2, 3],[4, 5, 6]])
print(f"\nMatrix M:\n{matrix_M}")
print(f"Shape: {matrix_M.shape}") # (2, 3)# 張量 (3D Array)
tensor_T = np.arange(12).reshape((2, 3, 2)) # 創建一個 0 到 11 的數組,并重塑為 2x3x2
print(f"\nTensor T:\n{tensor_T}")
print(f"Shape: {tensor_T.shape}") # (2, 3, 2)print("\n--- 3.2 執行基本運算 ---")# 準備用于運算的矩陣 (確保形狀兼容)
A = np.array([[1, 0], [-1, 2]]) # Shape (2, 2)
B = np.array([[3, -2], [1, 4]]) # Shape (2, 2)
C = np.array([[5], [6]]) # Shape (2, 1) - 列向量
s = 2 # 標量# 元素級加法 (需要相同形狀)
print(f"\nElement-wise Addition (A + B):\n{A + B}")# 元素級減法
print(f"\nElement-wise Subtraction (A - B):\n{A - B}")# 標量乘法
print(f"\nScalar Multiplication (s * A):\n{s * A}")# 哈達瑪積 (元素級乘法)
print(f"\nHadamard Product (A * B):\n{A * B}")# 矩陣轉置
print(f"\nMatrix Transpose (A.T):\n{A.T}")
print(f"Shape of A: {A.shape}, Shape of A.T: {A.T.shape}") # (2, 2) -> (2, 2)
print(f"\nMatrix Transpose (C.T):\n{C.T}")
print(f"Shape of C: {C.shape}, Shape of C.T: {C.T.shape}") # (2, 1) -> (1, 2)# 向量點積 (需要長度相同)
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
print(f"\nVector Dot Product (v1 . v2): {np.dot(v1, v2)}") # 32
# 或者 v1 @ v2# 矩陣乘法 (需要內維匹配)
# A(2x2) @ B(2x2) -> (2x2)
print(f"\nMatrix Multiplication (A @ B):\n{A @ B}") # 使用 @ 運算符
# 或者 np.dot(A, B)# A(2x2) @ C(2x1) -> (2x1)
print(f"\nMatrix Multiplication (A @ C):\n{A @ C}")# 嘗試不兼容的乘法 B(2x2) @ C.T(1x2) -> 會報錯
try:B @ C.T
except ValueError as e:print(f"\nError multiplying B(2x2) and C.T(1x2): {e}")# C.T(1x2) @ A(2x2) -> (1x2)
print(f"\nMatrix Multiplication (C.T @ A):\n{C.T @ A}")
這段代碼演示了如何在 NumPy 中輕松地創建和操作這些線性代數對象。熟練使用 NumPy 是進行深度學習實踐的基礎。
四、常見問題與提示
在學習和應用線性代數,特別是在編程實現時,新手常常會遇到一些問題。這里列舉幾個常見點:
4.1 維度不匹配 (Dimension Mismatch)
- 問題: 這是最常見的錯誤之一,尤其是在進行矩陣乘法和元素級運算時。例如,試圖將一個 3 × 2 3 \times 2 3×2 矩陣和一個 3 × 3 3 \times 3 3×3 矩陣進行元素級相加,或者將一個 2 × 3 2 \times 3 2×3 矩陣和一個 2 × 2 2 \times 2 2×2 矩陣進行矩陣乘法,都會導致維度不匹配錯誤。
- 排查建議:
- 在進行運算前,務必使用
print(matrix.shape)
檢查參與運算的張量的形狀。 - 牢記矩陣乘法 A B AB AB 的要求: A A A 的列數必須等于 B B B 的行數。
- 牢記元素級運算的要求:參與運算的張量必須具有完全相同的形狀(或者滿足廣播機制,后續文章會介紹)。
- 仔細閱讀報錯信息,它通常會明確指出哪個操作在哪一步維度不匹配。
- 在進行運算前,務必使用
4.2 區分哈達瑪積與矩陣乘法
- 問題: 初學者容易混淆元素級乘法(哈達瑪積)和矩陣乘法,尤其是在 NumPy 中,它們對應不同的運算符。
- 排查建議:
- 哈達瑪積 (Element-wise): 使用
*
運算符。要求兩個張量形狀相同。 - 矩陣乘法 (Dot Product): 使用
@
運算符 (Python 3.5+) 或np.dot()
函數。要求內維匹配。 - 明確你的計算意圖:你是想讓對應元素相乘,還是想進行標準的線性變換?根據意圖選擇正確的運算。
- 哈達瑪積 (Element-wise): 使用
4.3 理解張量的軸 (Understanding Tensor Axes)
- 問題: 當處理三維或更高維張量時,理解每個軸(維度)代表什么變得至關重要,尤其是在進行求和、取最大值、轉置等操作時指定
axis
參數。 - 提示:
- 通常,深度學習中張量的軸有約定俗成的含義,例如圖像的
(batch, height, width, channels)
或 NLP 中的(batch, sequence_length, embedding_dim)
。 - 在調用 NumPy 或框架函數時,注意
axis
參數的用法。例如,np.sum(tensor, axis=0)
會沿著第一個軸(通常是批次維度)求和。 - 多打印中間結果的形狀 (
.shape
) 來確認操作是否符合預期。
- 通常,深度學習中張量的軸有約定俗成的含義,例如圖像的
五、總結
恭喜你完成了深度學習數學基礎的第一部分——線性代數核心!回顧一下本篇的主要內容:
- 數據表示的重要性: 線性代數是深度學習中表示和操作數據的通用語言。標量、向量、矩陣和張量是構建模型和處理信息的基本數據結構。
- 核心數據結構:
- 標量 (Scalar): 單個數值 (0D)。
- 向量 (Vector): 一維有序數組 (1D),用于表示特征、詞嵌入等。
- 矩陣 (Matrix): 二維數組 (2D),用于表示圖像、數據批次、權重等。
- 張量 (Tensor): 多維數組 (nD),是前三者的推廣,深度學習框架中的標準數據格式。
- 關鍵運算:
- 元素級運算 (加、減、哈達瑪積): 對相同形狀張量的對應元素進行操作。
- 標量乘法: 用標量縮放張量中的每個元素。
- 轉置: 交換矩陣的行和列 ( A T A^T AT)。
- 點積/內積: 向量運算,結果為標量,衡量相似度。
- 矩陣乘法: 核心運算,實現線性變換,是神經網絡信息傳遞的關鍵,注意維度匹配和不可交換性。
- NumPy 實踐: NumPy 提供了高效實現這些線性代數運算的工具,熟練使用 NumPy 是深度學習編程的基礎。
- 關鍵提示: 注意維度匹配、區分哈達瑪積與矩陣乘法、理解張量軸是避免常見錯誤的關鍵。
線性代數構成了深度學習算法的骨架。雖然我們沒有深入探討所有理論細節,但理解這些核心概念和運算對于你閱讀后續內容、理解模型工作原理以及動手實踐至關重要。
在下一篇文章 【深度學習-Day 3】必備數學(二) - 微積分關鍵 中,我們將探討另一個數學基石——微積分,特別是導數、偏導數和鏈式法則,它們是理解模型如何“學習”(優化參數)的關鍵。敬請期待!