第一篇:机器学习基础(快速回顾)#

篇章概述#

本篇是计算机视觉学习的基础准备篇,快速回顾机器学习核心概念,为后续深度学习和计算机视觉内容打下基础。

学习目标

  • 理解机器学习的基本概念和分类
  • 掌握损失函数、优化器等核心要素
  • 了解过拟合与正则化
  • 理解传统图像特征提取方法
  • 明确深度学习相比传统方法的优势

适合人群

  • 有Python基础,想快速了解机器学习概念
  • 准备学习深度学习和计算机视觉
  • 需要回顾机器学习基础知识

章节结构#

第1章:机器学习核心概念#

涵盖机器学习的基本分类、损失函数、优化器等核心概念,并通过sklearn实现手写数字分类的实战案例。

关键内容

  • 监督学习 vs 无监督学习
  • 损失函数与优化器
  • 过拟合与正则化
  • 实战:手写数字分类(sklearn)

第2章:从传统特征到深度学习#

介绍传统图像特征提取方法(SIFT、HOG等),解释为什么需要深度学习,并准备深度学习环境。

关键内容

  • 传统图像特征(SIFT、HOG)
  • 传统方法的局限性
  • 为什么需要深度学习
  • 环境准备(PyTorch/TensorFlow)

学习路径#

第1章:机器学习核心概念
理解监督学习/无监督学习
掌握损失函数和优化器
实战:MNIST分类(sklearn)
第2章:从传统特征到深度学习
了解SIFT、HOG等传统特征
理解深度学习的优势
准备深度学习环境
进入第二篇:深度学习基础

学习建议#

  1. 快速回顾:本篇作为快速回顾,不需要深入每个细节
  2. 动手实践:运行所有代码示例,理解实际效果
  3. 概念理解:重点理解核心概念,为后续学习打基础
  4. 环境准备:确保环境配置正确,能够运行所有示例代码

环境要求#

# Python版本
Python 3.10+

# 第1章所需库
pip install scikit-learn numpy matplotlib

# 第2章所需库(传统特征)
pip install opencv-python scikit-image

# 深度学习环境(第2章末尾准备)
pip install torch torchvision  # PyTorch
# 或
pip install tensorflow         # TensorFlow

预计学习时间#

  • 第1章:2-3小时
  • 第2章:2-3小时
  • 总计:4-6小时

后续安排#

完成本篇后,将进入第二篇:深度学习基础,学习神经网络、卷积神经网络等深度学习核心内容。


第1章:机器学习核心概念#

本章概述#

本章快速回顾机器学习的核心概念,包括监督学习与无监督学习的区别、损失函数与优化器的作用、以及如何处理过拟合问题。通过一个完整的手写数字分类实战案例,让你理解机器学习的基本流程。

学习目标

  • 理解监督学习和无监督学习的区别
  • 掌握损失函数和优化器的概念
  • 了解过拟合与正则化方法
  • 完成手写数字分类实战

前置知识

  • Python基础语法
  • NumPy基础操作

1.1 机器学习基本分类#

监督学习(Supervised Learning)#

定义:从标注数据中学习输入到输出的映射关系。

特点

  • 训练数据包含输入(特征)和输出(标签)
  • 目标是学习一个函数 f(x) = y
  • 可以评估模型在已知标签数据上的表现

常见任务

任务类型输出类型典型应用示例
分类(Classification)离散值图像分类、文本分类猫狗识别、垃圾邮件检测
回归(Regression)连续值价格预测、温度预测房价预测、股票预测

代码示例

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

# 生成分类数据
X, y = make_classification(n_samples=100, n_features=20, n_classes=2)

# 监督学习:训练数据包含X和y
model = LogisticRegression()
model.fit(X, y)  # 需要标签y

# 预测
predictions = model.predict(X)

无监督学习(Unsupervised Learning)#

定义:从未标注数据中发现隐藏的模式和结构。

特点

  • 训练数据只有输入,没有标签
  • 目标是发现数据的内在结构
  • 难以量化评估模型性能

常见任务

任务类型目标典型应用示例
聚类(Clustering)分组相似样本客户分群、图像分割K-means聚类
降维(Dimensionality Reduction)减少特征数量可视化、压缩PCA、t-SNE
异常检测(Anomaly Detection)发现异常样本欺诈检测、故障检测Isolation Forest

代码示例

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

# 生成聚类数据
X, _ = make_blobs(n_samples=100, n_features=2, centers=3)

# 无监督学习:训练数据只有X
model = KMeans(n_clusters=3)
model.fit(X)  # 不需要标签

# 聚类结果
labels = model.predict(X)

对比总结#

维度监督学习无监督学习
数据标签需要标签不需要标签
训练目标学习输入到输出的映射发现数据内在结构
性能评估容易(有标签对比)困难(无标准答案)
数据成本高(需要人工标注)低(无需标注)
典型应用分类、回归聚类、降维

1.2 损失函数与优化器#

损失函数(Loss Function)#

定义:衡量模型预测值与真实值之间差异的函数。

作用

  • 量化模型的预测误差
  • 指导模型参数的更新方向
  • 不同任务使用不同的损失函数

常见损失函数

1. 均方误差(MSE)- 回归任务#

$$ \text{MSE} = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2 $$

特点

  • 对异常值敏感(平方放大误差)
  • 可导,便于优化
  • 适用于回归任务
import numpy as np

def mse_loss(y_true, y_pred):
    """均方误差损失"""
    return np.mean((y_true - y_pred) ** 2)

# 示例
y_true = np.array([1.0, 2.0, 3.0])
y_pred = np.array([1.1, 2.2, 2.9])
loss = mse_loss(y_true, y_pred)
print(f"MSE Loss: {loss:.4f}")  # 0.0233

2. 交叉熵(Cross-Entropy)- 分类任务#

二分类(Binary Cross-Entropy)

$$ \text{BCE} = -\frac{1}{n}\sum_{i=1}^{n}[y_i\log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i)] $$

多分类(Categorical Cross-Entropy)

$$ \text{CCE} = -\frac{1}{n}\sum_{i=1}^{n}\sum_{j=1}^{C}y_{ij}\log(\hat{y}_{ij}) $$

def binary_cross_entropy(y_true, y_pred):
    """二分类交叉熵"""
    epsilon = 1e-15  # 防止log(0)
    y_pred = np.clip(y_pred, epsilon, 1 - epsilon)
    return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))

# 示例
y_true = np.array([1, 0, 1])
y_pred = np.array([0.9, 0.1, 0.8])
loss = binary_cross_entropy(y_true, y_pred)
print(f"BCE Loss: {loss:.4f}")  # 0.1336

损失函数选择

任务类型推荐损失函数原因
二分类Binary Cross-Entropy衡量概率分布差异
多分类Categorical Cross-Entropy适合softmax输出
回归MSE / MAE衡量数值差异
排序Hinge Loss最大化分类间隔

优化器(Optimizer)#

定义:根据损失函数的梯度更新模型参数的算法。

核心思想:通过迭代更新参数,使损失函数最小化。

梯度下降(Gradient Descent)#

基本公式

$$ \theta_{t+1} = \theta_t - \eta \cdot \nabla_\theta L(\theta_t) $$

其中:

  • $\theta$:模型参数
  • $\eta$:学习率(learning rate)
  • $\nabla_\theta L$:损失函数对参数的梯度

变体对比

优化器每次更新使用的数据特点适用场景
批量梯度下降(BGD)全部数据稳定但慢小数据集
随机梯度下降(SGD)单个样本快但不稳定在线学习
小批量梯度下降(Mini-batch GD)小批量数据平衡速度和稳定性最常用

常见优化器#

1. SGD(Stochastic Gradient Descent)

# sklearn中的SGD示例
from sklearn.linear_model import SGDClassifier

model = SGDClassifier(
    loss='log_loss',        # 损失函数
    learning_rate='constant',  # 学习率策略
    eta0=0.01,             # 初始学习率
    max_iter=1000
)

2. Adam(Adaptive Moment Estimation)

特点

  • 结合动量(Momentum)和自适应学习率
  • 对每个参数使用不同的学习率
  • 最常用的优化器之一

优势

  • 收敛速度快
  • 对超参数不敏感
  • 适合大多数深度学习任务

优化器选择建议

场景推荐优化器原因
快速原型Adam收敛快,调参少
最优性能SGD + Momentum泛化能力好
稀疏数据AdaGrad自适应学习率
RNN/LSTMAdam / RMSprop处理梯度消失

1.3 过拟合与正则化#

过拟合(Overfitting)#

定义:模型在训练集上表现很好,但在测试集上表现差。

表现

  • 训练误差很低
  • 测试误差很高
  • 模型记住了训练数据,而非学习了通用模式

原因

  • 模型过于复杂(参数太多)
  • 训练数据太少
  • 训练时间过长

示例图示

训练误差和测试误差随模型复杂度变化:

误差
 |          测试误差
 |         /‾‾‾‾‾
 |        /
 |       /
 |      /
 |     /_________ 训练误差
 |
 └─────────────────→ 模型复杂度
    最佳复杂度

欠拟合(Underfitting)#

定义:模型过于简单,无法捕捉数据的模式。

表现

  • 训练误差高
  • 测试误差高
  • 模型能力不足

正则化(Regularization)#

目的:防止过拟合,提高模型泛化能力。

1. L1正则化(Lasso)#

公式

$$ L = L_{\text{original}} + \lambda\sum_{i}|\theta_i| $$

特点

  • 惩罚参数的绝对值
  • 产生稀疏解(部分参数为0)
  • 可用于特征选择
from sklearn.linear_model import Lasso

# L1正则化
model = Lasso(alpha=0.1)  # alpha是正则化强度

2. L2正则化(Ridge)#

公式

$$ L = L_{\text{original}} + \lambda\sum_{i}\theta_i^2 $$

特点

  • 惩罚参数的平方
  • 参数趋向于小值但不为0
  • 更常用,数值稳定
from sklearn.linear_model import Ridge

# L2正则化
model = Ridge(alpha=1.0)  # alpha是正则化强度

3. Elastic Net(L1 + L2)#

公式

$$ L = L_{\text{original}} + \lambda_1\sum_{i}|\theta_i| + \lambda_2\sum_{i}\theta_i^2 $$

from sklearn.linear_model import ElasticNet

# L1 + L2正则化
model = ElasticNet(alpha=0.1, l1_ratio=0.5)  # l1_ratio控制L1和L2的比例

正则化方法对比

方法惩罚项特点适用场景
L1绝对值稀疏解,特征选择高维稀疏数据
L2平方平滑解,数值稳定大多数场景
Elastic NetL1+L2结合两者优势特征相关性高
Dropout随机失活集成效果深度神经网络

其他防止过拟合的方法#

方法原理优点缺点
数据增强增加训练样本提高泛化能力需要领域知识
Early Stopping提前停止训练简单有效需要验证集
Dropout随机丢弃神经元集成效果仅用于神经网络
交叉验证多次划分数据充分利用数据计算成本高

1.4 实战:手写数字分类(sklearn)#

项目概述#

使用scikit-learn实现MNIST手写数字分类,这是机器学习领域的"Hello World"项目。

数据集:MNIST手写数字数据集

  • 60,000个训练样本
  • 10,000个测试样本
  • 每个图像28×28像素,灰度图
  • 10个类别(数字0-9)

目标

  • 加载和探索MNIST数据
  • 训练多个分类器
  • 评估模型性能
  • 可视化结果

完整代码#

代码文件:code/chapter01_ml_basics/mnist_sklearn.py

# 详见 code/chapter01_ml_basics/mnist_sklearn.py

运行步骤#

# 1. 安装依赖
pip install scikit-learn numpy matplotlib

# 2. 运行代码
cd chapter01/code
python mnist_sklearn.py

预期输出#

数据集信息:
训练集: 60000 samples
测试集: 10000 samples
图像尺寸: 28x28

模型性能比较:
Logistic Regression - 准确率: 92.50%
Random Forest - 准确率: 96.80%
SVM - 准确率: 94.20%

最佳模型: Random Forest

代码详解#

1. 数据加载#

from sklearn.datasets import fetch_openml

# 加载MNIST数据集
mnist = fetch_openml('mnist_784', version=1, parser='auto')
X, y = mnist.data, mnist.target

关键点

  • fetch_openml从OpenML下载数据集
  • 数据已经展平为784维向量(28×28)
  • 标签为字符串,需要转换为整数

2. 数据预处理#

# 归一化
X = X / 255.0

# 划分训练集和测试集
X_train, X_test = X[:60000], X[60000:]
y_train, y_test = y[:60000], y[60000:]

为什么归一化

  • 特征值范围统一(0-1)
  • 加速模型收敛
  • 防止某些特征主导

3. 模型训练#

from sklearn.linear_model import LogisticRegression

model = LogisticRegression(max_iter=100)
model.fit(X_train, y_train)

逻辑回归要点

  • 虽然名为"回归",但用于分类
  • 多分类使用one-vs-rest策略
  • max_iter控制最大迭代次数

4. 模型评估#

from sklearn.metrics import accuracy_score, classification_report

y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"准确率: {accuracy:.2%}")

评估指标

  • 准确率(Accuracy):正确预测的比例
  • 精确率(Precision):预测为正的样本中真正为正的比例
  • 召回率(Recall):真正为正的样本中被正确预测的比例
  • F1分数:精确率和召回率的调和平均

实验结果分析#

不同模型对比

模型准确率训练时间优点缺点
Logistic Regression~92%简单,可解释性能一般
Random Forest~97%性能好,鲁棒模型较大
SVM~94%泛化能力强训练慢

提升性能的方法

  1. 特征工程:提取更好的特征
  2. 模型调参:调整超参数
  3. 集成学习:组合多个模型
  4. 深度学习:使用CNN(下一篇)

本章小结#

核心概念回顾#

  1. 机器学习分类

    • 监督学习:有标签,学习映射关系
    • 无监督学习:无标签,发现数据结构
  2. 损失函数

    • 衡量模型预测误差
    • 回归任务:MSE、MAE
    • 分类任务:交叉熵
  3. 优化器

    • 根据梯度更新参数
    • SGD、Adam等常用优化器
    • 学习率是关键超参数
  4. 过拟合与正则化

    • 过拟合:训练好测试差
    • 正则化:L1、L2、Dropout
    • 其他方法:数据增强、Early Stopping

实战经验#

  • MNIST分类:传统机器学习可达到~97%准确率
  • 模型选择:Random Forest在sklearn中表现最好
  • 局限性:传统方法难以处理复杂图像任务

下一章预告#

第2章将介绍传统图像特征(SIFT、HOG),并解释为什么需要深度学习来突破传统方法的局限。

扩展阅读#

  1. scikit-learn官方文档:https://scikit-learn.org/
  2. MNIST数据集:http://yann.lecun.com/exdb/mnist/
  3. 机器学习实战:《Hands-On Machine Learning》

练习题#

  1. 修改代码:尝试不同的正则化参数,观察对准确率的影响
  2. 特征工程:提取新特征(如像素均值、方差),看能否提升性能
  3. 可视化:绘制混淆矩阵,分析哪些数字容易混淆
  4. 挑战:使用PCA降维到50维,观察性能变化

下一章第2章:从传统特征到深度学习


第2章:从传统特征到深度学习#

本章概述#

本章介绍传统图像特征提取方法(如SIFT、HOG),分析这些方法的优势和局限性,并解释为什么深度学习能够突破这些限制。最后,我们将准备深度学习环境,为后续章节做好准备。

学习目标

  • 理解传统图像特征提取方法(SIFT、HOG)
  • 了解传统方法的优势和局限性
  • 理解深度学习相比传统方法的优势
  • 配置PyTorch/TensorFlow环境

前置知识

  • 基本的图像处理概念
  • Python和NumPy基础
  • 第1章的机器学习知识

2.1 传统图像特征#

什么是特征?#

定义:特征是图像中具有区分性的、可以用数值表示的信息。

好特征的标准

  • 可区分性:不同类别的特征值差异大
  • 不变性:对光照、旋转、尺度变化鲁棒
  • 可计算性:能够高效计算
  • 紧凑性:用较少的数值表示丰富的信息

传统方法的核心思想

原始图像 → 手工设计的特征提取器 → 特征向量 → 分类器 → 预测结果

2.1.1 SIFT(Scale-Invariant Feature Transform)#

发明者:David Lowe (1999)

核心思想:检测图像中的关键点,并计算具有尺度和旋转不变性的特征描述子。

主要步骤

  1. 尺度空间极值检测

    • 使用高斯差分(DoG)在不同尺度上寻找关键点
    • 对尺度变化具有不变性
  2. 关键点定位

    • 精确定位关键点的位置和尺度
    • 去除低对比度和边缘响应的关键点
  3. 方向分配

    • 计算关键点的主方向
    • 实现旋转不变性
  4. 关键点描述

    • 计算128维特征向量
    • 描述关键点周围的梯度分布

特点

特性说明
尺度不变性对图像缩放鲁棒
旋转不变性对图像旋转鲁棒
亮度不变性对光照变化鲁棒
特征维度128维向量
计算速度较慢

应用场景

  • 图像匹配和拼接
  • 物体识别
  • 3D重建
  • 图像检索

代码示例

import cv2
import numpy as np
import matplotlib.pyplot as plt

def detect_sift_features(image_path):
    """
    使用SIFT检测和提取特征

    Args:
        image_path: 图像路径
    """
    # 读取图像(灰度)
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

    # 创建SIFT检测器
    sift = cv2.SIFT_create()

    # 检测关键点和计算描述子
    keypoints, descriptors = sift.detectAndCompute(img, None)

    # 绘制关键点
    img_keypoints = cv2.drawKeypoints(
        img,
        keypoints,
        None,
        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
    )

    print(f"检测到 {len(keypoints)} 个关键点")
    print(f"描述子维度: {descriptors.shape}")

    # 显示结果
    plt.figure(figsize=(12, 6))
    plt.imshow(img_keypoints, cmap='gray')
    plt.title(f'SIFT关键点 (共{len(keypoints)}个)')
    plt.axis('off')
    plt.tight_layout()
    plt.savefig('sift_keypoints.png', dpi=150, bbox_inches='tight')
    plt.close()

    return keypoints, descriptors

# 使用示例
# keypoints, descriptors = detect_sift_features('image.jpg')

2.1.2 HOG(Histogram of Oriented Gradients)#

发明者:Navneet Dalal & Bill Triggs (2005)

核心思想:统计图像局部区域的梯度方向直方图,作为特征描述子。

主要步骤

  1. 计算梯度

    • 计算图像每个像素的梯度幅值和方向
    • 使用Sobel算子或简单差分
  2. 划分单元格(Cell)

    • 将图像划分为小的单元格(如8×8像素)
    • 每个单元格计算梯度方向直方图
  3. 构建块(Block)

    • 将多个单元格组成块(如2×2个单元格)
    • 在块内进行归一化,提高鲁棒性
  4. 特征向量

    • 连接所有块的直方图形成最终特征向量
    • 典型维度:几千维

特点

特性说明
光照不变性对亮度变化较鲁棒
几何不变性对小范围的几何变形鲁棒
特征维度通常几千维
计算速度较快
适用任务行人检测、物体检测

应用场景

  • 行人检测(经典应用)
  • 物体检测
  • 姿态估计
  • 动作识别

代码示例

from skimage.feature import hog
from skimage import exposure
import matplotlib.pyplot as plt

def extract_hog_features(image, visualize=True):
    """
    提取HOG特征

    Args:
        image: 输入图像(灰度)
        visualize: 是否可视化

    Returns:
        features: HOG特征向量
        hog_image: HOG可视化图像(如果visualize=True)
    """
    # 提取HOG特征
    features, hog_image = hog(
        image,
        orientations=9,           # 梯度方向的bins数量
        pixels_per_cell=(8, 8),   # 每个cell的像素数
        cells_per_block=(2, 2),   # 每个block的cell数
        visualize=visualize,
        block_norm='L2-Hys'       # 归一化方法
    )

    if visualize:
        # 增强对比度以便可视化
        hog_image_rescaled = exposure.rescale_intensity(
            hog_image,
            in_range=(0, 10)
        )

        # 显示原图和HOG特征
        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))

        ax1.imshow(image, cmap='gray')
        ax1.set_title('原始图像')
        ax1.axis('off')

        ax2.imshow(hog_image_rescaled, cmap='gray')
        ax2.set_title('HOG特征可视化')
        ax2.axis('off')

        plt.tight_layout()
        plt.savefig('hog_features.png', dpi=150, bbox_inches='tight')
        plt.close()

    print(f"HOG特征维度: {len(features)}")

    return features, hog_image if visualize else None

# 使用示例
# features, hog_img = extract_hog_features(gray_image)

2.1.3 其他传统特征#

特征类型主要用途特点
SURF图像匹配SIFT的加速版本,使用积分图
ORB实时应用快速、免费,结合FAST和BRIEF
LBP纹理分类计算简单,对光照鲁棒
颜色直方图图像检索简单高效,忽略空间信息
边缘特征形状检测Canny、Sobel等边缘检测

2.1.4 传统特征的优势#

1. 可解释性强

  • 特征提取过程清晰
  • 容易理解和调试
  • 可以根据领域知识设计

2. 计算效率高

  • 不需要大量训练数据
  • 推理速度快
  • 适合资源受限的场景

3. 特定任务表现好

  • HOG在行人检测上效果优秀
  • SIFT在图像匹配上非常可靠
  • 在小数据集上可能优于深度学习

代码示例:传统方法的完整流程

详见:code/chapter02_traditional_cv/traditional_features.py

2.2 传统方法的局限性#

2.2.1 特征工程的困境#

问题1:需要领域专家

  • 设计好的特征需要丰富的经验
  • 不同任务需要不同的特征
  • 特征设计是一个试错过程

问题2:泛化能力有限

  • 为特定任务设计的特征难以迁移
  • 对新场景的适应性差
  • 需要重新设计特征

问题3:特征表达能力不足

传统方法:
  图像 → 手工特征(数百到数千维)→ 分类器

深度学习:
  图像 → 自动学习特征(数百万参数)→ 分类

2.2.2 复杂场景下的失效#

场景1:复杂背景

  • 传统特征容易受背景干扰
  • 难以区分前景和背景
  • 需要额外的预处理

场景2:多样性变化

| 变化类型 | 传统方法应对 | 效果 |
|---------|------------|------|
| 光照变化 | 归一化、不变特征 | 中等 |
| 尺度变化 | 多尺度检测 | 较好 |
| 视角变化 | 3D特征、视角不变性 | 较差 |
| 遮挡 | 局部特征 | 较差 |
| 类内变化 | 特征选择 | 较差 |

场景3:高级语义理解

  • 传统特征难以捕捉高级语义
  • 无法理解上下文关系
  • 对抽象概念的表达能力弱

2.2.3 性能瓶颈#

实验数据对比(ImageNet数据集):

方法Top-5错误率年份
传统方法(SIFT+SVM)~25%2012前
AlexNet(深度学习)15.3%2012
ResNet-1523.6%2015
人类水平~5%-

关键观察

  • 2012年AlexNet的出现是转折点
  • 深度学习在大规模数据集上显著优于传统方法
  • 持续改进,已接近甚至超越人类水平

2.3 为什么需要深度学习?#

2.3.1 自动特征学习#

传统方法 vs 深度学习

传统方法:
  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ 原始图像 │ →  │ 手工特征 │ →  │  分类器  │
  └──────────┘    └──────────┘    └──────────┘
                  需要人工设计

深度学习:
  ┌──────────┐    ┌──────────────────────┐    ┌──────────┐
  │ 原始图像 │ →  │ 自动学习的特征层级   │ →  │  分类器  │
  └──────────┘    └──────────────────────┘    └──────────┘
                  低级特征 → 中级特征 → 高级特征
                  端到端学习

优势

  • 自动化:不需要手工设计特征
  • 层次化:自动学习从低级到高级的特征层次
  • 端到端:直接从原始数据到最终输出

2.3.2 表达能力强大#

特征层次的自动学习

卷积神经网络(CNN)的特征层次:

第1层(低级特征):
  - 边缘检测器
  - 颜色斑点
  - 简单纹理

第2-3层(中级特征):
  - 简单形状
  - 纹理组合
  - 局部模式

第4-5层(高级特征):
  - 物体部件(眼睛、轮子等)
  - 复杂模式
  - 语义概念

可视化示例(概念图):

输入图像(猫)
[第1层] 边缘、纹理
[第2层] 简单形状
[第3层] 猫的局部特征(耳朵、眼睛)
[第4层] 猫的整体特征
输出:猫(95%置信度)

2.3.3 可扩展性#

数据规模的影响

性能
  |              深度学习
  |            /
  |          /
  |        /
  |      /______ 传统方法(性能饱和)
  |    /
  |  /
  |/
  └─────────────────────→ 数据量

关键点

  • 小数据:传统方法可能更好(避免过拟合)
  • 中等数据:两者接近
  • 大数据:深度学习显著优于传统方法

2.3.4 迁移学习能力#

传统方法

  • 特征通常针对特定任务
  • 难以在不同任务间迁移

深度学习

  • 预训练模型可以迁移到新任务
  • 只需微调少量参数
  • 大大减少训练数据需求

示例

# 使用预训练的ResNet模型
import torchvision.models as models

# 加载ImageNet预训练模型
resnet = models.resnet50(pretrained=True)

# 只替换最后一层用于新任务
num_classes = 10  # 新任务的类别数
resnet.fc = nn.Linear(resnet.fc.in_features, num_classes)

# 只训练最后一层,其他层使用预训练权重
for param in resnet.parameters():
    param.requires_grad = False
resnet.fc.weight.requires_grad = True
resnet.fc.bias.requires_grad = True

2.3.5 深度学习的优势总结#

维度传统方法深度学习
特征提取手工设计自动学习
表达能力有限(数百到数千维)强大(数百万参数)
数据需求多(或使用预训练模型)
可解释性较弱(黑盒)
泛化能力特定任务跨任务迁移
性能上限较低高(接近人类)
计算资源多(需要GPU)

2.4 环境准备#

2.4.1 PyTorch环境配置#

PyTorch简介

  • Facebook开发的深度学习框架
  • 动态计算图,灵活易用
  • 学术界最流行的框架

安装步骤

# 1. 创建虚拟环境(推荐)
python -m venv cv_env
source cv_env/bin/activate  # Windows: cv_env\Scripts\activate

# 2. 安装PyTorch(根据CUDA版本选择)
# CPU版本
pip install torch torchvision torchaudio

# GPU版本(CUDA 11.8)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# GPU版本(CUDA 12.1)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

# 3. 安装其他依赖
pip install numpy matplotlib opencv-python scikit-image

验证安装

import torch
import torchvision

print(f"PyTorch版本: {torch.__version__}")
print(f"TorchVision版本: {torchvision.__version__}")
print(f"CUDA可用: {torch.cuda.is_available()}")
if torch.cuda.is_available():
    print(f"CUDA版本: {torch.version.cuda}")
    print(f"GPU设备: {torch.cuda.get_device_name(0)}")

预期输出

PyTorch版本: 2.1.0+cu118
TorchVision版本: 0.16.0+cu118
CUDA可用: True
CUDA版本: 11.8
GPU设备: NVIDIA GeForce RTX 3080

2.4.2 TensorFlow环境配置(可选)#

TensorFlow简介

  • Google开发的深度学习框架
  • 工业界广泛使用
  • 提供TensorFlow Lite用于移动端部署

安装步骤

# 安装TensorFlow(包含GPU支持)
pip install tensorflow

# 验证安装
python -c "import tensorflow as tf; print(f'TensorFlow版本: {tf.__version__}'); print(f'GPU可用: {len(tf.config.list_physical_devices(\"GPU\"))}')"

本教程选择

  • 主要使用PyTorch
  • 原因:代码更直观、调试更方便、学术界主流

2.4.3 完整环境配置脚本#

创建requirements.txt

# 深度学习框架
torch>=2.0.0
torchvision>=0.15.0
torchaudio>=2.0.0

# 图像处理
opencv-python>=4.8.0
scikit-image>=0.21.0
Pillow>=10.0.0

# 数据处理
numpy>=1.24.0
pandas>=2.0.0
matplotlib>=3.7.0
seaborn>=0.12.0

# 机器学习工具
scikit-learn>=1.3.0

# 进度条和可视化
tqdm>=4.65.0
tensorboard>=2.13.0

# Jupyter支持
jupyter>=1.0.0
ipywidgets>=8.0.0

安装:

pip install -r requirements.txt

2.4.4 环境测试代码#

详见:code/chapter02_traditional_cv/test_environment.py

运行测试

cd chapter02/code
python test_environment.py

预期输出

========================================
环境测试开始
========================================

[测试1] PyTorch安装
  ✓ PyTorch版本: 2.1.0+cu118
  ✓ CUDA可用: True
  ✓ GPU设备: NVIDIA GeForce RTX 3080

[测试2] 张量操作
  ✓ CPU张量创建成功
  ✓ GPU张量创建成功
  ✓ 张量运算正确

[测试3] 图像处理库
  ✓ OpenCV版本: 4.8.0
  ✓ scikit-image可用

[测试4] 数据加载
  ✓ MNIST数据集加载成功
  ✓ 数据形状: torch.Size([1, 28, 28])

========================================
所有测试通过!环境配置成功。
========================================

2.5 第一个深度学习示例#

简单的神经网络#

为了对比传统方法和深度学习,我们用一个简单的神经网络重新实现MNIST分类。

代码示例(概览,详细代码见code/chapter02_traditional_cv/simple_nn_mnist.py):

import torch
import torch.nn as nn

# 定义简单的全连接神经网络
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(28 * 28, 128)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = x.view(-1, 28 * 28)  # 展平
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

# 训练模型
model = SimpleNN()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练循环(简化版)
for epoch in range(10):
    for images, labels in train_loader:
        outputs = model(images)
        loss = criterion(outputs, labels)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

性能对比

方法准确率训练时间
Logistic Regression~92%
Random Forest~97%
简单神经网络~98%中(GPU加速)
CNN(下一篇)~99%+快(GPU加速)

本章小结#

核心知识点#

  1. 传统特征方法

    • SIFT:尺度和旋转不变,用于图像匹配
    • HOG:梯度方向直方图,用于物体检测
    • 优势:可解释、高效、特定任务表现好
    • 局限:需要人工设计、泛化能力有限
  2. 深度学习的优势

    • 自动特征学习,端到端训练
    • 强大的表达能力和层次化特征
    • 在大数据集上性能优越
    • 支持迁移学习
  3. 环境准备

    • PyTorch是本教程的主要框架
    • 配置GPU加速(推荐)
    • 验证环境安装成功

从传统到深度学习的转变#

传统计算机视觉流程:
  图像 → 预处理 → 特征提取(手工) → 分类器 → 结果

深度学习流程:
  图像 → 神经网络(端到端) → 结果
      自动学习特征

下一步学习#

完成本章后,你已经:

  • ✓ 理解了传统图像特征方法
  • ✓ 明白了为什么需要深度学习
  • ✓ 配置好了深度学习环境

第二篇预告:深度学习基础

  • 神经网络基础
  • 反向传播算法
  • 卷积神经网络(CNN)
  • 经典CNN架构

扩展阅读#

  1. SIFT原始论文:Lowe, D. G. (2004). “Distinctive Image Features from Scale-Invariant Keypoints”
  2. HOG原始论文:Dalal, N., & Triggs, B. (2005). “Histograms of oriented gradients for human detection”
  3. PyTorch官方教程:https://pytorch.org/tutorials/
  4. Deep Learning Book:http://www.deeplearningbook.org/

练习题#

  1. 实践:运行traditional_features.py,比较SIFT和HOG在不同图像上的表现
  2. 实验:使用HOG特征+SVM训练MNIST分类器,对比第1章的结果
  3. 环境:确保test_environment.py所有测试通过
  4. 思考:为什么SIFT适合图像匹配,而HOG适合物体检测?

下一篇第二篇:深度学习基础


[统计组件仅在生产环境显示]