第2篇 | AI工程师必备数学基础:线性代数核心概念
·
引言
线性代数是AI算法工程师必须掌握的基础数学工具。无论是机器学习中的数据表示,还是深度学习中的矩阵运算,线性代数都扮演着至关重要的角色。本文将介绍AI学习中最重要的线性代数概念,帮助大家打好数学基础。
一、向量:数据的表示方式
1.1 向量的基本概念
向量是线性代数的基本单位,在AI中用于表示数据样本或特征。
import numpy as np
# 创建向量
v = np.array([1, 2, 3, 4, 5])
print("向量 v:", v)
print("向量形状:", v.shape)
# 向量运算
u = np.array([2, 4, 6, 8, 10])
# 加法
print("\n向量加法:")
print("u + v =", u + v)
# 数乘
print("\n标量乘法:")
print("2 * v =", 2 * v)
# 点积
print("\n向量点积:")
print("u · v =", np.dot(u, v))
# 向量范数(模长)
print("\n向量范数:")
print("||v|| =", np.linalg.norm(v))
1.2 向量的应用场景
在机器学习中,向量通常用于表示:
- 样本特征:一个样本的所有特征值组成一个向量
- 权重向量:线性模型中的参数
- 词向量:NLP中的词语表示(Word2Vec)
# 示例:用向量表示一个图像样本(28x28展平为784维)
image_vector = np.random.rand(784) # 模拟MNIST图像
print("图像向量形状:", image_vector.shape)
# 示例:用向量表示词嵌入
word_embedding = {
'word': np.random.rand(300), # 300维词向量
'embedding': np.random.rand(300),
'vector': np.random.rand(300)
}
二、矩阵:批量数据的表示
2.1 矩阵的基本概念
矩阵是二维数组,在AI中用于表示批量数据或线性变换。
# 创建矩阵
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print("矩阵 A:")
print(A)
print("\n矩阵形状:", A.shape)
# 矩阵基本运算
B = np.array([[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])
# 矩阵加法
print("\n矩阵加法:")
print("A + B =")
print(A + B)
# 矩阵乘法
print("\n矩阵乘法:")
print("A @ B =")
print(np.dot(A, B))
# 矩阵转置
print("\n矩阵转置:")
print("A.T =")
print(A.T)
# 单位矩阵
I = np.eye(3)
print("\n3x3单位矩阵:")
print(I)
# 逆矩阵
A_square = np.array([[1, 2], [3, 4]])
A_inv = np.linalg.inv(A_square)
print("\n矩阵逆运算:")
print("A的逆矩阵:")
print(A_inv)
print("A @ A^{-1} =")
print(np.dot(A_square, A_inv))
2.2 矩阵在AI中的应用
# 示例1:用矩阵表示批量图像数据
# 假设有100张28x28的图像,展平后构成(100, 784)的矩阵
batch_images = np.random.rand(100, 784)
print("图像批量矩阵形状:", batch_images.shape)
# 示例2:用矩阵表示全连接层的权重
# 输入层784维,输出层10维
W = np.random.randn(784, 10) # 权重矩阵
b = np.random.randn(10) # 偏置向量
print("权重矩阵形状:", W.shape)
# 前向传播计算
input_vector = np.random.randn(784)
output = np.dot(input_vector, W) + b
print("输出向量形状:", output.shape)
# 示例3:用矩阵表示卷积核
# 假设3个通道,3x3卷积核,输出16个特征图
conv_kernel = np.random.randn(3, 3, 3, 16)
print("卷积核形状:", conv_kernel.shape)
三、特征值与特征向量
3.1 概念解释
特征值和特征向量用于理解矩阵的"本质"变换:
- 特征向量:在矩阵变换后方向不变的向量
- 特征值:特征向量在变换后的伸缩倍数
# 计算特征值和特征向量
A = np.array([[4, 1],
[2, 3]])
eigenvalues, eigenvectors = np.linalg.eig(A)
print("矩阵 A:")
print(A)
print("\n特征值:")
print(eigenvalues)
print("\n特征向量:")
print(eigenvectors)
3.2 特征值分解的应用
# PCA降维中的特征值分解
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# 加载数据
iris = load_iris()
X = iris.data
y = iris.target
# PCA降维到2维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
print("原始数据形状:", X.shape)
print("PCA后数据形状:", X_pca.shape)
print("各主成分解释的方差比例:", pca.explained_variance_ratio_)
print("特征值:", pca.explained_variance_)
# 可视化
plt.figure(figsize=(8, 6))
colors = ['navy', 'turquoise', 'darkorange']
for i, color in enumerate(colors):
plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1],
c=color, label=iris.target_names[i], alpha=0.8)
plt.xlabel('First Principal Component')
plt.ylabel('Second Principal Component')
plt.title('PCA of IRIS Dataset')
plt.legend()
plt.tight_layout()
plt.savefig('pca_visualization.png', dpi=150)
plt.show()
四、奇异值分解(SVD)
4.1 概念解释
SVD是矩阵分解的更通用形式,任何矩阵都可以分解为三个矩阵的乘积:
$$A = U \cdot \Sigma \cdot V^T$$
# SVD分解
A = np.array([[1, 2, 3],
[4, 5, 6]])
U, s, Vt = np.linalg.svd(A)
print("原始矩阵 A:")
print(A)
print("\nU 矩阵:")
print(U)
print("\n奇异值向量 s:")
print(s)
print("\nVt 矩阵:")
print(Vt)
# 重构矩阵
Sigma = np.zeros_like(A)
np.fill_diagonal(Sigma, s)
A_reconstructed = U @ Sigma @ Vt
print("\n重构的矩阵:")
print(A_reconstructed)
4.2 SVD的典型应用
# 应用1:图像压缩
from skimage import data, color
from skimage.transform import resize
import matplotlib.image as mpimg
# 加载图像并转为灰度
img = color.rgb2gray(mpimg.imread('example_image.jpg'))
print("图像形状:", img.shape)
# SVD分解
U, s, Vt = np.linalg.svd(img)
print("奇异值数量:", len(s))
# 用前k个奇异值重构图像
def reconstruct_image(U, s, Vt, k):
Sigma = np.zeros_like(img)
np.fill_diagonal(Sigma[:k, :k], s[:k])
return U @ Sigma @ Vt
# 比较不同k值的效果
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
k_values = [5, 20, 50, 100]
for ax, k in zip(axes, k_values):
img_reconstructed = reconstruct_image(U, s, Vt, k)
ax.imshow(img_reconstructed, cmap='gray')
ax.set_title(f'k={k}')
ax.axis('off')
plt.suptitle('SVD Image Compression')
plt.tight_layout()
plt.savefig('svd_compression.png', dpi=150)
plt.show()
# 应用2:推荐系统中的协同过滤
def matrix_factorization(R, k, learning_rate=0.01, epochs=100):
"""
简单的矩阵分解用于推荐系统
R: 用户-物品评分矩阵
k: 隐因子数量
"""
m, n = R.shape
np.random.seed(42)
# 初始化
U = np.random.randn(m, k)
V = np.random.randn(n, k)
# 梯度下降
for epoch in range(epochs):
for i in range(m):
for j in range(n):
if R[i, j] > 0:
error = R[i, j] - np.dot(U[i], V[j])
U[i] += learning_rate * error * V[j]
V[j] += learning_rate * error * U[i]
return U, V
# 示例用户评分矩阵
R = np.array([
[5, 3, 0, 1],
[4, 0, 0, 1],
[1, 1, 0, 5],
[1, 0, 0, 4],
[0, 1, 5, 4]
])
U, V = matrix_factorization(R, k=2)
print("用户矩阵 U:")
print(U)
print("\n物品矩阵 V:")
print(V)
五、矩阵运算在神经网络中的应用
5.1 全连接层的矩阵运算
class FullyConnectedLayer:
"""全连接层的前向传播"""
def __init__(self, input_size, output_size):
# Xavier初始化
self.W = np.random.randn(input_size, output_size) * np.sqrt(2.0 / input_size)
self.b = np.zeros(output_size)
def forward(self, x):
# y = xW + b
self.x = x # 保存输入用于反向传播
return np.dot(x, self.W) + self.b
def backward(self, grad_output, learning_rate=0.01):
# 计算梯度
grad_input = np.dot(grad_output, self.W.T)
grad_W = np.dot(self.x.T, grad_output)
grad_b = np.sum(grad_output, axis=0)
# 更新参数
self.W -= learning_rate * grad_W
self.b -= learning_rate * grad_b
return grad_input
# 测试全连接层
layer = FullyConnectedLayer(input_size=784, output_size=10)
x = np.random.randn(100, 784) # 100个样本
output = layer.forward(x)
print("输入形状:", x.shape)
print("输出形状:", output.shape)
5.2 卷积运算的矩阵实现
def im2col(X, kernel_size, stride=1, pad=0):
"""
将图像块转换为列,方便卷积运算
X: 输入图像 (H, W, C)
"""
H, W, C = X.shape
X_padded = np.pad(X, ((pad, pad), (pad, pad), (0, 0)), mode='constant')
# 计算输出尺寸
out_h = (H + 2 * pad - kernel_size) // stride + 1
out_w = (W + 2 * pad - kernel_size) // stride + 1
# 提取所有图像块
patches = []
for i in range(out_h):
for j in range(out_w):
patch = X_padded[i*stride:i*stride+kernel_size,
j*stride:j*stride+kernel_size, :]
patches.append(patch.reshape(-1))
return np.array(patches).T # (kernel_size*kernel_size*C, out_h*out_w)
def convolution_matrix(X, kernel, stride=1, pad=0):
"""
使用矩阵乘法实现卷积
"""
# 展开输入
X_col = im2col(X, kernel.shape[0], stride, pad)
# 展开卷积核
K_flat = kernel.reshape(-1, 1)
# 矩阵乘法实现卷积
out = X_col.T @ K_flat
# 恢复形状
H, W, C = X.shape
out_h = (H + 2 * pad - kernel.shape[0]) // stride + 1
out_w = (W + 2 * pad - kernel.shape[0]) // stride + 1
return out.reshape(out_h, out_w, -1).squeeze()
# 测试
X_test = np.random.randn(8, 8, 3) # 8x8的RGB图像
kernel_test = np.random.randn(3, 3, 3) # 3x3卷积核
output = convolution_matrix(X_test, kernel_test, stride=1, pad=0)
print("输入形状:", X_test.shape)
print("卷积核形状:", kernel_test.shape)
print("输出形状:", output.shape)
六、总结
本文介绍了AI学习中最重要的线性代数概念:
- 向量与矩阵的基本运算
- 特征值分解与SVD
- 矩阵运算在神经网络中的应用
这些数学知识是后续学习机器学习和深度学习的基础,建议大家多动手实践,加深理解。
下期预告:🚀 第3篇 | AI工程师必备数学基础:概率论与统计
更多推荐
所有评论(0)