李宏毅深度学习课程实战指南
简介:《李宏毅深度学习课程实战指南》是一套系统全面的深度学习入门教程,由台湾大学李宏毅教授主讲。课程从深度学习基础讲起,涵盖神经网络原理、反向传播算法,到主流模型如CNN、RNN、LSTM、GAN等,并结合TensorFlow和PyTorch框架进行实战训练。内容还包括注意力机制、Transformer模型、深度强化学习及在图像识别、自然语言处理等领域的应用,帮助学习者构建扎实的理论基础与实战能力。
1. 深度学习基础概念与历史
1.1 深度学习的定义与核心思想
深度学习是机器学习的一个子领域,其核心在于通过多层次的非线性变换,从原始数据中自动提取高层次的抽象特征。与传统机器学习模型相比,深度学习模型通过“端到端”的方式,省去了大量人工特征工程的步骤。其基本思想是模拟人脑神经元的连接方式,构建多层网络结构,实现对数据的复杂建模与推理。
1.2 神经网络的发展历程
神经网络的研究最早可追溯至20世纪40年代,1943年McCulloch和Pitts提出了第一个神经元模型。1958年,Rosenblatt提出的感知机(Perceptron)是首个可训练的神经网络模型。然而,由于线性不可分问题的限制,感知机在20世纪70年代遭遇瓶颈。直到1986年,Rumelhart等人提出了反向传播算法(Backpropagation),使得多层神经网络的训练成为可能,推动了神经网络的复兴。进入21世纪后,随着大数据和计算能力的提升,深度神经网络(DNN)在图像、语音等任务中取得了突破性进展。
1.3 从感知机到深度神经网络的演进
感知机是单层神经网络,只能解决线性可分问题;而多层感知机(MLP)引入隐藏层和非线性激活函数,突破了线性限制。随后,卷积神经网络(CNN)、循环神经网络(RNN)和长短期记忆网络(LSTM)等结构相继提出,逐步解决了图像、语音和序列数据处理中的难题。2012年,AlexNet在ImageNet竞赛中取得突破性成绩,标志着深度学习进入爆发期。
1.4 深度学习的主要应用领域
深度学习已在多个领域取得广泛应用,主要包括:
| 应用领域 | 典型任务 | 使用模型 |
|---|---|---|
| 图像识别 | 图像分类、目标检测 | CNN(如ResNet、VGG) |
| 自然语言处理 | 机器翻译、文本生成 | RNN、Transformer |
| 语音识别 | 语音转文字、语音合成 | LSTM、CTC模型 |
| 推荐系统 | 用户行为建模、个性化推荐 | 深度兴趣网络 DIN |
| 医疗诊断 | 医学图像分析、疾病预测 | CNN+迁移学习 |
深度学习通过强大的特征学习能力,显著提升了这些领域的性能,成为当前人工智能发展的核心技术之一。
2. 神经网络基本组成与反向传播算法
神经网络是深度学习的核心技术之一,其本质是通过模拟人脑神经元的连接方式,实现对复杂模式的识别和学习。理解神经网络的基本结构和运行机制是深入掌握深度学习的前提。本章将系统性地介绍神经网络的组成模块,包括神经元、激活函数、前向传播机制,以及训练神经网络的关键算法——反向传播(Backpropagation)。
2.1 神经网络的基本结构
神经网络的基本结构由神经元、激活函数、层结构以及前向传播机制构成。理解这些基本单元的原理和功能,有助于我们构建和训练更复杂的网络模型。
2.1.1 神经元与激活函数
神经元是神经网络的基本处理单元,其结构类似于人脑神经元。一个基本的神经元接收多个输入信号,每个输入信号通过一个权重进行加权求和,再加上一个偏置项,最后通过一个激活函数输出结果。
神经元的数学表达式:
y = f\left( \sum_{i=1}^{n} w_i x_i + b \right)
其中:
- $ x_i $:第 $i$ 个输入值
- $ w_i $:第 $i$ 个输入对应的权重
- $ b $:偏置项(bias)
- $ f(\cdot) $:激活函数
- $ y $:神经元的输出
说明 :权重和偏置是神经网络的可训练参数,通过训练数据不断调整,使模型输出更接近真实值。
常见激活函数对比
| 激活函数 | 数学表达式 | 特点 | 应用场景 |
|---|---|---|---|
| Sigmoid | $ \sigma(x) = \frac{1}{1 + e^{-x}} $ | 输出范围在 (0,1),可解释为概率 | 二分类输出层 |
| Tanh | $ \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} $ | 输出范围在 (-1,1),中心对称 | 隐藏层 |
| ReLU | $ \text{ReLU}(x) = \max(0, x) $ | 简单高效,缓解梯度消失 | 隐藏层 |
| Leaky ReLU | $ \text{LeakyReLU}(x) = \max(\alpha x, x) $ | 负数区域也有输出 | 深层网络 |
| Softmax | $ \text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}} $ | 多分类输出概率归一化 | 多分类输出层 |
说明 :选择合适的激活函数对于神经网络的训练效率和最终性能至关重要。例如,ReLU 是目前最常用的隐藏层激活函数,因其简单、高效且能缓解梯度消失问题。
2.1.2 网络层与前向传播
神经网络由多个层组成,每一层由多个神经元构成。常见的层结构包括输入层、隐藏层和输出层。
神经网络的典型结构图(mermaid格式):
graph LR
InputLayer[输入层] --> HiddenLayer[隐藏层]
HiddenLayer --> OutputLayer[输出层]
前向传播过程
前向传播是指输入数据从输入层经过隐藏层逐层传递,最终在输出层得到预测结果的过程。每层的计算可以表示为:
z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)}
a^{(l)} = f(z^{(l)})
其中:
- $ l $:第 $ l $ 层
- $ W^{(l)} $:第 $ l $ 层的权重矩阵
- $ b^{(l)} $:第 $ l $ 层的偏置向量
- $ a^{(l-1)} $:第 $ l-1 $ 层的输出(即第 $ l $ 层的输入)
- $ f(\cdot) $:激活函数
说明 :前向传播是神经网络预测的核心过程,它决定了模型如何根据输入数据生成输出结果。
示例代码:实现一个简单的前向传播
import numpy as np
# 定义激活函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 输入数据(1个样本,3个特征)
X = np.array([1.0, 2.0, 3.0])
# 权重和偏置(隐藏层有2个神经元)
W1 = np.array([[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6]])
b1 = np.array([0.1, 0.2])
# 第一层前向传播
z1 = np.dot(W1, X) + b1
a1 = sigmoid(z1)
# 输出层(1个神经元)
W2 = np.array([0.7, 0.8])
b2 = np.array([0.1])
# 第二层前向传播
z2 = np.dot(W2, a1) + b2
a2 = sigmoid(z2)
print("输出结果:", a2)
代码逻辑逐行分析:
import numpy as np:导入 NumPy 库,用于数组运算。def sigmoid(x)::定义 Sigmoid 激活函数。X = np.array([...]):定义输入特征。W1,b1:定义第一层的权重和偏置。z1 = np.dot(W1, X) + b1:计算第一层的加权和。a1 = sigmoid(z1):应用激活函数得到第一层输出。W2,b2:定义输出层的参数。z2 = np.dot(W2, a1) + b2:计算输出层的加权和。a2 = sigmoid(z2):应用激活函数得到最终输出。print(...):输出预测结果。
说明 :该代码展示了神经网络前向传播的基本流程。虽然结构简单,但体现了神经网络的核心计算方式。
2.2 损失函数与优化方法
为了训练神经网络,我们需要衡量模型预测值与真实值之间的差异,并通过优化算法不断调整模型参数,使损失最小化。
2.2.1 常见损失函数(均方误差、交叉熵)
损失函数(Loss Function)用于衡量模型预测输出与真实标签之间的差距。常见的损失函数包括:
1. 均方误差(Mean Squared Error, MSE)
适用于回归任务:
L = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2
其中:
- $ y_i $:真实值
- $ \hat{y}_i $:预测值
2. 交叉熵损失(Cross Entropy Loss)
适用于分类任务,常用于输出为概率分布的情况。
- 二分类交叉熵损失 :
L = -\frac{1}{n} \sum_{i=1}^{n} [y_i \log(\hat{y}_i) + (1 - y_i)\log(1 - \hat{y}_i)]
- 多分类交叉熵损失(Softmax + Cross Entropy) :
L = -\frac{1}{n} \sum_{i=1}^{n} \sum_{c=1}^{C} y_{ic} \log(\hat{y}_{ic})
其中:
- $ C $:类别数量
- $ y_{ic} $:第 $i$ 个样本的真实类别标签(one-hot 编码)
- $ \hat{y}_{ic} $:第 $i$ 个样本的预测类别概率
2.2.2 梯度下降法与随机梯度下降
梯度下降法(Gradient Descent)是优化神经网络参数的核心方法。其基本思想是通过计算损失函数对参数的梯度,沿着梯度的反方向更新参数,从而最小化损失。
梯度下降法公式:
W^{(t+1)} = W^{(t)} - \eta \cdot \nabla L(W^{(t)})
其中:
- $ W^{(t)} $:第 $t$ 次迭代的参数
- $ \eta $:学习率(learning rate)
- $ \nabla L(W^{(t)}) $:损失函数对参数的梯度
随机梯度下降(SGD)
与标准梯度下降不同,SGD 每次只使用一个样本或一个小批量(mini-batch)样本进行参数更新,提高了训练效率并有助于跳出局部最优。
扩展讨论:学习率选择与优化器演进
学习率的选择直接影响训练速度和收敛效果。学习率过大可能导致震荡不收敛,学习率过小则会导致训练缓慢。为了解决这一问题,研究者提出了多种优化器,如:
- Momentum
- RMSProp
- Adam
这些优化器通过引入动量、自适应学习率等机制,显著提升了训练效率和稳定性。
2.3 反向传播算法详解
反向传播(Backpropagation)是神经网络训练的核心算法。它通过链式法则计算损失函数对每个参数的梯度,从而指导参数更新。
2.3.1 链式法则与梯度计算
反向传播基于链式法则(Chain Rule)逐层计算梯度。以一个简单的三层网络为例,假设损失函数为 $ L $,我们希望计算损失对权重 $ W_2 $ 和 $ W_1 $ 的梯度。
\frac{\partial L}{\partial W_2} = \frac{\partial L}{\partial a_2} \cdot \frac{\partial a_2}{\partial z_2} \cdot \frac{\partial z_2}{\partial W_2}
\frac{\partial L}{\partial W_1} = \frac{\partial L}{\partial a_2} \cdot \frac{\partial a_2}{\partial z_2} \cdot \frac{\partial z_2}{\partial a_1} \cdot \frac{\partial a_1}{\partial z_1} \cdot \frac{\partial z_1}{\partial W_1}
说明 :链式法则使得我们可以从输出层反向传播梯度,逐步计算每一层参数的梯度。
2.3.2 参数更新与训练过程
一旦计算出梯度,就可以使用梯度下降法更新参数:
W \leftarrow W - \eta \cdot \frac{\partial L}{\partial W}
训练过程通常包括以下步骤:
1. 前向传播计算输出和损失;
2. 反向传播计算各参数梯度;
3. 使用梯度下降更新参数;
4. 重复上述过程直到收敛。
2.3.3 反向传播的数学推导与实现示例
我们以一个包含一个隐藏层的神经网络为例,推导其反向传播过程,并实现一个简单的反向传播程序。
推导过程(以 MSE 损失为例)
设损失函数为:
L = \frac{1}{2}(y - \hat{y})^2
其中:
- $ y $:真实值
- $ \hat{y} $:预测值
设:
- 隐藏层输出为 $ a_1 $
- 输出层输出为 $ a_2 $
- 激活函数为 Sigmoid
则损失函数对输出层权重 $ W_2 $ 的梯度为:
\frac{\partial L}{\partial W_2} = (a_2 - y) \cdot a_2 (1 - a_2) \cdot a_1
同理,对隐藏层权重 $ W_1 $ 的梯度为:
\frac{\partial L}{\partial W_1} = (a_2 - y) \cdot a_2 (1 - a_2) \cdot W_2 \cdot a_1 (1 - a_1) \cdot x
实现代码:反向传播示例
import numpy as np
# 激活函数及其导数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
# 真实标签
y = np.array([1.0])
# 输入数据
X = np.array([1.0, 2.0, 3.0])
# 初始化参数
W1 = np.array([[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6]])
b1 = np.array([0.1, 0.2])
W2 = np.array([0.7, 0.8])
b2 = np.array([0.1])
learning_rate = 0.1
# 前向传播
a1 = sigmoid(np.dot(W1, X) + b1)
a2 = sigmoid(np.dot(W2, a1) + b2)
# 计算损失
loss = 0.5 * (y - a2)**2
# 反向传播
delta_output = (a2 - y) * sigmoid_derivative(a2)
dW2 = np.dot(delta_output, a1.T)
db2 = delta_output
delta_hidden = np.dot(W2.T, delta_output) * sigmoid_derivative(a1)
dW1 = np.outer(delta_hidden, X)
db1 = delta_hidden
# 参数更新
W2 -= learning_rate * dW2
b2 -= learning_rate * db2
W1 -= learning_rate * dW1
b1 -= learning_rate * db1
print("更新后的输出值:", a2)
代码逻辑逐行分析:
- 定义激活函数及其导数,用于反向传播计算。
- 设置输入数据和真实标签。
- 初始化权重和偏置。
- 执行前向传播,得到预测值。
- 计算损失值。
- 计算输出层误差和梯度。
- 计算隐藏层误差和梯度。
- 更新参数。
- 输出更新后的预测值。
说明 :该代码展示了反向传播的完整流程,包括梯度计算和参数更新,是理解神经网络训练机制的重要示例。
本章从神经网络的基本结构讲起,逐步深入到前向传播、损失函数、优化方法和反向传播算法,为后续章节中更复杂的网络结构(如 CNN、RNN)打下了坚实的理论基础和实践基础。
3. 前馈神经网络(FFN)设计与实现
3.1 FFN的结构设计
3.1.1 输入层、隐藏层与输出层配置
前馈神经网络(Feedforward Neural Network, FFN)是最基础也是最常用的神经网络结构之一。其结构由三层组成:输入层、隐藏层(一个或多个)和输出层。这些层之间通过权重矩阵连接,并通过激活函数进行非线性变换。
输入层设计
输入层负责接收原始数据。输入层的神经元数量通常与输入特征的维度一致。例如,在图像分类任务中,若输入图像大小为 28×28 的灰度图,则输入层应包含 784 个神经元(28×28 = 784)。
隐藏层设计
隐藏层是网络的核心部分,用于提取数据的高维特征。每一层隐藏层通常包含多个神经元,数量可由用户自定义。常见的隐藏层配置包括单层、多层堆叠结构。例如:
- 单隐藏层:适合简单任务,如手写数字识别(MNIST)
- 多隐藏层:适合复杂任务,如非线性函数逼近或多分类任务
选择隐藏层的数量和每层神经元数量时,需权衡模型复杂度与过拟合风险。通常建议从少量层和神经元开始,逐步增加以观察性能变化。
输出层设计
输出层根据任务类型决定神经元数量及激活函数。例如:
- 二分类任务:输出层 1 个神经元,使用 Sigmoid 激活函数
- 多分类任务:输出层等于类别数,使用 Softmax 激活函数
- 回归任务:输出层 1 个神经元,使用线性激活函数
以下是一个简单的 PyTorch 实现示例,展示三层 FFN 的结构配置:
import torch
import torch.nn as nn
class SimpleFFN(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(SimpleFFN, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim) # 输入层到隐藏层
self.relu = nn.ReLU() # 激活函数
self.fc2 = nn.Linear(hidden_dim, output_dim) # 隐藏层到输出层
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
return out
# 实例化网络
model = SimpleFFN(input_dim=784, hidden_dim=512, output_dim=10)
代码逻辑分析:
fc1:第一层全连接层,将输入特征映射到隐藏层空间。relu:引入非线性,解决线性模型无法拟合复杂函数的问题。fc2:输出层,将隐藏层的特征映射到最终输出空间。forward:定义前向传播流程,数据依次经过线性层和激活函数。
3.1.2 网络深度与宽度对性能的影响
网络的深度(层数)和宽度(每层神经元数量)对模型性能有显著影响。
深度的影响
- 优点 :
- 更深的网络可以学习更复杂的特征表示。
- 有助于捕捉数据的层次化结构。
- 缺点 :
- 增加训练难度,易出现梯度消失/爆炸。
- 更深的网络容易过拟合,需要正则化策略。
宽度的影响
- 优点 :
- 更宽的网络具有更强的表达能力。
- 可以在更少的层数下达到较高的准确率。
- 缺点 :
- 增加参数数量,提升训练成本。
- 过宽的网络可能导致内存不足或训练缓慢。
实验对比分析
| 网络结构 | 层数 | 每层神经元数 | 准确率(MNIST) | 参数数量 |
|---|---|---|---|---|
| 单隐藏层 FFN | 2 | 512 | 97.8% | 407K |
| 两层隐藏层 FFN | 3 | 512-256 | 98.2% | 669K |
| 三层隐藏层 FFN | 4 | 512-256-128 | 98.4% | 921K |
说明:随着网络深度增加,模型性能略有提升,但参数量也显著增加。实际设计中应根据任务复杂度和硬件资源进行权衡。
3.2 FFN的训练流程
3.2.1 数据准备与标准化
在训练 FFN 之前,必须对数据进行预处理。主要包括数据清洗、特征提取、标准化等步骤。
数据标准化示例(使用 PyTorch)
from torchvision import datasets, transforms
# 数据预处理:将像素值标准化到 [-1, 1] 区间
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# 加载 MNIST 数据集
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
参数说明:
transforms.ToTensor():将图像转换为 PyTorch Tensor。transforms.Normalize((0.5,), (0.5,)):将图像像素值标准化为均值为 0,标准差为 1 的分布,有助于加速训练。
3.2.2 批量训练与迭代优化
批量训练(Mini-batch Training)是现代神经网络训练的标准方式。它在每次迭代中使用一个小批量数据来计算梯度并更新参数,既保证了训练效率,又减少了内存占用。
训练过程流程图(mermaid)
graph TD
A[加载训练数据] --> B[初始化模型和优化器]
B --> C[前向传播]
C --> D[计算损失]
D --> E[反向传播]
E --> F[更新参数]
F --> G{是否达到训练轮数?}
G -- 否 --> C
G -- 是 --> H[训练完成]
代码实现:训练 FFN 模型
import torch.optim as optim
# 初始化模型、损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练过程
num_epochs = 5
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.view(-1, 28*28) # 展平图像
# 前向传播
outputs = model(images)
loss = criterion(outputs, labels)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
代码逻辑分析:
images.view(-1, 28*28):将图像展平为一维向量。outputs = model(images):调用模型的forward方法进行预测。loss.backward():计算梯度。optimizer.step():根据梯度更新参数。
3.3 FFN的实战应用
3.3.1 使用 PyTorch/TensorFlow 构建 FFN 模型
除了 PyTorch,TensorFlow 也广泛用于构建 FFN 模型。以下是 TensorFlow 实现 MNIST 分类任务的示例:
import tensorflow as tf
from tensorflow.keras import layers, models
# 构建模型
model = models.Sequential([
layers.Flatten(input_shape=(28, 28)), # 输入层
layers.Dense(512, activation='relu'), # 隐藏层
layers.Dense(10) # 输出层
])
# 编译模型
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 加载数据
(train_images, train_labels), _ = tf.keras.datasets.mnist.load_data()
train_images = train_images / 255.0
# 训练模型
model.fit(train_images, train_labels, epochs=5)
参数说明:
layers.Flatten:将输入图像展平。layers.Dense:全连接层。activation='relu':使用 ReLU 激活函数。SparseCategoricalCrossentropy:适用于整数标签的交叉熵损失函数。
3.3.2 图像分类任务中的 FFN 实现
在图像分类任务中,FFN 通常用于简单任务,如 MNIST 手写数字识别。尽管其性能不如 CNN,但在小数据集上依然有效。
性能对比(FFN vs CNN on MNIST)
| 模型类型 | 准确率(测试集) | 参数数量 | 训练时间(5 epochs) |
|---|---|---|---|
| FFN | 97.5% | 407K | 2.1 min |
| CNN | 99.2% | 1.2M | 3.5 min |
说明:虽然 FFN 在 MNIST 上表现良好,但在更复杂的图像任务(如 CIFAR-10)中,CNN 会显著优于 FFN。
3.3.3 FFN 模型的评估与调优
在训练完成后,需对模型进行评估与调优。常见的评估指标包括准确率、损失值、混淆矩阵等。
模型评估代码(PyTorch)
correct = 0
total = 0
with torch.no_grad():
for images, labels in train_loader:
images = images.view(-1, 28*28)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy of the model on the {total} training images: {100 * correct / total}%')
模型调优策略
- 调整学习率 :尝试不同的学习率(0.001, 0.0001)观察收敛速度。
- 增加正则化 :如 Dropout、L2 正则化防止过拟合。
- 改变网络结构 :增加隐藏层数量或神经元数量以提高表现。
本章详细讲解了 FFN 的结构设计、训练流程与实战应用,涵盖输入输出配置、网络深度宽度影响、数据标准化、训练优化、模型评估与调优等内容,并结合 PyTorch 和 TensorFlow 给出了具体实现示例。
4. 卷积神经网络(CNN)设计与实现
卷积神经网络(Convolutional Neural Network, CNN)是深度学习中最具代表性的模型之一,广泛应用于图像识别、视频处理、自然语言处理等领域。本章将从CNN的基本原理出发,深入探讨其结构设计、经典模型对比、训练流程与实际应用,最终通过代码示例展示如何使用PyTorch/TensorFlow构建和优化CNN模型。
4.1 CNN的基本原理
CNN之所以在图像识别中表现出色,主要得益于其局部感受野和参数共享机制。这些机制不仅减少了模型的参数数量,还增强了模型对图像空间特征的提取能力。
4.1.1 卷积层与池化层的作用
卷积层是CNN的核心组成部分,其作用是从输入图像中提取特征。卷积操作通过一个小型的权重矩阵(称为卷积核或滤波器)在图像上滑动,计算局部区域的加权和,从而生成特征图(Feature Map)。
池化层(Pooling Layer)则用于降低特征图的空间维度,从而减少计算量和参数数量,同时增强模型的平移不变性。常见的池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling)。
下面是一个简单的卷积层和池化层的PyTorch实现示例:
import torch
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3) # 卷积层
self.pool = nn.MaxPool2d(kernel_size=2, stride=2) # 池化层
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x))) # 应用ReLU激活函数后进行池化
return x
代码分析:
nn.Conv2d:定义一个二维卷积层,输入通道数为1(灰度图),输出通道数为16,卷积核大小为3x3。nn.MaxPool2d:最大池化层,池化窗口大小为2x2,步长为2,有效降低特征图尺寸。forward函数中,先进行卷积操作,然后使用ReLU激活函数引入非线性,最后通过池化层压缩特征。
4.1.2 局部感受野与参数共享机制
局部感受野指的是每个神经元只与输入图像的一个局部区域相连,这种设计使得CNN能够有效地捕捉图像的局部特征。而参数共享则是指在卷积过程中,同一个卷积核在整个图像上共享权重,从而大大减少了模型参数数量。
下表对比了全连接网络与CNN在参数数量上的差异:
| 网络类型 | 输入大小 | 层类型 | 输出大小 | 参数数量 |
|---|---|---|---|---|
| 全连接网络 | 28x28 | 全连接层 | 100 | 784x100=78,400 |
| CNN | 28x28 | 卷积层(3x3) | 26x26x16 | 3x3x1x16=144 |
从表中可以看出,CNN通过局部连接和参数共享,显著降低了参数数量,提升了模型的泛化能力。
4.2 CNN的经典结构
随着深度学习的发展,多个经典的CNN结构被提出,包括LeNet、AlexNet、VGG和ResNet等。它们在不同阶段推动了图像识别技术的进步。
4.2.1 LeNet、AlexNet、VGG与ResNet对比
| 模型名称 | 年份 | 特点 | 层数 | 使用场景 |
|---|---|---|---|---|
| LeNet | 1998 | 第一个成功的CNN模型,用于手写数字识别 | 5层 | MNIST |
| AlexNet | 2012 | 使用ReLU激活函数和Dropout机制 | 8层 | ImageNet |
| VGG | 2014 | 使用多个3x3小卷积核堆叠,提升模型表达能力 | 16~19层 | 图像分类 |
| ResNet | 2015 | 引入残差连接,解决深层网络的梯度消失问题 | 152层 | 图像分类、目标检测 |
ResNet的残差结构如下图所示:
graph TD
A[输入] --> B[卷积层]
B --> C[激活函数]
C --> D[卷积层]
D --> E[激活函数]
A --> F[残差连接]
E --> G[输出]
F --> G
残差连接使得网络可以跳过某些层的计算,从而缓解梯度消失问题,使训练更深的网络成为可能。
4.2.2 CNN在图像分类中的应用
CNN在图像分类任务中取得了巨大成功,尤其是在ImageNet竞赛中,Top-5错误率逐年下降。以下是一个使用预训练VGG16模型进行图像分类的示例:
import torchvision.models as models
import torch
# 加载预训练VGG16模型
model = models.vgg16(pretrained=True)
model.eval()
# 输入图像预处理
from torchvision import transforms
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# 假设image是PIL图像
input_tensor = preprocess(image)
input_batch = input_tensor.unsqueeze(0) # 添加batch维度
# 模型推理
with torch.no_grad():
output = model(input_batch)
代码分析:
models.vgg16(pretrained=True):加载预训练的VGG16模型。transforms:对输入图像进行标准化处理,使其符合ImageNet训练时的数据分布。unsqueeze(0):将单张图像扩展为batch形式,以适配模型输入要求。model(input_batch):进行前向传播,输出类别概率。
4.3 CNN的实践操作
在实际应用中,CNN的构建、训练与优化需要结合具体任务进行调整。本节将介绍如何构建自定义CNN模型、进行数据增强、迁移学习以及使用预训练模型进行微调。
4.3.1 构建自定义CNN模型
构建一个适合图像分类任务的CNN模型,通常包括多个卷积层、池化层和全连接层。以下是一个自定义CNN模型的PyTorch实现:
class CustomCNN(nn.Module):
def __init__(self, num_classes=10):
super(CustomCNN, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
nn.Conv2d(64, 128, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
self.classifier = nn.Sequential(
nn.Linear(128 * 8 * 8, 512),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(512, num_classes)
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
代码分析:
features模块:包含两个卷积层和两个池化层,用于提取图像特征。classifier模块:全连接层用于分类任务,使用Dropout防止过拟合。forward函数:定义数据流动方向,先经过特征提取层,再展平后输入分类器。
4.3.2 图像数据增强与迁移学习
数据增强(Data Augmentation)是提高模型泛化能力的重要手段。常见的增强方法包括旋转、翻转、裁剪等。PyTorch中可以通过 torchvision.transforms 实现:
transform = transforms.Compose([
transforms.RandomHorizontalFlip(), # 随机水平翻转
transforms.RandomRotation(10), # 随机旋转
transforms.ColorJitter(brightness=0.2), # 随机调整亮度
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
迁移学习(Transfer Learning)则是利用预训练模型的特征提取能力,快速适应新任务。例如,使用ResNet进行微调:
model = models.resnet18(pretrained=True)
for param in model.parameters():
param.requires_grad = False # 冻结所有层
# 替换最后的全连接层
model.fc = nn.Linear(model.fc.in_features, num_classes)
4.3.3 使用预训练模型进行微调
微调(Fine-tuning)是指在冻结部分层后,对整个模型进行重新训练,以适应新的数据集。以下是完整的训练流程:
import torch.optim as optim
from torch.utils.data import DataLoader
# 假设train_dataset和val_dataset已定义
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# 训练循环
for epoch in range(10): # 训练10个epoch
model.train()
for images, labels in train_loader:
outputs = model(images)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 验证
model.eval()
with torch.no_grad():
correct = 0
total = 0
for images, labels in val_loader:
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"Epoch {epoch+1}, Accuracy: {100 * correct / total}%")
代码分析:
DataLoader:用于批量加载训练和验证数据。CrossEntropyLoss:适用于多分类任务的损失函数。SGD:随机梯度下降优化器,设置学习率和动量。model.train()和model.eval():分别控制模型的训练和评估模式。torch.max:获取预测结果中概率最高的类别。
通过本章的学习,读者应能够掌握CNN的基本原理、经典结构设计、数据增强策略、迁移学习与模型微调方法,并具备独立实现图像分类任务的能力。
5. 循环神经网络(RNN)设计与实现
循环神经网络(Recurrent Neural Network, RNN)是处理序列数据的一类重要神经网络结构,特别适用于自然语言处理、语音识别和时间序列预测等任务。与传统的前馈神经网络(Feedforward Neural Network, FFN)不同,RNN具有记忆能力,可以捕捉序列中的时间依赖关系。
5.1 RNN的基本结构
RNN 的核心思想是通过引入“状态”(state)机制,使得网络能够在处理当前输入的同时保留之前输入的信息。这种机制使得 RNN 非常适合处理像句子、时间序列这样的序列数据。
5.1.1 序列建模与状态传递机制
RNN 的基本结构如图所示:
graph LR
A[Input x_t] --> B(Hidden State h_t)
B --> C[Output y_t]
B --> D[(Hidden State h_{t+1})]
在时间步 $ t $,RNN 接收输入 $ x_t $ 和前一个时间步的隐藏状态 $ h_{t-1} $,计算当前的隐藏状态 $ h_t $ 和输出 $ y_t $。其计算公式如下:
h_t = \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h)
y_t = W_{hy} h_t + b_y
其中:
- $ W_{hh} $:隐藏层到隐藏层的权重矩阵
- $ W_{xh} $:输入层到隐藏层的权重矩阵
- $ W_{hy} $:隐藏层到输出层的权重矩阵
- $ b_h $:隐藏层的偏置项
- $ b_y $:输出层的偏置项
隐藏状态 $ h_t $ 是 RNN 的关键组成部分,它保存了序列中前面时间步的信息,从而实现对序列建模。
5.1.2 Vanilla RNN 的局限性
尽管 RNN 在理论上可以捕捉长距离依赖关系,但在实际训练过程中,Vanilla RNN 存在两个显著问题:
- 梯度消失(Vanishing Gradient) :在反向传播过程中,梯度可能随着时间步的增加而指数级减小,导致模型难以学习远距离依赖。
- 梯度爆炸(Exploding Gradient) :梯度也可能指数级增大,导致参数更新不稳定。
此外,Vanilla RNN 的训练速度较慢,且容易陷入局部最优解。这些局限性促使了后续 RNN 变体的发展,如 LSTM 和 GRU。
5.2 RNN 的变体与改进
为了解决 Vanilla RNN 的局限性,研究者提出了多种改进结构,包括多层 RNN、双向 RNN 等,使得 RNN 在处理复杂序列任务时更具表现力。
5.2.1 多层 RNN 与双向 RNN
多层 RNN(Deep RNN)
多层 RNN 是将多个 RNN 层堆叠在一起,形成更深层次的网络结构。每一层的输出作为下一层的输入,从而增强模型的表示能力。
其结构如下:
graph LR
A[Input x_t] --> B[Layer 1]
B --> C[Layer 2]
C --> D[Layer 3]
D --> E[Output y_t]
多层 RNN 可以更好地捕捉序列数据中的高阶抽象特征,但也增加了训练难度和计算开销。
双向 RNN(Bidirectional RNN)
双向 RNN 能够同时捕捉序列中过去和未来的上下文信息。它由两个方向相反的 RNN 组成:一个从左到右处理序列,另一个从右到左处理序列。
其结构如下:
graph LR
A[Input x_t] --> B1[Forward RNN]
A --> B2[Backward RNN]
B1 --> C[Concatenate]
B2 --> C
C --> D[Output y_t]
输出 $ y_t $ 由前向和后向隐藏状态拼接而成:
y_t = W_{y} [h_t^{\rightarrow}; h_t^{\leftarrow}] + b_y
双向 RNN 在自然语言处理中尤为有效,因为它可以同时考虑上下文信息。
5.2.2 RNN 在语言模型中的应用
语言模型的目标是根据已有的词预测下一个词,RNN 是构建语言模型的经典选择。
语言模型训练流程
- 数据预处理 :将文本数据转换为词向量(Word Embedding)。
- 构建 RNN 模型 :使用 Vanilla RNN、LSTM 或 GRU。
- 定义损失函数 :通常使用交叉熵损失函数。
- 训练模型 :通过反向传播优化参数。
- 生成文本 :利用训练好的模型进行文本生成。
示例代码:使用 PyTorch 构建简单 RNN 语言模型
import torch
import torch.nn as nn
class RNNModel(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim, num_layers):
super(RNNModel, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.rnn = nn.RNN(embed_dim, hidden_dim, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_dim, vocab_size)
def forward(self, x, hidden):
x = self.embedding(x) # [batch_size, seq_len, embed_dim]
out, hidden = self.rnn(x, hidden) # out: [batch_size, seq_len, hidden_dim]
out = self.fc(out) # out: [batch_size, seq_len, vocab_size]
return out, hidden
# 参数定义
vocab_size = 10000 # 词汇表大小
embed_dim = 256 # 词向量维度
hidden_dim = 512 # 隐藏层维度
num_layers = 1 # RNN层数
# 初始化模型
model = RNNModel(vocab_size, embed_dim, hidden_dim, num_layers)
# 示例输入
input_seq = torch.randint(0, vocab_size, (32, 20)) # batch_size=32, seq_len=20
hidden = torch.zeros(num_layers, 32, hidden_dim) # 初始隐藏状态
# 前向传播
output, hidden = model(input_seq, hidden)
print(output.shape) # 输出:torch.Size([32, 20, 10000])
代码逻辑分析:
- Embedding 层 :将输入的词索引转换为词向量。
- RNN 层 :处理序列数据,保留上下文信息。
- 全连接层(FC) :将 RNN 输出映射到词汇表空间,用于预测下一个词。
- forward 方法 :接受输入序列和初始隐藏状态,返回预测结果和更新后的隐藏状态。
5.3 RNN 的训练与优化
RNN 的训练过程与传统神经网络类似,但其特有的时间依赖性使得训练更加复杂,需要特别注意梯度消失和爆炸问题。
5.3.1 梯度消失与梯度爆炸问题
在反向传播过程中,RNN 的梯度会随着时间步的增加而不断乘以权重矩阵,可能导致梯度指数级减小(消失)或增大(爆炸)。
解决方案:
- 梯度裁剪(Gradient Clipping) :限制梯度的最大值,防止梯度爆炸。
- 使用 LSTM 或 GRU 替代 Vanilla RNN :这些结构引入门控机制,缓解梯度消失问题。
- 权重初始化 :合理初始化权重矩阵,避免梯度不稳定。
5.3.2 RNN 模型的训练技巧与调参
训练 RNN 时,需要注意以下技巧:
- 学习率调整 :使用学习率衰减策略(如
StepLR或ReduceLROnPlateau)。 - 批量训练 :采用小批量(mini-batch)训练,提高训练效率。
- 正则化 :加入 Dropout 层防止过拟合。
- 初始化隐藏状态 :在每个训练批次开始时重新初始化隐藏状态。
训练流程示例(PyTorch)
import torch.optim as optim
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练循环
for epoch in range(10): # 迭代10轮
model.train()
hidden = torch.zeros(num_layers, 32, hidden_dim) # 初始隐藏状态
for batch in data_loader:
inputs, targets = batch
optimizer.zero_grad()
outputs, hidden = model(inputs, hidden)
loss = criterion(outputs.view(-1, vocab_size), targets.view(-1))
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5) # 梯度裁剪
optimizer.step()
参数说明:
data_loader:封装好的数据迭代器,每次返回一个批次的数据。inputs:当前批次的输入词索引,形状为[batch_size, seq_len]。targets:目标词索引,形状与输入相同。clip_grad_norm_:对梯度进行裁剪,最大范数为 0.5。
5.3.3 使用 PyTorch 实现 RNN 文本生成
在训练完 RNN 模型后,可以使用其进行文本生成。以下是一个简单的文本生成函数:
def generate_text(model, start_words, length=100):
model.eval()
hidden = torch.zeros(num_layers, 1, hidden_dim)
input_word = torch.tensor([word_to_idx[start_words[0]]]) # 起始词索引
generated = [start_words[0]]
for _ in range(length):
output, hidden = model(input_word.unsqueeze(0), hidden)
_, topi = output.topk(1)
word_idx = topi.item()
generated.append(idx_to_word[word_idx])
input_word = torch.tensor([word_idx])
return ' '.join(generated)
# 示例调用
generated_text = generate_text(model, start_words=["Once"])
print(generated_text)
代码逻辑分析:
- 模型评估模式 :
model.eval()禁用 Dropout 和 BatchNorm。 - 初始化输入 :从起始词开始生成。
- 循环生成 :每一步预测下一个词,并将其作为下一轮的输入。
- topk :选取概率最高的词作为输出。
总结
本章系统地介绍了 RNN 的基本结构、变体及其在语言模型中的应用。我们详细分析了 Vanilla RNN 的局限性,并介绍了多层 RNN 和双向 RNN 等改进结构。最后,我们通过 PyTorch 实现了一个完整的 RNN 语言模型,并展示了其文本生成能力。这些内容为后续章节中更高级的序列建模方法(如 LSTM 和 Transformer)打下了坚实基础。
6. 长短期记忆网络(LSTM)设计与实现
6.1 LSTM的结构与原理
长短期记忆网络(Long Short-Term Memory,简称 LSTM)是循环神经网络(RNN)的一种重要变体,专门用于解决传统 RNN 中的梯度消失和梯度爆炸问题。LSTM 的核心思想是引入“记忆单元”(Memory Cell)和三个门控机制(Gate Mechanism):输入门、遗忘门和输出门。这些结构使得 LSTM 能够在处理长序列时保留重要的历史信息,同时遗忘不相关的信息。
6.1.1 记忆单元与门控机制
LSTM 的基本单元是记忆单元,它通过门控机制控制信息的流动。每个时间步的输入包括当前输入 $x_t$ 和上一时刻的隐藏状态 $h_{t-1}$。
- 输入门(Input Gate) :决定当前输入中哪些信息需要更新到记忆单元中。
- 遗忘门(Forget Gate) :决定哪些信息需要从记忆单元中遗忘。
- 输出门(Output Gate) :决定当前记忆单元的输出如何影响隐藏状态。
数学表达如下:
\begin{aligned}
f_t &= \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) \quad \text{(遗忘门)} \
i_t &= \sigma(W_i \cdot [h_{t-1}, x_t] + b_i) \quad \text{(输入门)} \
\tilde{C} t &= \tanh(W_C \cdot [h {t-1}, x_t] + b_C) \quad \text{(候选记忆)} \
C_t &= f_t \odot C_{t-1} + i_t \odot \tilde{C} t \quad \text{(更新记忆单元)} \
o_t &= \sigma(W_o \cdot [h {t-1}, x_t] + b_o) \quad \text{(输出门)} \
h_t &= o_t \odot \tanh(C_t) \quad \text{(输出隐藏状态)}
\end{aligned}
其中,$\sigma$ 是 Sigmoid 激活函数,$\tanh$ 是双曲正切函数,$\odot$ 表示按元素相乘。
6.1.2 输入门、遗忘门与输出门的作用
- 输入门 控制当前输入中有多少信息可以进入记忆单元。
- 遗忘门 决定前一个记忆单元中有多少信息需要保留。
- 输出门 控制当前记忆单元的输出对隐藏状态的影响。
这种结构使得 LSTM 在处理长序列时能够选择性地记住或遗忘信息,从而缓解了传统 RNN 的长期依赖问题。
6.2 LSTM与GRU对比
虽然 LSTM 在处理序列问题上表现优异,但它结构复杂,计算量较大。门控循环单元(Gated Recurrent Unit,GRU)是 LSTM 的简化版本,它将输入门和遗忘门合并为一个更新门(Update Gate),并且没有单独的记忆单元。
6.2.1 GRU的简化结构
GRU 的核心结构包括:
- 更新门(Update Gate) :控制前一状态中有多少信息需要保留。
- 重置门(Reset Gate) :决定是否忽略前一状态的信息。
数学表达如下:
\begin{aligned}
z_t &= \sigma(W_z \cdot [h_{t-1}, x_t] + b_z) \quad \text{(更新门)} \
r_t &= \sigma(W_r \cdot [h_{t-1}, x_t] + b_r) \quad \text{(重置门)} \
\tilde{h} t &= \tanh(W_h \cdot [r_t \odot h {t-1}, x_t] + b_h) \quad \text{(候选隐藏状态)} \
h_t &= (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t \quad \text{(最终隐藏状态)}
\end{aligned}
6.2.2 不同任务中的性能差异
| 模型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| LSTM | 长期依赖能力强,适合复杂任务 | 结构复杂,训练慢 | 语言建模、机器翻译 |
| GRU | 结构简单,训练速度快 | 略逊于 LSTM | 短序列任务、资源有限场景 |
在实践中,LSTM 通常在需要强记忆能力的任务中表现更优,而 GRU 更适合对计算资源敏感的场景。
6.3 LSTM的实战应用
在实际应用中,我们可以使用深度学习框架如 PyTorch 或 TensorFlow 来构建和训练 LSTM 模型。下面以时间序列预测为例,展示如何使用 PyTorch 构建一个简单的 LSTM 模型。
6.3.1 使用LSTM进行时间序列预测
我们将使用 LSTM 来预测正弦波的时间序列数据。
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
# 生成正弦波数据
def generate_sine_data(seq_length=50, num_samples=1000):
X = []
y = []
for i in range(num_samples):
start = np.random.rand() * 4 * np.pi
x = np.sin(np.linspace(start, start + 4 * np.pi, seq_length + 1))
X.append(x[:-1].reshape(-1, 1))
y.append(x[-1])
return np.array(X), np.array(y)
X, y = generate_sine_data()
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.float32).unsqueeze(1)
# 定义LSTM模型
class LSTMModel(nn.Module):
def __init__(self, input_size=1, hidden_size=32, num_layers=1, output_size=1):
super(LSTMModel, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.linear = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.lstm(x)
out = self.linear(out[:, -1, :])
return out
model = LSTMModel()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# 训练模型
for epoch in range(100):
outputs = model(X)
loss = criterion(outputs, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')
# 可视化预测结果
predicted = model(X).detach().numpy()
plt.plot(y.numpy(), label='True')
plt.plot(predicted, label='Predicted')
plt.legend()
plt.show()
代码说明:
generate_sine_data:生成正弦波时间序列数据,用于训练 LSTM。LSTMModel:定义了一个包含单层 LSTM 和全连接层的模型。forward:定义了模型的前向传播过程。train:使用均方误差损失和 Adam 优化器进行训练。predict:可视化模型预测结果与真实值对比。
6.3.2 LSTM在机器翻译中的实现
在机器翻译任务中,LSTM 被广泛应用于序列到序列(Seq2Seq)模型中,其中编码器-解码器结构非常典型。
- 编码器(Encoder) :将源语言(如英语)编码为上下文向量(context vector)。
- 解码器(Decoder) :基于上下文向量解码出目标语言(如法语)。
PyTorch 提供了 nn.LSTM 和 nn.LSTMCell 接口,可以方便地构建 Seq2Seq 模型。通常还需要使用嵌入层(Embedding Layer)将词索引映射为词向量,并使用注意力机制(Attention)来提升翻译质量。
6.3.3 调整LSTM模型超参数与性能优化
LSTM 模型的性能受多个超参数影响,常见的调参建议如下:
| 超参数 | 调整建议 |
|---|---|
| 隐藏层大小(hidden_size) | 增大可提升模型容量,但也可能导致过拟合 |
| 层数(num_layers) | 2~3 层通常足够,深层 LSTM 需要更多数据 |
| 学习率(learning_rate) | 0.001~0.01,使用学习率调度器(Scheduler)动态调整 |
| 批大小(batch_size) | 根据显存大小调整,通常 32~128 |
| dropout | 在 LSTM 层之间添加 Dropout,防止过拟合 |
此外,使用 Teacher Forcing 技术可以加速解码器的训练,即在训练阶段将真实目标值作为下一个时间步的输入,而不是模型的预测值。
以上内容展示了 LSTM 的结构原理、与 GRU 的对比以及在实际任务中的实现方式。下一章节将深入探讨注意力机制与 Transformer 模型的设计思想与实现方法。
简介:《李宏毅深度学习课程实战指南》是一套系统全面的深度学习入门教程,由台湾大学李宏毅教授主讲。课程从深度学习基础讲起,涵盖神经网络原理、反向传播算法,到主流模型如CNN、RNN、LSTM、GAN等,并结合TensorFlow和PyTorch框架进行实战训练。内容还包括注意力机制、Transformer模型、深度强化学习及在图像识别、自然语言处理等领域的应用,帮助学习者构建扎实的理论基础与实战能力。
更多推荐



所有评论(0)