1深度学习

线性代数

深度学习的数学基础

矩阵向量特征值SVD

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第1章:线性代数(Linear Algebra)

一、导读

1.1 本章学习目标

第1章是《深度学习》的数学基础开篇,为后续所有章节提供必要的线性代数工具。深度学习本质上是在高维空间中进行大量的数值运算,而线性代数正是描述和操作这些高维数据的核心语言。本章不是传统线性代数课程的完整复述,而是聚焦于深度学习中最高频使用的概念和运算。

本章的核心学习目标包括:

  • 掌握标量、向量、矩阵和张量的定义与运算:理解这些基本数据结构在深度学习中的角色
  • 理解矩阵乘法的本质:不仅是数值计算,更是线性变换的几何表达
  • 掌握特征值分解和奇异值分解(SVD):理解矩阵的内在结构和降维原理
  • 理解范数的概念和作用:学会用范数度量向量的"大小"和"距离"
  • 掌握线性相关性和秩的概念:理解数据的信息冗余和有效维度
  • 了解特殊矩阵和特殊运算:如正交矩阵、迹、行列式等在深度学习中的应用

1.2 为什么本章如此重要

很多读者急于进入神经网络的实际构建,觉得数学基础章节"太枯燥"或"不重要"。这种想法是极其危险的。深度学习的每一个核心操作——前向传播、反向传播、损失计算、梯度更新——都建立在线性代数运算之上。

具体来说:

  • 数据表示:一张图片是一个三维张量(高×宽×通道),一段文本是一个二维矩阵(序列长度×词向量维度)
  • 模型参数:神经网络的权重几乎都是矩阵形式存储和运算的
  • 前向传播:每一层的计算本质上就是矩阵乘法加上非线性变换
  • 反向传播:链式法则的每一步都涉及矩阵的转置和乘法

不理解线性代数,就无法真正理解深度学习模型在做什么。你只能机械地调用API,而无法调试问题、改进模型或设计新架构。

1.3 核心问题引导

在阅读本章时,请带着以下问题思考:

为什么深度学习中的数据几乎都用矩阵和张量表示?这种表示有什么优势?

矩阵乘法的几何意义是什么?它如何改变向量的空间?

特征值分解揭示了矩阵的什么本质信息?为什么它在降维中如此重要?

为什么我们需要多种范数(L1、L2、L∞)?它们各自适用于什么场景?

矩阵的秩如何反映数据的有效信息量?低秩矩阵有什么特殊性质?

奇异值分解(SVD)与特征值分解有什么区别?为什么SVD更通用?


二、核心概念详解

2.1 标量、向量、矩阵和张量

2.1.1 基本定义

线性代数中最基本的对象有四种层级:

标量(Scalar):单个数值,是零阶张量。在深度学习中通常表示学习率、损失值、正则化系数等。

python
import numpy as np

learning_rate = 0.001  # 标量
loss = 0.523           # 标量

向量(Vector):一维有序数组,是一阶张量。在深度学习中表示单个样本的特征、词向量、隐藏层激活值等。

python
x = np.array([1.0, 2.0, 3.0])  # 3维向量
embedding = np.random.randn(300)  # 300维词向量

矩阵(Matrix):二维有序数组,是二阶张量。在深度学习中表示一批样本的数据集、权重矩阵、注意力分数矩阵等。

python
W = np.random.randn(256, 128)  # 权重矩阵:256个输入特征 -> 128个输出特征
batch = np.random.randn(32, 784)  # 一批32个样本,每个784维

张量(Tensor):n维有序数组,是标量、向量、矩阵的推广。在深度学习中,几乎所有数据都以张量形式存在。

python
image = np.random.randn(3, 224, 224)  # 3通道224x224的图像张量
video = np.random.randn(16, 3, 224, 224)  # 16帧视频张量

2.1.2 向量的运算

向量的基本运算包括加法、数乘和内积:

python
import numpy as np

a = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])

# 向量加法
c = a + b  # [5.0, 7.0, 9.0]

# 数乘
d = 2.0 * a  # [2.0, 4.0, 6.0]

# 内积(点积)
dot_product = np.dot(a, b)  # 1*4 + 2*5 + 3*6 = 32.0

# 外积
outer_product = np.outer(a, b)
# [[ 4,  5,  6],
#  [ 8, 10, 12],
#  [12, 15, 18]]

内积的几何意义:两个向量的内积等于它们的模长乘以夹角余弦。内积衡量了两个向量的"相似程度"——内积越大,方向越接近。在深度学习中,注意力机制的核心就是计算query和key的内积。

python
cosine_similarity = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

2.1.3 矩阵的运算

矩阵运算中最重要的是矩阵乘法。设 A 是 m×n 矩阵,B 是 n×p 矩阵,则 C = AB 是 m×p 矩阵:

python
A = np.random.randn(3, 4)  # 3x4 矩阵
B = np.random.randn(4, 5)  # 4x5 矩阵
C = np.dot(A, B)           # 3x5 矩阵

# 等价写法
C = A @ B

矩阵乘法的几何意义:矩阵乘法是对向量空间的线性变换。一个 2×2 矩阵可以将二维平面上的点进行旋转、缩放、剪切等变换。

python
import matplotlib.pyplot as plt

# 旋转矩阵
theta = np.pi / 4  # 旋转45度
R = np.array([
    [np.cos(theta), -np.sin(theta)],
    [np.sin(theta),  np.cos(theta)]
])

# 原始点集
points = np.array([[1, 0], [0, 1], [1, 1], [-1, 0]])

# 变换后的点
transformed = points @ R.T

2.1.4 常见误区

误区一:矩阵乘法满足交换律

矩阵乘法不满足交换律,即 AB ≠ BA。这在深度学习中有重要含义:层的顺序很重要,交换层的顺序会完全改变模型的行为。

误区二:矩阵乘法就是逐元素相乘

矩阵乘法是行与列的内积运算,而不是逐元素相乘。逐元素相乘称为Hadamard积,在深度学习中用于门控机制(如LSTM的门控)。

python
# 矩阵乘法
C = A @ B  # 行与列的内积

# Hadamard积(逐元素相乘)
D = A * B  # 逐元素相乘,要求A和B形状相同

2.2 单位矩阵与逆矩阵

2.2.1 单位矩阵

单位矩阵 I_n 是 n×n 的对角矩阵,对角线元素为1,其余为0。任何矩阵乘以单位矩阵都等于自身:

python
I = np.eye(3)
A = np.array([[1, 2], [3, 4]])

# A @ I = A(需要维度匹配)
A_I = A @ np.eye(2)

在深度学习中,单位矩阵常用于正则化项(如权重衰减中的 L2 正则化)和初始化。

2.2.2 逆矩阵

如果矩阵 A 存在逆矩阵 A^(-1),则 A·A^(-1) = A^(-1)·A = I。只有方阵且行列式不为零的矩阵才有逆矩阵。

python
A = np.array([[1, 2], [3, 4]])
A_inv = np.linalg.inv(A)

# 验证
identity = A @ A_inv
print(np.allclose(identity, np.eye(2)))  # True

在深度学习中的应用:直接求逆在深度学习中很少使用,因为计算代价太高(O(n³))。但在某些特殊场景下会用到,如高斯过程的精确推断、线性系统的求解等。

2.3 线性相关性与秩

2.3.1 线性组合与线性相关

一组向量的线性组合是它们的标量倍数的和:

python
v1 = np.array([1, 0])
v2 = np.array([0, 1])
v3 = np.array([1, 1])

# v3 是 v1 和 v2 的线性组合
# v3 = 1*v1 + 1*v2

如果一组向量中至少有一个可以表示为其他向量的线性组合,则这组向量是线性相关的。线性相关意味着存在信息冗余。

python
# 线性相关的例子
v1 = np.array([1, 2, 3])
v2 = np.array([2, 4, 6])  # v2 = 2*v1,线性相关

# 判断线性相关性
matrix = np.column_stack([v1, v2])
rank = np.linalg.matrix_rank(matrix)
print(f"秩: {rank}")  # 1,说明两个向量线性相关

2.3.2 矩阵的秩

矩阵的秩(rank)是矩阵中线性无关的行(或列)向量的最大数目。秩反映了矩阵所包含的"有效信息量"。

python
A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
rank = np.linalg.matrix_rank(A)
print(f"矩阵A的秩: {rank}")  # 2

# 第三行 = 第一行 + 第二行,所以秩为2

在深度学习中的意义:

  • 权重矩阵的秩反映了该层能够表达的不同特征的数量
  • 数据矩阵的秩反映了数据的有效维度
  • 低秩近似用于模型压缩和降维

2.4 范数

2.4.1 Lp 范数

范数(norm)用于度量向量的"大小"。Lp 范数的定义为:

‖x‖_p = (Σ|x_i|^p)^(1/p)
python
x = np.array([3.0, 4.0])

# L1 范数(曼哈顿距离)
l1_norm = np.sum(np.abs(x))  # |3| + |4| = 7.0

# L2 范数(欧几里得距离)
l2_norm = np.linalg.norm(x)  # sqrt(9 + 16) = 5.0

# L∞ 范数(最大绝对值)
linf_norm = np.max(np.abs(x))  # max(3, 4) = 4.0

2.4.2 范数在深度学习中的应用

L1 正则化(Lasso):产生稀疏解,用于特征选择。

python
# L1 正则化损失
def l1_regularized_loss(w, X, y, lambda_l1):
    predictions = X @ w
    mse = np.mean((predictions - y) ** 2)
    l1_penalty = lambda_l1 * np.sum(np.abs(w))
    return mse + l1_penalty

L2 正则化(Ridge/权重衰减):防止权重过大,提高泛化能力。

python
# L2 正则化损失
def l2_regularized_loss(w, X, y, lambda_l2):
    predictions = X @ w
    mse = np.mean((predictions - y) ** 2)
    l2_penalty = lambda_l2 * np.sum(w ** 2)
    return mse + l2_penalty

Frobenius 范数:矩阵的范数,常用于正则化权重矩阵。

python
W = np.random.randn(10, 20)
frob_norm = np.linalg.norm(W, 'fro')
# 等价于 sqrt(sum(W_ij^2))

2.5 特征值分解

2.5.1 特征值与特征向量

对于方阵 A,如果存在非零向量 v 和标量 λ 使得:

Av = λv

则 v 是 A 的特征向量,λ 是对应的特征值。特征向量是在矩阵变换下方向不变的向量,特征值是该方向上的缩放因子。

python
A = np.array([[4, 1],
              [2, 3]])

eigenvalues, eigenvectors = np.linalg.eig(A)

print("特征值:", eigenvalues)        # [5., 2.]
print("特征向量:\n", eigenvectors)   # 每列是一个特征向量

2.5.2 特征值分解

如果矩阵 A 有 n 个线性无关的特征向量,则 A 可以分解为:

A = QΛQ^(-1)

其中 Q 的列是特征向量,Λ 是对角矩阵,对角元素是特征值。

python
# 特征值分解
eigenvalues, Q = np.linalg.eig(A)
Lambda = np.diag(eigenvalues)
Q_inv = np.linalg.inv(Q)

# 重构
A_reconstructed = Q @ Lambda @ Q_inv
print(np.allclose(A, A_reconstructed))  # True

2.5.3 在深度学习中的应用

PCA 降维:主成分分析通过特征值分解找到数据方差最大的方向。

python
# PCA 降维示例
X = np.random.randn(100, 10)  # 100个样本,10维特征

# 中心化
X_centered = X - np.mean(X, axis=0)

# 协方差矩阵
cov_matrix = X_centered.T @ X_centered / (X.shape[0] - 1)

# 特征值分解
eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)

# 取前2个主成分
top2_eigenvectors = eigenvectors[:, -2:]  # 最大的2个特征值对应的特征向量

# 降维
X_pca = X_centered @ top2_eigenvectors  # 100x2

2.6 奇异值分解(SVD)

2.6.1 SVD 的定义

SVD 是特征值分解的推广,适用于任意形状的矩阵(不限于方阵)。对于 m×n 矩阵 A:

A = UΣV^T

其中 U 是 m×m 正交矩阵,Σ 是 m×n 对角矩阵(对角元素为奇异值),V 是 n×n 正交矩阵。

python
A = np.random.randn(5, 3)

U, sigma, Vt = np.linalg.svd(A, full_matrices=False)

print("U 的形状:", U.shape)      # (5, 3)
print("sigma:", sigma)            # 奇异值
print("Vt 的形状:", Vt.shape)     # (3, 3)

# 重构
Sigma = np.diag(sigma)
A_reconstructed = U @ Sigma @ Vt
print(np.allclose(A, A_reconstructed))  # True

2.6.2 SVD 的几何意义

SVD 将矩阵变换分解为三个步骤:

V^T:在输入空间中进行旋转/反射

Σ:在每个轴上进行缩放

U:在输出空间中进行旋转/反射

2.6.3 低秩近似

SVD 最重要的应用之一是低秩近似。只保留前 k 个最大的奇异值,可以得到原矩阵的最佳 k 秩近似:

python
# 低秩近似
k = 2
U_k = U[:, :k]
sigma_k = sigma[:k]
Vt_k = Vt[:k, :]
Sigma_k = np.diag(sigma_k)

A_k = U_k @ Sigma_k @ Vt_k
print(f"秩-{k} 近似的误差: {np.linalg.norm(A - A_k, 'fro')}")

在深度学习中的应用:

  • 模型压缩:用低秩矩阵近似权重矩阵,减少参数量
  • 去噪:保留主要成分,去除噪声
  • 推荐系统:矩阵分解的核心算法

2.7 特殊矩阵与运算

2.7.1 正交矩阵

正交矩阵 Q 满足 Q^T·Q = Q·Q^T = I。正交矩阵的列向量两两正交且模为1。正交变换保持向量的长度和角度不变。

python
# 旋转矩阵是正交矩阵
theta = np.pi / 6
Q = np.array([
    [np.cos(theta), -np.sin(theta)],
    [np.sin(theta),  np.cos(theta)]
])

print(np.allclose(Q.T @ Q, np.eye(2)))  # True

2.7.2 对称矩阵

对称矩阵 A 满足 A = A^T。对称矩阵的特征值都是实数,特征向量可以选为正交的。协方差矩阵、Hessian 矩阵都是对称矩阵。

python
# 协方差矩阵是对称矩阵
X = np.random.randn(50, 5)
cov = np.cov(X.T)
print(np.allclose(cov, cov.T))  # True

2.7.3 迹(Trace)

矩阵的迹是对角线元素之和:

python
A = np.array([[1, 2], [3, 4]])
trace_A = np.trace(A)  # 1 + 4 = 5

# 迹等于特征值之和
eigenvalues = np.linalg.eigvals(A)
print(np.sum(eigenvalues))  # 约等于 5

在深度学习中的应用:迹运算常用于简化梯度计算和损失函数的表达。

2.7.4 行列式(Determinant)

行列式反映了矩阵变换对空间的缩放因子。

python
A = np.array([[1, 2], [3, 4]])
det_A = np.linalg.det(A)  # 1*4 - 2*3 = -2

# |det(A)| > 1: 变换扩大面积
# |det(A)| < 1: 变换缩小面积
# det(A) = 0: 矩阵奇异,将空间压缩到更低维度

三、实战案例

3.1 案例一:图像压缩的SVD实现

python
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def svd_image_compression(image_path, k_values=[5, 20, 50, 100]):
    # 读取图像并转为灰度
    img = Image.open(image_path).convert('L')
    img_array = np.array(img, dtype=float)
    
    # SVD 分解
    U, sigma, Vt = np.linalg.svd(img_array, full_matrices=False)
    
    fig, axes = plt.subplots(2, 3, figsize=(15, 10))
    
    # 原始图像
    axes[0, 0].imshow(img_array, cmap='gray')
    axes[0, 0].set_title(f'原始图像\n{img_array.shape[0]}x{img_array.shape[1]}')
    axes[0, 0].axis('off')
    
    for idx, k in enumerate(k_values):
        row, col = (idx + 1) // 3, (idx + 1) % 3
        
        # 低秩近似
        img_compressed = U[:, :k] @ np.diag(sigma[:k]) @ Vt[:k, :]
        
        # 计算压缩比
        original_size = img_array.size
        compressed_size = k * (img_array.shape[0] + img_array.shape[1] + 1)
        ratio = compressed_size / original_size * 100
        
        # 计算误差
        error = np.linalg.norm(img_array - img_compressed, 'fro')
        relative_error = error / np.linalg.norm(img_array, 'fro') * 100
        
        axes[row, col].imshow(img_compressed, cmap='gray')
        axes[row, col].set_title(f'k={k}\n压缩比: {ratio:.1f}%\n相对误差: {relative_error:.2f}%')
        axes[row, col].axis('off')
    
    plt.tight_layout()
    plt.savefig('svd_compression.png', dpi=150)
    plt.show()
    
    return U, sigma, Vt

# 使用示例(假设有一张测试图片)
# 生成一个测试图像
test_image = np.zeros((100, 100))
for i in range(100):
    for j in range(100):
        test_image[i, j] = np.sin(i * 0.1) * np.cos(j * 0.1) * 128 + 128

# 保存为临时文件
Image.fromarray(test_image.astype(np.uint8)).save('/tmp/test_image.png')

# 运行压缩
U, sigma, Vt = svd_image_compression('/tmp/test_image.png')

# 分析奇异值分布
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(sigma, 'bo-')
plt.xlabel('奇异值索引')
plt.ylabel('奇异值大小')
plt.title('奇异值衰减曲线')

plt.subplot(1, 2, 2)
cumulative_energy = np.cumsum(sigma ** 2) / np.sum(sigma ** 2)
plt.plot(cumulative_energy, 'ro-')
plt.xlabel('奇异值索引')
plt.ylabel('累积能量占比')
plt.title('奇异值累积能量')
plt.axhline(y=0.99, color='g', linestyle='--', label='99%能量')
plt.legend()
plt.tight_layout()
plt.savefig('singular_value_analysis.png', dpi=150)
plt.show()

代码解析:

  • SVD将图像矩阵分解为三个矩阵的乘积
  • 保留前k个最大奇异值,可以大幅压缩数据量
  • 奇异值衰减越快,用较少成分就能保留大部分信息
  • 压缩比和重建误差之间存在权衡

3.2 案例二:PCA降维可视化

python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification

def pca_visualization():
    # 生成高维数据
    X, y = make_classification(
        n_samples=300, n_features=10, n_informative=3,
        n_redundant=2, n_classes=3, random_state=42
    )
    
    # 中心化
    X_centered = X - np.mean(X, axis=0)
    
    # 协方差矩阵
    cov_matrix = X_centered.T @ X_centered / (X.shape[0] - 1)
    
    # 特征值分解
    eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)
    
    # 按特征值从大到小排序
    sorted_idx = np.argsort(eigenvalues)[::-1]
    eigenvalues = eigenvalues[sorted_idx]
    eigenvectors = eigenvectors[:, sorted_idx]
    
    # 取前2个主成分
    top2_components = eigenvectors[:, :2]
    
    # 投影到2D
    X_pca = X_centered @ top2_components
    
    # 可视化
    plt.figure(figsize=(15, 5))
    
    # 原始数据的前两个特征
    plt.subplot(1, 3, 1)
    scatter = plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis', alpha=0.7)
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.title('原始特征 (Feature 1 vs 2)')
    plt.colorbar(scatter)
    
    # PCA降维结果
    plt.subplot(1, 3, 2)
    scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis', alpha=0.7)
    plt.xlabel('PC 1')
    plt.ylabel('PC 2')
    plt.title('PCA 降维 (PC1 vs PC2)')
    plt.colorbar(scatter)
    
    # 特征值分布
    plt.subplot(1, 3, 3)
    explained_variance_ratio = eigenvalues / np.sum(eigenvalues)
    plt.bar(range(1, 11), explained_variance_ratio, alpha=0.7)
    plt.xlabel('主成分')
    plt.ylabel('方差解释比')
    plt.title('各主成分的方差解释比')
    plt.axhline(y=1/10, color='r', linestyle='--', label='均匀分布')
    plt.legend()
    
    plt.tight_layout()
    plt.savefig('pca_visualization.png', dpi=150)
    plt.show()
    
    # 打印分析结果
    cumulative = np.cumsum(explained_variance_ratio)
    print(f"前2个主成分解释了 {cumulative[1]*100:.1f}% 的方差")
    print(f"前3个主成分解释了 {cumulative[2]*100:.1f}% 的方差")

pca_visualization()

代码解析:

  • PCA通过特征值分解找到数据方差最大的方向
  • 前两个主成分通常能保留大部分可分性信息
  • 特征值的大小反映了对应主成分的重要性

3.3 案例三:权重矩阵的低秩近似

python
import numpy as np

def low_rank_weight_approximation():
    """模拟神经网络权重矩阵的低秩近似"""
    
    # 模拟一个全连接层的权重矩阵
    input_dim = 512
    output_dim = 256
    W = np.random.randn(output_dim, input_dim) * 0.01
    
    # 原始参数量
    original_params = W.size
    print(f"原始参数量: {original_params:,}")
    
    # 不同秩的近似
    ranks = [10, 25, 50, 100, 128]
    
    print(f"\n{'秩':>6} | {'参数量':>10} | {'压缩比':>8} | {'相对误差':>10}")
    print("-" * 50)
    
    for k in ranks:
        # SVD 分解
        U, sigma, Vt = np.linalg.svd(W, full_matrices=False)
        
        # 低秩近似
        W_k = U[:, :k] @ np.diag(sigma[:k]) @ Vt[:k, :]
        
        # 参数量: U_k (output_dim × k) + sigma_k (k) + Vt_k (k × input_dim)
        compressed_params = output_dim * k + k + k * input_dim
        
        # 压缩比
        compression_ratio = compressed_params / original_params * 100
        
        # 相对误差 (Frobenius范数)
        relative_error = np.linalg.norm(W - W_k, 'fro') / np.linalg.norm(W, 'fro') * 100
        
        print(f"{k:>6} | {compressed_params:>10,} | {compression_ratio:>7.1f}% | {relative_error:>9.2f}%")

low_rank_weight_approximation()

运行结果分析:

  • 秩越低,压缩比越大,但误差也越大
  • 通常选择能保持90%以上精度的最低秩
  • 实际应用中,可以通过微调(fine-tuning)恢复部分精度损失

四、本章小结

本章系统介绍了深度学习中必需的线性代数知识:

基本数据结构:标量、向量、矩阵和张量构成了深度学习中所有数据的表示基础。理解它们的运算规则是后续学习的前提。

矩阵乘法:不仅是数值运算,更是线性变换的几何表达。理解矩阵乘法的几何意义有助于直觉地把握神经网络各层的作用。

特征值分解与SVD:揭示了矩阵的内在结构。特征值分解适用于方阵,SVD适用于任意矩阵。两者都是降维、压缩和分析的核心工具。

范数:度量向量和矩阵的"大小"。L1范数产生稀疏性,L2范数防止过拟合,Frobenius范数是矩阵正则化的标准选择。

线性相关性与秩:反映了数据的有效信息量。秩越低,信息冗余越大,可利用这一点进行压缩和加速。

特殊矩阵:正交矩阵保持距离不变,对称矩阵有良好的数学性质,迹和行列式在理论推导中频繁出现。

线性代数是深度学习的"语言"。掌握这些概念,才能在阅读论文、理解模型、调试代码时做到心中有数。后续章节中的前向传播、反向传播、注意力机制等,都将频繁使用本章介绍的工具。


五、思考与练习

思考题

为什么深度学习框架(如PyTorch、TensorFlow)中的张量运算都针对GPU进行了优化?矩阵运算在GPU上为什么比CPU快得多?

如果一个权重矩阵的秩远小于其维度,这意味着什么?能否利用这一点来设计更高效的网络结构?

L1正则化为什么能产生稀疏解?从几何角度解释L1和L2正则化的区别。

为什么协方差矩阵一定是半正定的?这个性质在深度学习中有什么应用?

SVD的低秩近似为什么是"最优"的?这里的"最优"是在什么意义下的?

编程练习

实现矩阵乘法:不使用 np.dot 或 @ 运算符,用纯Python循环实现矩阵乘法,比较与NumPy的性能差异。

PCA实现:在MNIST手写数字数据集上实现PCA降维,将784维降到2维并可视化,观察不同数字类别的分离程度。

SVD图像压缩:选择一张彩色图片,对每个通道分别进行SVD分解和压缩,找到能保持视觉质量的最小秩。

条件数分析:计算不同随机矩阵的条件数(最大奇异值/最小奇异值),理解条件数与矩阵"病态"程度的关系。

低秩权重近似:在一个简单的全连接网络上,用SVD对权重矩阵进行低秩近似,观察不同秩对模型准确率的影响。

1/10线性代数
0%