深度学习知识点总结

什么是深度学习?

引入:从大脑的启发到算法的设计

现代的神经网络并不是凭空产生的,它的灵感来自人类大脑的工作方式。

在我们的神经系统中,神经元(Neuron)通过"接收信号 → 判断 → 传递"的方式协同工作,构成了感知、记忆和决策的基础。
科学家受到这一机制的启发,尝试用数学和计算的方法去模拟这种"层层处理信息"的过程,于是便有了人工神经元,以及由它们组成的
神经网络

而当这种网络的层数不断加深、能力不断增强时,就发展成了今天我们所说的------深度学习


一、神经网络与深度学习的基本概念

在正式学习之前,我们先要明确两个核心术语的含义和关系。

📚 神经网络(Neural Network)

神经网络 是由大量人工神经元按照层次结构连接组成的计算模型,用于从数据中学习输入与输出之间的映射关系。

它本质上是一个由"计算单元"构成的函数,可以自动提取数据特征、组合信息,并给出预测或分类结果。

📚 深度学习(Deep Learning)

深度学习 是机器学习的一个分支,通过 多层神经网络 自动从原始数据中学习特征表示和决策规则。

可以这样理解:

  • 神经网络是"结构"
  • 深度学习是"方法"
  • 深度学习 = 用多层神经网络解决复杂问题的机器学习技术

📍 一句话理解:神经网络是"骨架",深度学习是"能力"。


二、神经元:神经网络的基本计算单元

神经网络的最小组成部分是 人工神经元(Artificial Neuron)。它的设计思路与生物神经元类似,但用数学形式实现了"接收---计算---输出"的过程。

🧠 人工神经元的工作原理

一个人工神经元接收多个输入,对它们进行加权求和,并加上偏置项,然后通过激活函数决定输出:

y=f(w1x1+w2x2+⋯+wnxn+b) y = f(w_1 x_1 + w_2 x_2 + \dots + w_n x_n + b) y=f(w1x1+w2x2+⋯+wnxn+b)

  • x_i:输入特征
  • wiw_iwi:权重(特征的重要性)
  • bbb:偏置项(调整阈值)
  • f(\cdot):激活函数(决定是否"激活")

👉 它就像一个"计算器",会根据输入信号的强弱来输出不同的结果。

🧪 举个例子

判断"今天要不要点外卖":

输入 含义 权重
x1x_1x1 是否很饿
x2x_2x2 冰箱里有无食材
x3x_3x3 天气是否恶劣

神经元会对这些输入求和,如果"信号"超过阈值,则输出"点外卖",否则"不点"。


🔧 激活函数详解

激活函数是神经网络的"灵魂",它为网络引入了非线性,使得神经网络能够学习复杂的模式。

为什么需要激活函数?

如果没有激活函数,无论神经网络有多少层,它本质上都只是一个线性变换:

y=W2(W1x+b1)+b2=W2W1x+W2b1+b2 y = W_2(W_1x + b_1) + b_2 = W_2W_1x + W_2b_1 + b_2 y=W2(W1x+b1)+b2=W2W1x+W2b1+b2

这样就无法学习复杂的非线性关系。

常见的激活函数

1. Sigmoid 函数

σ(x)=11+e−x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+e−x1

  • 输出范围:(0, 1)
  • 特点:将输入压缩到 0-1 之间,适合二分类输出层
  • 缺点:梯度消失问题(当输入很大或很小时,梯度接近 0)

2. ReLU(Rectified Linear Unit)

ReLU(x)=max⁡(0,x) \text{ReLU}(x) = \max(0, x) ReLU(x)=max(0,x)

  • 输出范围:[0, +∞)
  • 特点:计算简单,收敛快,是目前最常用的激活函数
  • 缺点:可能出现"死亡 ReLU"问题(负数输入永远输出 0)

3. Tanh(双曲正切)

tanh⁡(x)=ex−e−xex+e−x \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=ex+e−xex−e−x

  • 输出范围:(-1, 1)
  • 特点:输出以 0 为中心,适合隐藏层
  • 缺点:梯度消失问题

4. Leaky ReLU

LeakyReLU(x)={xif x>0αxif x≤0 \text{LeakyReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha x & \text{if } x \leq 0 \end{cases} LeakyReLU(x)={xαxif x>0if x≤0

  • 输出范围:(-∞, +∞)
  • 特点:解决了 ReLU 的"死亡"问题
  • α 通常取 0.01
Python 代码示例
python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 定义激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def relu(x):
    return np.maximum(0, x)

def tanh(x):
    return np.tanh(x)

def leaky_relu(x, alpha=0.01):
    return np.where(x > 0, x, alpha * x)

# 可视化
x = np.linspace(-5, 5, 100)

fig, axes = plt.subplots(2, 2, figsize=(12, 10))

axes[0, 0].plot(x, sigmoid(x))
axes[0, 0].set_title('Sigmoid')
axes[0, 0].grid(True)

axes[0, 1].plot(x, relu(x))
axes[0, 1].set_title('ReLU')
axes[0, 1].grid(True)

axes[1, 0].plot(x, tanh(x))
axes[1, 0].set_title('Tanh')
axes[1, 0].grid(True)

axes[1, 1].plot(x, leaky_relu(x))
axes[1, 1].set_title('Leaky ReLU')
axes[1, 1].grid(True)

plt.tight_layout()
plt.show()
如何选择激活函数?
层类型 推荐激活函数 原因
隐藏层 ReLU 或 Leaky ReLU 计算快,避免梯度消失
二分类输出层 Sigmoid 输出概率,范围 (0, 1)
多分类输出层 Softmax 输出各类别概率
回归输出层 无激活函数(线性) 输出任意实数

三、神经网络:从单元到系统

单个神经元的计算能力有限,但当大量神经元连接在一起时,就能表达更复杂的函数关系,解决图像识别、语音识别、自然语言理解等任务。

🧬 神经网络的基本结构

复制代码
输入层(Input) → 隐藏层(Hidden) → 输出层(Output)
  • 输入层:接收原始数据(如像素、词向量)
  • 隐藏层:逐层提炼特征,组合信息
  • 输出层:输出最终结果

可以把神经网络看成"数据加工流水线":数据从输入层进入,经过每一层的加工被逐步抽象,最终产出决策。

📍 示例流程:

  • 输入:一张图片
  • 隐藏层:提取边缘 → 组合形状 → 理解语义
  • 输出层:分类为"猫"或"狗"

四、深度学习:神经网络的进化

早期的神经网络层数很浅,表达能力有限。随着算力和数据的增长,我们可以堆叠更多层、构建更深的模型,从而具备更强的特征提炼和抽象能力------这就是深度学习

📚 "深度"的含义

"深度"指的是神经网络中隐藏层 的层数。"深度学习"并不是全新的算法,而是指通过 多层隐藏层 自动从数据中学习复杂特征。

📍 重要区分

  • 浅层网络:只有 1-2 个隐藏层
  • 深度网络:有多个隐藏层(通常 3 层以上)
  • 输入层和输出层不计入"深度"

每一层都在做"抽象":

  • 第 1 层:提取低级特征(线条、边缘)
  • 第 2 层:组合中级特征(形状、结构)
  • 第 3 层:抽象高级语义(物体、情感)

👉 正是这种"层层抽象"的机制,让深度学习能直接从原始数据中学出复杂的模式。


五、深度学习的价值与特点

深度学习成为现代 AI 技术的核心,是因为它具备以下关键能力:

特性 说明
🤖 自动学习 不需手工设计特征,模型可直接从数据中提炼信息
📈 强大表达力 多层结构几乎可以逼近任意复杂函数
🔁 迁移泛化 已学知识可迁移到新任务
🚀 可扩展性 随着数据和算力增长,性能几乎线性提升

六、神经网络如何学习:损失函数、反向传播与优化器

前面我们介绍了神经网络的结构,但神经网络如何"学习"呢?这需要三个关键组件:损失函数反向传播优化器

📊 损失函数:衡量预测的好坏

损失函数(Loss Function)用于衡量模型预测值与真实值之间的差距。损失越小,模型预测越准确。

常见的损失函数

1. 均方误差(MSE)- 用于回归问题

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

  • 适用场景:房价预测、温度预测等回归任务
  • 特点:对大误差敏感,容易受异常值影响

2. 交叉熵损失(Cross-Entropy)- 用于分类问题

Cross-Entropy=−∑i=1nyilog⁡(y^i) \text{Cross-Entropy} = -\sum_{i=1}^{n}y_i\log(\hat{y}_i) Cross-Entropy=−i=1∑nyilog(y^i)

  • 适用场景:图像分类、文本分类等分类任务
  • 特点:衡量两个概率分布的差异

3. 二元交叉熵(Binary Cross-Entropy)- 用于二分类

BCE=−ylog⁡(y\^)+(1−y)log⁡(1−y\^) \text{BCE} = -y\\log(\\hat{y}) + (1-y)\\log(1-\\hat{y}) BCE=−ylog(y\^)+(1−y)log(1−y\^)

  • 适用场景:判断是否为垃圾邮件、是否患病等二分类任务
Python 代码示例
python 复制代码
import numpy as np

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

# 二元交叉熵
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, 1])
y_pred = np.array([0.9, 0.1, 0.8, 0.7])

print(f"MSE Loss: {mse_loss(y_true, y_pred):.4f}")
print(f"BCE Loss: {binary_cross_entropy(y_true, y_pred):.4f}")

🔄 反向传播:计算梯度的核心算法

反向传播(Backpropagation)是神经网络训练的核心算法,它通过链式法则计算损失函数对每个参数的梯度。

工作原理
  1. 前向传播:输入数据通过网络,计算预测值
  2. 计算损失:比较预测值和真实值,计算损失
  3. 反向传播:从输出层向输入层反向计算梯度
  4. 更新参数:根据梯度调整权重和偏置
链式法则

反向传播的核心是链式法则。假设有一个复合函数:

y=f(g(x)) y = f(g(x)) y=f(g(x))

那么它的导数是:

dydx=dydg⋅dgdx \frac{dy}{dx} = \frac{dy}{dg} \cdot \frac{dg}{dx} dxdy=dgdy⋅dxdg

在神经网络中,每一层的梯度都通过链式法则传递:

∂L∂w(l)=∂L∂a(l)⋅∂a(l)∂z(l)⋅∂z(l)∂w(l) \frac{\partial L}{\partial w^{(l)}} = \frac{\partial L}{\partial a^{(l)}} \cdot \frac{\partial a^{(l)}}{\partial z^{(l)}} \cdot \frac{\partial z^{(l)}}{\partial w^{(l)}} ∂w(l)∂L=∂a(l)∂L⋅∂z(l)∂a(l)⋅∂w(l)∂z(l)

其中:

  • LLL:损失函数
  • a(l)a^{(l)}a(l):第 lll 层的激活输出
  • z(l)z^{(l)}z(l):第 lll 层的加权输入
  • w(l)w^{(l)}w(l):第 lll 层的权重
Python 代码示例:简单的反向传播
python 复制代码
import numpy as np

# 简单的单层神经网络
class SimpleNeuralNetwork:
    def __init__(self, input_size, hidden_size, output_size):
        # 初始化权重
        self.W1 = np.random.randn(input_size, hidden_size) * 0.01
        self.b1 = np.zeros((1, hidden_size))
        self.W2 = np.random.randn(hidden_size, output_size) * 0.01
        self.b2 = np.zeros((1, output_size))

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    def sigmoid_derivative(self, x):
        return x * (1 - x)

    def forward(self, X):
        # 前向传播
        self.z1 = np.dot(X, self.W1) + self.b1
        self.a1 = self.sigmoid(self.z1)
        self.z2 = np.dot(self.a1, self.W2) + self.b2
        self.a2 = self.sigmoid(self.z2)
        return self.a2

    def backward(self, X, y, learning_rate=0.1):
        m = X.shape[0]

        # 计算输出层误差
        dz2 = self.a2 - y
        dW2 = (1/m) * np.dot(self.a1.T, dz2)
        db2 = (1/m) * np.sum(dz2, axis=0, keepdims=True)

        # 计算隐藏层误差
        dz1 = np.dot(dz2, self.W2.T) * self.sigmoid_derivative(self.a1)
        dW1 = (1/m) * np.dot(X.T, dz1)
        db1 = (1/m) * np.sum(dz1, axis=0, keepdims=True)

        # 更新参数
        self.W2 -= learning_rate * dW2
        self.b2 -= learning_rate * db2
        self.W1 -= learning_rate * dW1
        self.b1 -= learning_rate * db1

    def train(self, X, y, epochs=1000):
        for epoch in range(epochs):
            # 前向传播
            output = self.forward(X)

            # 反向传播
            self.backward(X, y)

            # 计算损失
            loss = -np.mean(y * np.log(output) + (1 - y) * np.log(1 - output))

            if epoch % 100 == 0:
                print(f"Epoch {epoch}, Loss: {loss:.4f}")

# 示例:XOR 问题
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

nn = SimpleNeuralNetwork(2, 4, 1)
nn.train(X, y, epochs=1000)

# 测试
predictions = nn.forward(X)
print("\n预测结果:")
print(predictions)

⚙️ 优化器:如何更新参数

优化器决定了如何根据梯度更新神经网络的参数。不同的优化器有不同的更新策略。

常见的优化器

1. 随机梯度下降(SGD)

wt+1=wt−η⋅∇L(wt) w_{t+1} = w_t - \eta \cdot \nabla L(w_t) wt+1=wt−η⋅∇L(wt)

  • 特点:简单直接,但容易陷入局部最小值
  • η\etaη:学习率

2. 动量法(Momentum)

vt=γvt−1+η∇L(wt) v_t = \gamma v_{t-1} + \eta \nabla L(w_t) vt=γvt−1+η∇L(wt)

wt+1=wt−vt w_{t+1} = w_t - v_t wt+1=wt−vt

  • 特点:积累历史梯度,加速收敛
  • γ\gammaγ:动量系数(通常 0.9)

3. Adam(Adaptive Moment Estimation)

  • 特点:结合了动量法和自适应学习率
  • 是目前最流行的优化器
  • 自动调整每个参数的学习率
Python 代码示例:不同优化器的比较
python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 定义目标函数(Rosenbrock 函数)
def rosenbrock(x, y):
    return (1 - x)**2 + 100 * (y - x**2)**2

# 定义梯度
def rosenbrock_grad(x, y):
    dx = -2 * (1 - x) - 400 * x * (y - x**2)
    dy = 200 * (y - x**2)
    return np.array([dx, dy])

# SGD 优化器
def sgd(start, learning_rate=0.001, epochs=1000):
    path = [start]
    x, y = start
    for _ in range(epochs):
        grad = rosenbrock_grad(x, y)
        x = x - learning_rate * grad[0]
        y = y - learning_rate * grad[1]
        path.append([x, y])
    return np.array(path)

# Momentum 优化器
def momentum(start, learning_rate=0.001, gamma=0.9, epochs=1000):
    path = [start]
    x, y = start
    vx, vy = 0, 0
    for _ in range(epochs):
        grad = rosenbrock_grad(x, y)
        vx = gamma * vx + learning_rate * grad[0]
        vy = gamma * vy + learning_rate * grad[1]
        x = x - vx
        y = y - vy
        path.append([x, y])
    return np.array(path)

# Adam 优化器
def adam(start, learning_rate=0.01, beta1=0.9, beta2=0.999, epsilon=1e-8, epochs=1000):
    path = [start]
    x, y = start
    m = np.array([0.0, 0.0])
    v = np.array([0.0, 0.0])
    for t in range(1, epochs + 1):
        grad = rosenbrock_grad(x, y)
        m = beta1 * m + (1 - beta1) * grad
        v = beta2 * v + (1 - beta2) * (grad ** 2)
        m_hat = m / (1 - beta1 ** t)
        v_hat = v / (1 - beta2 ** t)
        x = x - learning_rate * m_hat[0] / (np.sqrt(v_hat[0]) + epsilon)
        y = y - learning_rate * m_hat[1] / (np.sqrt(v_hat[1]) + epsilon)
        path.append([x, y])
    return np.array(path)

# 运行优化器
start = np.array([-1.0, 1.0])
path_sgd = sgd(start)
path_momentum = momentum(start)
path_adam = adam(start)

# 可视化
plt.figure(figsize=(12, 8))

# 绘制等高线
x = np.linspace(-2, 2, 100)
y = np.linspace(-1, 3, 100)
X, Y = np.meshgrid(x, y)
Z = rosenbrock(X, Y)
plt.contour(X, Y, Z, levels=50, cmap='viridis', alpha=0.6)

# 绘制优化路径
plt.plot(path_sgd[:, 0], path_sgd[:, 1], 'r-', label='SGD', linewidth=2)
plt.plot(path_momentum[:, 0], path_momentum[:, 1], 'g-', label='Momentum', linewidth=2)
plt.plot(path_adam[:, 0], path_adam[:, 1], 'b-', label='Adam', linewidth=2)

plt.plot(1, 1, 'r*', markersize=15, label='最优点')
plt.xlabel('x')
plt.ylabel('y')
plt.title('优化器比较:Rosenbrock 函数')
plt.legend()
plt.colorbar(label='函数值')
plt.show()
如何选择优化器?
优化器 适用场景 优点 缺点
SGD 简单任务 简单、可控 收敛慢、易震荡
Momentum 需要加速收敛 快速、稳定 需要调整动量参数
Adam 大多数任务 自适应、快速 可能过拟合
RMSprop RNN/LSTM 适合非平稳目标 需要调整学习率

📦 总结:从"计算单元"到"学习系统"的演进

阶段 概念 功能
🔹 神经元 基本计算单元 接收输入、计算输出
🔹 神经网络 神经元的组合结构 表达复杂映射关系
🔹 深度学习 多层神经网络方法 自动抽象特征、学习模式规律

📍 一句话总结

深度学习是利用"多层神经网络"从数据中自动学习的机器学习方法。它的基础是神经元,结构是神经网络,目标是通过层层抽象解决复杂问题。

结束了吗?

读到这里,你感觉总是缺了点什么东西?

市面上99%的课程和教材都没有讲到的,那个好像缺掉的东西。

那就是 神经网络的模型本质


神经网络:从单个神经元到"函数的嵌套"

我们前面已经知道,一个人工神经元的计算本质是这样的:

y=f(x)=w1x1+w2x2+⋯+wnxn+b y = f(x) = w_1x_1 + w_2x_2 + \dots + w_nx_n + b y=f(x)=w1x1+w2x2+⋯+wnxn+b

然后再经过一个非线性激活函数(比如 σ\sigmaσ):

z=g(y)=σ(f(x)) z = g(y) = \sigma(f(x)) z=g(y)=σ(f(x))

📍 换句话说:一个神经元本质上就是一个"函数"------它接收输入 xxx,经过加权、求和、非线性变换,输出一个结果 zzz。


🧠 神经网络 = 多层函数的复合

如果我们把很多神经元层层连接起来,那么神经网络整体就变成了"函数的嵌套":

  • 第一层:

    h(1)=g(1)(W(1)x+b(1)) h^{(1)} = g^{(1)}(W^{(1)}x + b^{(1)}) h(1)=g(1)(W(1)x+b(1))

  • 第二层:

    h(2)=g(2)(W(2)h(1)+b(2)) h^{(2)} = g^{(2)}(W^{(2)}h^{(1)} + b^{(2)}) h(2)=g(2)(W(2)h(1)+b(2))

  • 第三层(输出层):

    y^=g(3)(W(3)h(2)+b(3)) \hat{y} = g^{(3)}(W^{(3)}h^{(2)} + b^{(3)}) y^=g(3)(W(3)h(2)+b(3))

最终整个神经网络的计算可以写成:

y^=F(x)=g(3)(W(3)g(2)(W(2)g(1)(W(1)x+b(1))+b(2))+b(3)) \hat{y} = F(x) = g^{(3)}(W^{(3)}g^{(2)}(W^{(2)}g^{(1)}(W^{(1)}x + b^{(1)}) + b^{(2)}) + b^{(3)}) y^=F(x)=g(3)(W(3)g(2)(W(2)g(1)(W(1)x+b(1))+b(2))+b(3))

📍 换句话说,神经网络就是一个由多层线性变换和非线性变换组成的"复合函数"


🔁 直觉理解

你可以这样理解神经网络的工作流程:

  • 输入层:接收原始数据 xxx
  • 第 1 层:做第一次"加权 + 激活" → 得到 h(1)h^{(1)}h(1)
  • 第 2 层:再次"加权 + 激活" → 得到 h(2)h^{(2)}h(2)
  • 输出层:最终计算出预测 y^\hat{y}y^(可能是类别概率、数值预测等)

这一整个计算流程,其实就是:

x→h(1)→h(2)→⋯→y^ x \rightarrow h^{(1)} \rightarrow h^{(2)} \rightarrow \dots \rightarrow \hat{y} x→h(1)→h(2)→⋯→y^

👉 这就是神经网络的本质:

输入特征经过一连串函数变换,逐层提炼信息,最后输出一个预测值或概率。


📦 一个重要的理解方式

📍 神经网络 = 一台"学函数的机器"

  • 我们给它输入数据 xxx 和标签 yyy
  • 它就通过调整 WWW 和 bbb 的值,让复合函数 F(x)F(x)F(x) 尽量逼近 yyy
  • 最终,F(x)F(x)F(x) 就是"从输入到输出"的映射函数

这就是深度学习的本质工作:学习一个足够复杂的函数,把输入映射到正确的输出。


📌 小结:换一个角度看神经网络

角度 理解
结构角度 多个神经元连接成的层次结构
数学角度 一连串线性变换 + 非线性函数的嵌套
功能角度 一个可以从数据中"学习"复杂映射关系的可调函数
学习过程角度 通过不断调整参数 WWW 和 bbb,让 F(x)F(x)F(x) 接近真实输出 yyy

📍 一句话总结

神经网络不是"会思考的程序",它就是一个多层复合函数:输入特征进去,经过层层变换,输出预测结果。深度学习的任务,就是让这个函数通过训练变得"更聪明"。