未记录事实核验 · 状态:维护中

记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。

warning 适用边界与维护说明

本文适合具备机器学习与NumPy矩阵运算基础的读者学习神经网络、反向传播和CNN;MNIST部分提供数据加载、训练、评估与预测流程,但不是生产部署方案,各代码块也不应视为可顺序执行的单一脚本。当前AND/XOR示例的输入数组仍含三元素行及重复拼接,且输入数量与标签数量不一致,不能按原样完成训练。20维二分类训练片段需另行准备形状为(n, 20)的数值特征及对应的0/1标签,不能复用MNIST图像与十类独热标签;后续稀疏分类损失示例需要整数类别标签。手写MLP的梯度实现适用于本文单输出均方误差示例;其历史梯度问题及三个卷积核的形状问题已在代码结构上修正。本次仅作全文结构与代码一致性审阅,未运行代码,也未作外部事实核验。 已取消无法确定目标的可点击引用「【AI 与大数据】/10-Transformer与注意力机制」,保留原提及;Missing link target: 【AI 与大数据】/10-Transformer与注意力机制

深度学习入门 - 神经网络基础与实践

abstract 学习目标

  • 核心概念:掌握神经网络的数学基础和工作原理
  • 技术基础:机器学习 + NumPy数值计算
  • 学习内容:感知机、多层感知机、反向传播算法、CNN卷积神经网络
  • 实践项目:图像分类完整案例
  • 框架工具:TensorFlow/Keras深度学习框架

深度学习概述

深度学习是机器学习的子领域,使用包含多个隐藏层的人工神经网络来学习数据中的复杂模式。其核心特点:

  1. 多层架构:通过多个隐藏层实现层次化特征学习
  2. 端到端学习:从原始输入直接学习到最终输出
  3. 自动特征提取:无需手工设计特征,网络自动学习特征表示
  4. 非线性映射:通过激活函数实现复杂的非线性变换

深度学习vs传统机器学习

# 传统机器学习流程
def traditional_ml_pipeline(data):
    # 手工特征工程
    features = manual_feature_engineering(data)
    # 特征选择
    selected_features = feature_selection(features)
    # 训练浅层模型
    model = train_shallow_model(selected_features)
    return model

# 深度学习流程
def deep_learning_pipeline(data):
    # 端到端学习
    model = build_deep_network()
    trained_model = train_deep_model(model, data)
    return trained_model

神经网络基础理论

感知机:神经网络的基础单元

感知机是最简单的神经网络单元,由Rosenblatt于1957年提出。数学表示:

$$y = f(\sum_{i=1}^n w_i x_i + b)$$

其中:

  • $x_i$:输入特征
  • $w_i$:权重参数
  • $b$:偏置项
  • $f$:激活函数
import numpy as np
import matplotlib.pyplot as plt

class Perceptron:
    """感知机实现"""
    
    def __init__(self, n_inputs, learning_rate=0.1):
        # 初始化权重和偏置
        self.weights = np.random.normal(0, 0.1, n_inputs)
        self.bias = 0
        self.learning_rate = learning_rate
        
    def activation(self, z):
        """阶跃激活函数"""
        return 1 if z >= 0 else 0
        
    def predict(self, inputs):
        """预测输出"""
        z = np.dot(inputs, self.weights) + self.bias
        return self.activation(z)
    
    def train(self, training_inputs, labels, epochs=100):
        """感知机学习算法"""
        for epoch in range(epochs):
            errors = 0
            for inputs, label in zip(training_inputs, labels):
                prediction = self.predict(inputs)
                error = label - prediction
                
                if error != 0:
                    # 更新权重和偏置
                    self.weights += self.learning_rate * error * inputs
                    self.bias += self.learning_rate * error
                    errors += 1
            
            if errors == 0:
                print(f"训练完成,耗时{epoch+1}个epoch")
                break
    
    def decision_boundary(self, x):
        """计算决策边界"""
        return -(self.weights[0] * x + self.bias) / self.weights[1]

# 示例:AND门实现
print("感知机实现AND逻辑门")
print("=" * 20)

# 训练数据:AND门真值表
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1|0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 0, 0, 1])  # AND门输出

# 创建感知机
perceptron = Perceptron(n_inputs=2)

# 训练感知机
perceptron.train(X, y)

# 测试
print("\n测试结果:")
for inputs, expected in zip(X, y):
    prediction = perceptron.predict(inputs)
    print(f"输入: {inputs}, 预期: {expected}, 预测: {prediction}")

多层感知机(MLP)

多层感知机通过添加隐藏层克服了感知机的线性限制,可以解决非线性问题。网络结构:

  • 输入层:接收原始特征
  • 隐藏层:进行特征变换,可以有多层
  • 输出层:产生最终预测
class MultiLayerPerceptron:
    """多层感知机实现"""
    
    def __init__(self, layer_sizes):
        self.layer_sizes = layer_sizes
        self.weights = []
        self.biases = []
        
        # Xavier初始化权重
        for i in range(len(layer_sizes) - 1):
            fan_in, fan_out = layer_sizes[i], layer_sizes[i+1]
            limit = np.sqrt(6.0 / (fan_in + fan_out))
            weight = np.random.uniform(-limit, limit, (fan_in, fan_out))
            bias = np.zeros(fan_out)
            
            self.weights.append(weight)
            self.biases.append(bias)
    
    def sigmoid(self, z):
        """Sigmoid激活函数"""
        return 1 / (1 + np.exp(-np.clip(z, -500, 500)))
    
    def sigmoid_derivative(self, z):
        """Sigmoid导数"""
        s = self.sigmoid(z)
        return s * (1 - s)
    
    def forward(self, X):
        """前向传播"""
        self.z_values = []  # 存储线性变换结果
        self.activations = [X]  # 存储激活值
        
        current_input = X
        for i, (W, b) in enumerate(zip(self.weights, self.biases)):
            z = np.dot(current_input, W) + b
            self.z_values.append(z)
            
            if i < len(self.weights) - 1:  # 隐藏层使用sigmoid
                current_input = self.sigmoid(z)
            else:  # 输出层使用sigmoid
                current_input = self.sigmoid(z)
                
            self.activations.append(current_input)
        
        return current_input
    
    def backward(self, X, y, learning_rate=0.01):
        """反向传播算法"""
        m = X.shape[0]
        
        # 计算输出层误差
        delta = 2 * (self.activations[-1] - y.reshape(-1, 1)) * self.sigmoid_derivative(self.z_values[-1])
        
        # 反向传播误差
        for i in reversed(range(len(self.weights))):
            # 计算梯度
            dW = np.dot(self.activations[i].T, delta) / m
            db = np.sum(delta, axis=0) / m
            
            # 使用更新前的权重传播到前一层(除了输入层)
            if i > 0:
                next_delta = np.dot(delta, self.weights[i].T) * \
                             self.sigmoid_derivative(self.z_values[i-1])

            # 更新参数
            self.weights[i] -= learning_rate * dW
            self.biases[i] -= learning_rate * db

            if i > 0:
                delta = next_delta
    
    def train(self, X, y, epochs=1000, learning_rate=0.01):
        """训练网络"""
        costs = []
        
        for epoch in range(epochs):
            # 前向传播
            output = self.forward(X)
            
            # 计算损失
            cost = np.mean((output - y.reshape(-1, 1))**2)
            costs.append(cost)
            
            # 反向传播
            self.backward(X, y, learning_rate)
            
            if epoch % 100 == 0:
                print(f"Epoch {epoch}, Cost: {cost:.4f}")
        
        return costs

# 示例:XOR问题(非线性分类)
print("多层感知机解决XOR问题")
print("=" * 20)

# XOR训练数据
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1|0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])  # XOR输出

# 创建MLP网络
mlp = MultiLayerPerceptron([2, 4, 1])  # 2输入-4隐藏-1输出

# 训练网络
costs = mlp.train(X, y, epochs=5000, learning_rate=1.0)

# 测试结果
print("\n测试结果:")
for i, (inputs, expected) in enumerate(zip(X, y)):
    prediction = mlp.forward(inputs.reshape(1, -1))[0][0]
    print(f"输入: {inputs}, 预期: {expected}, 预测: {prediction:.3f}")

反向传播算法原理

反向传播(Backpropagation)是训练神经网络的核心算法,基于链式法则计算梯度。

数学原理

对于损失函数 $L$ 和网络参数 $w$,梯度计算:

$$\frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial w}$$

其中:

  • $z$:线性变换结果
  • $a$:激活函数输出
  • $L$:损失函数

算法步骤

  1. 前向传播:计算网络输出和损失
  2. 计算输出层梯度:$\delta_L = \frac{\partial L}{\partial z_L} = \frac{\partial L}{\partial a_L} \odot \sigma'(z_L)$
  3. 反向传播梯度:$\delta_l = ((W_{l+1})^T \delta_{l+1}) \odot \sigma'(z_l)$
  4. 更新参数:$W_l := W_l - \alpha \frac{\partial L}{\partial W_l}$

深度学习框架:TensorFlow/Keras

常用激活函数

import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt

# 常用激活函数对比
def compare_activation_functions():
    """比较不同激活函数"""
    x = np.linspace(-5, 5, 100)
    
    # 定义激活函数
    sigmoid = lambda x: 1 / (1 + np.exp(-x))
    tanh = lambda x: np.tanh(x)
    relu = lambda x: np.maximum(0, x)
    leaky_relu = lambda x: np.where(x > 0, x, 0.01 * x)
    
    fig, axes = plt.subplots(2, 2, figsize=(12, 10))
    
    # Sigmoid
    axes[0, 0].plot(x, sigmoid(x), 'b-', linewidth=2)
    axes[0, 0].set_title('Sigmoid: σ(x) = 1/(1+e^(-x))')
    axes[0, 0].grid(True, alpha=0.3)
    axes[0, 0].set_ylim(-0.1, 1.1)
    
    # Tanh
    axes[0, 1].plot(x, tanh(x), 'r-', linewidth=2)
    axes[0, 1].set_title('Tanh: tanh(x) = (e^x - e^(-x))/(e^x + e^(-x))')
    axes[0, 1].grid(True, alpha=0.3)
    axes[0, 1].set_ylim(-1.1, 1.1)
    
    # ReLU
    axes[1, 0].plot(x, relu(x), 'g-', linewidth=2)
    axes[1, 0].set_title('ReLU: f(x) = max(0, x)')
    axes[1, 0].grid(True, alpha=0.3)
    axes[1, 0].set_ylim(-0.5, 5)
    
    # Leaky ReLU
    axes[1, 1].plot(x, leaky_relu(x), 'm-', linewidth=2)
    axes[1, 1].set_title('Leaky ReLU: f(x) = max(0.01x, x)')
    axes[1, 1].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.show()

compare_activation_functions()

# 优化算法比较
def compare_optimizers():
    """比较不同优化算法"""
    print("常用优化算法特点:")
    print("=" * 20)
    
    optimizers = {
        'SGD': '随机梯度下降,简单但可能震荡',
        'Momentum': 'SGD + 动量,减少震荡',
        'RMSprop': '自适应学习率,适合RNN',
        'Adam': '结合动量和RMSprop,应用最广泛',
        'AdamW': 'Adam + 权重衰减,更好的泛化'
    }
    
    for name, desc in optimizers.items():
        print(f"{name:10}: {desc}")

compare_optimizers()

Keras构建深度神经网络

# 创建序贯模型
model = keras.Sequential([
    keras.layers.Dense(128, activation='relu', input_shape=(20,)),
    keras.layers.BatchNormalization(),  # 批标准化
    keras.layers.Dropout(0.3),          # Dropout防过拟合
    
    keras.layers.Dense(64, activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Dropout(0.3),
    
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dropout(0.2),
    
    keras.layers.Dense(1, activation='sigmoid')  # 二分类输出
])

# 编译模型
model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.001),
    loss='binary_crossentropy',
    metrics=['accuracy']
)

print("模型结构:")
model.summary()

训练技巧与正则化

# 训练回调函数
callbacks = [
    keras.callbacks.EarlyStopping(
        monitor='val_loss', patience=10, restore_best_weights=True
    ),
    keras.callbacks.ReduceLROnPlateau(
        monitor='val_loss', factor=0.5, patience=5, min_lr=1e-7
    ),
    keras.callbacks.ModelCheckpoint(
        'best_model.h5', save_best_only=True, monitor='val_loss'
    )
]

# 训练模型
history = model.fit(
    X_train, y_train,
    batch_size=32,
    epochs=100,
    validation_split=0.2,
    callbacks=callbacks,
    verbose=1
)

卷积神经网络(CNN)

卷积神经网络专门用于处理具有网格结构的数据,如图像。核心组件包括:

卷积层工作原理

卷积操作是CNN的核心,通过卷积核(滤波器)提取图像特征:

$$Y_{i,j} = \sum_{m=0}^{M-1} \sum_{n=0}^{N-1} X_{i+m,j+n} \cdot K_{m,n}$$
# 手动实现2D卷积
def conv2d(image, kernel, stride=1, padding=0):
    """2D卷积操作"""
    if padding > 0:
        image = np.pad(image, padding, mode='constant')
    
    h, w = image.shape
    kh, kw = kernel.shape
    
    output_h = (h - kh) // stride + 1
    output_w = (w - kw) // stride + 1
    output = np.zeros((output_h, output_w))
    
    for i in range(0, output_h * stride, stride):
        for j in range(0, output_w * stride, stride):
            output[i//stride, j//stride] = np.sum(
                image[i:i+kh, j:j+kw] * kernel
            )
    
    return output

# 常用卷积核
kernels = {
    'edge_detection': np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]),
    'blur': np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) / 9,
    'sharpen': np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
}

# 示例图像
image = np.array([
    [1, 2, 3, 0, 1],
    [0, 1, 2, 3, 4],
    [3, 0, 1, 2, 5],
    [2, 3, 0, 1, 2],
    [1, 0, 3, 1, 2]
])

print("卷积操作示例:")
for name, kernel in kernels.items():
    result = conv2d(image, kernel)
    print(f"{name}: {result.shape}")

CNN网络架构

# 构建CNN模型
def build_cnn_model(input_shape, num_classes):
    """构建卷积神经网络"""
    model = keras.Sequential([
        # 第一个卷积块
        keras.layers.Conv2D(32, 3, activation='relu', input_shape=input_shape),
        keras.layers.BatchNormalization(),
        keras.layers.Conv2D(32, 3, activation='relu'),
        keras.layers.MaxPooling2D(2),
        keras.layers.Dropout(0.25),
        
        # 第二个卷积块
        keras.layers.Conv2D(64, 3, activation='relu'),
        keras.layers.BatchNormalization(),
        keras.layers.Conv2D(64, 3, activation='relu'),
        keras.layers.MaxPooling2D(2),
        keras.layers.Dropout(0.25),
        
        # 第三个卷积块
        keras.layers.Conv2D(128, 3, activation='relu'),
        keras.layers.BatchNormalization(),
        keras.layers.Dropout(0.25),
        
        # 全连接层
        keras.layers.Flatten(),
        keras.layers.Dense(512, activation='relu'),
        keras.layers.Dropout(0.5),
        keras.layers.Dense(num_classes, activation='softmax')
    ])
    
    return model

# CNN关键概念
print("CNN关键组件:")
print("• 卷积层: 特征提取,参数共享")
print("• 池化层: 降维,平移不变性")
print("• 批标准化: 加速训练,提高稳定性")
print("• Dropout: 防止过拟合")

图像分类完整案例

使用CNN构建手写数字识别系统(MNIST数据集):

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt

# 1. 数据准备
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# 数据预处理
X_train = X_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0
X_test = X_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

print(f"训练集形状: {X_train.shape}")
print(f"测试集形状: {X_test.shape}")

# 2. 构建CNN模型
model = keras.Sequential([
    # 特征提取层
    keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
    keras.layers.MaxPooling2D(2),
    
    keras.layers.Conv2D(64, 3, activation='relu'),
    keras.layers.MaxPooling2D(2),
    
    keras.layers.Conv2D(64, 3, activation='relu'),
    
    # 分类层
    keras.layers.Flatten(),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(10, activation='softmax')
])

# 3. 编译模型
model.compile(
    optimizer='adam',
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

# 4. 训练模型
history = model.fit(
    X_train, y_train,
    batch_size=128,
    epochs=5,
    validation_split=0.1,
    verbose=1
)

# 5. 评估模型
test_loss, test_accuracy = model.evaluate(X_test, y_test, verbose=0)
print(f"测试准确率: {test_accuracy:.4f}")

# 6. 预测示例
predictions = model.predict(X_test[:5])
for i in range(5):
    predicted_class = np.argmax(predictions[i])
    actual_class = np.argmax(y_test[i])
    print(f"样本{i}: 预测={predicted_class}, 实际={actual_class}")

常见优化算法

深度学习训练的核心是优化算法,用于更新网络参数:

梯度下降变种

  1. 随机梯度下降(SGD) $$w_{t+1} = w_t - \alpha \nabla_w L(w_t)$$

  2. Momentum $$v_t = \beta v_{t-1} + \alpha \nabla_w L(w_t)$$ $$w_{t+1} = w_t - v_t$$

  3. Adam $$m_t = \beta_1 m_{t-1} + (1-\beta_1)\nabla_w L(w_t)$$ $$v_t = \beta_2 v_{t-1} + (1-\beta_2)(\nabla_w L(w_t))^2$$ $$w_{t+1} = w_t - \frac{\alpha \hat{m_t}}{\sqrt{\hat{v_t}} + \epsilon}$$

# 优化器使用示例
optimizers = {
    'SGD': keras.optimizers.SGD(learning_rate=0.01, momentum=0.9),
    'Adam': keras.optimizers.Adam(learning_rate=0.001),
    'RMSprop': keras.optimizers.RMSprop(learning_rate=0.001)
}

# 选择合适的优化器
model.compile(
    optimizer=optimizers['Adam'],
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

深度学习最佳实践

数据准备

  • 数据标准化:均值0,方差1
  • 数据增强:提高泛化能力
  • 合理划分:训练/验证/测试集

模型设计

  • 从简单开始:逐步增加复杂度
  • 正则化技术:Dropout、BatchNorm、权重衰减
  • 残差连接:解决梯度消失问题

训练策略

  • 学习率调度:逐步降低学习率
  • 早停机制:防止过拟合
  • 检查点保存:保存最佳模型

超参数调优

  • 网格搜索或随机搜索
  • 贝叶斯优化
  • 交叉验证

知识连接

info 深度学习知识体系

深度学习是现代人工智能的核心技术,连接传统机器学习与前沿AI应用

前置知识

相关应用

  • 文本挖掘 - 文本分类、情感分析
  • 时间序列 - 序列数据建模
  • 智能客服系统 - NLP在客服场景的应用

进阶方向

框架生态

框架 特点 适用场景
TensorFlow/Keras 工业级,生态完善 生产部署,初学者
PyTorch 灵活动态,研究友好 学术研究,快速原型
JAX 函数式,高性能 科学计算

文档信息

  • 创建时间:2024-06-29
  • 更新时间:2024-06-29
  • 学习时长:150分钟
  • 难度等级:中级

#深度学习 #神经网络 #反向传播 #CNN #TensorFlow #PyTorch #优化算法 #激活函数