深度学习期末复习知识点总结

  1. 【本题 10 分】 请把离散的递归神经网络模型 x ( k + 1 ) = f ( w x ( k ) + b ) x(k+1) = f(wx(k) + b) x(k+1)=f(wx(k)+b) 化成连续型神经网络模型。

    要将一个离散时间系统转换为连续时间系统,我们可以使用泰勒展开或直接假设一个小的时间步长 Δ t \Delta t Δt,然后利用差商近似导数。对于给定的离散模型 x ( k + 1 ) = f ( w x ( k ) + b ) x(k+1) = f(wx(k) + b) x(k+1)=f(wx(k)+b),可以将其视为在小时间间隔 Δ t \Delta t Δt 内的变化:
    x ( t + Δ t ) − x ( t ) Δ t ≈ x ˙ ( t ) \frac{x(t+\Delta t) - x(t)}{\Delta t} \approx \dot{x}(t) Δtx(t+Δt)x(t)x˙(t)
    如果我们设 Δ t = 1 \Delta t = 1 Δt=1,则 k k k 对应于时间 t t t,那么我们可以写出:
    x ˙ ( t ) = lim ⁡ Δ t → 0 f ( w x ( t ) + b ) − x ( t ) Δ t \dot{x}(t) = \lim_{\Delta t \to 0} \frac{f(wx(t) + b) - x(t)}{\Delta t} x˙(t)=Δt0limΔtf(wx(t)+b)x(t)
    这通常会简化为某种形式的微分方程,具体取决于激活函数 f f f 的选择。如果 f f f 是线性的,则可以直接得出结果;如果是非线性函数,则可能需要使用微分学的知识来求解。

  2. 【本题 10 分】 简述 PyTorch 框架中实现一个神经网络结构的方法,至少给出 2 种方法。

    • 使用 torch.nn.Module 类:这是最常用的方式,通过继承 nn.Module 类并定义 forward 方法来构建网络。
    • 使用 torch.nn.Sequential 构建简单的顺序模型:当模型是层的简单堆叠时,可以通过传递一系列层到 Sequential 来快速创建模型。
  3. 【本题 20 分】 请解释 LeNet5、AlexNet、ResNet 网络结构特点。

    • LeNet5:由 Yann LeCun 提出,是最早的卷积神经网络之一,用于手写数字识别。它引入了卷积层、池化层和全连接层的概念。
    • AlexNet:由 Alex Krizhevsky 等人提出,赢得了 ImageNet 2012 年挑战赛。它引入了 ReLU 激活函数、dropout 正则化以及更深层次的网络结构。
    • ResNet(残差网络):由 Kaiming He 等人提出,解决了非常深的网络中的梯度消失问题。它通过引入残差块,使得信息可以直接从一层传到多层之后,从而允许训练更深的网络。
  4. 【本题 20 分】 为了防止过拟合,有哪些正则化方法?

    • L2 正则化(权重衰减):向损失函数添加一个惩罚项,以限制参数的大小,从而减少复杂度。
    • Dropout:随机丢弃一部分神经元,迫使网络学习更加鲁棒的特征表示。
    • 数据增强:通过变换现有数据生成新的训练样本,增加数据多样性。
    • 早停(Early Stopping):监控验证集上的性能,并在性能开始下降时停止训练。
  5. 【本题 20 分】 什么是 Dropout?Dropout 有什么作用?ReLU 激活函数相对于传统的 Sigmoid 激活函数有什么优势?

    • Dropout 是一种正则化技术,其中在训练期间随机选择一部分神经元忽略(即设置为零)。这有助于防止复杂的共适应关系,从而提高泛化能力。
    • ReLU (Rectified Linear Unit) 相较于 Sigmoid 的优势在于:
      • 它不会造成梯度消失的问题,因为它的导数要么是 0 要么是 1。
      • 计算效率更高,因为它只涉及阈值操作。
      • 它能够缓解全负输入导致的“死亡神经元”问题,而 Sigmoid 在极端情况下可能会输出几乎恒定的值,导致后续梯度接近于零。
  6. 【本题 20 分】 请给出至少 3 种生成式 AI 模型的例子,并说明其用途。

    • Variational Autoencoders (VAE):用于学习数据的概率分布,可以用来生成与训练数据相似的新样本,如图像、文本等。
    • Generative Adversarial Networks (GAN):包含两个相互竞争的网络——生成器和判别器。广泛应用于图像合成、风格迁移等领域。
    • Transformer-based Models(如 GPT 或 BERT):虽然主要是预训练语言模型,但它们也被用于生成任务,例如文本补全、对话系统和翻译等。


  1. 【本题 10 分】 简述 PyTorch 框架中梯度自动计算的步骤,并举一个例子说明。

    PyTorch 中的梯度自动计算(autograd)是基于计算图的动态机制实现的。其主要步骤如下:

    • 定义模型参数:使用 torch.tensor 定义需要计算梯度的参数,并设置 requires_grad=True
    • 前向传播:通过模型计算输出值。
    • 计算损失:根据输出值和目标值计算损失函数。
    • 反向传播:调用 loss.backward() 计算损失相对于模型参数的梯度。
    • 更新参数:使用优化器(如 torch.optim.SGD)或手动更新参数。
    • 清空梯度:在每次参数更新后,调用 optimizer.zero_grad()tensor.grad.zero_() 清空梯度。

    以下是一个简单的线性回归示例:

    import torch
    
    # 定义输入和输出数据
    x_data = torch.tensor([[1.0], [2.0], [3.0]])
    y_data = torch.tensor([[2.0], [4.0], [6.0]])
    
    # 定义模型参数
    w = torch.tensor(1.0, requires_grad=True)
    
    # 前向传播
    def forward(x):
        return x * w
    
    # 定义损失函数
    def loss(x, y):
        y_pred = forward(x)
        return (y_pred - y) ** 2
    
    # 反向传播与参数更新
    print("Before update: w =", w.item())
    for x_val, y_val in zip(x_data, y_data):
        l = loss(x_val, y_val)
        l.backward()  # 反向传播
        print(f"\tx={x_val.item()}, y={y_val.item()}, loss={l.item():.2f}, grad={w.grad.item():.2f}")
        w.data = w.data - 0.01 * w.grad.data  # 手动更新参数
        w.grad.zero_()  # 清空梯度
    
    print("After update: w =", w.item())
    
  2. 【本题 10 分】 什么是梯度消失和梯度爆炸?有哪些解决梯度消失和梯度爆炸的方法?

    • 梯度消失:在深度神经网络中,反向传播时梯度逐层减小,导致靠近输入层的参数几乎不更新,模型难以训练。
    • 梯度爆炸:反向传播时梯度逐层增大,导致参数更新过大,模型训练不稳定甚至发散。

    解决方法包括:

    • 激活函数:使用 ReLU 或其变体(如 Leaky ReLU)避免梯度饱和。
    • 权重初始化:采用 Xavier 或 He 初始化,确保初始梯度合理。
    • 梯度裁剪:通过 torch.nn.utils.clip_grad_norm_ 限制梯度的最大范数。
    • 残差连接:在 ResNet 中引入跳跃连接,使梯度能够直接传递到浅层。
    • 正则化:使用 L2 正则化或 Dropout 减少过拟合。
  3. 【本题 20 分】
    (1) 求出下面递归神经网络模型的平衡点。
    d x ( t ) d t = − 3 5 ln ⁡ 2 x ( t ) + g ( x ( t ) ) , 其中  g ( x ) = e x − e − x e x + e − x \frac{dx(t)}{dt} = -\frac{3}{5 \ln 2} x(t) + g(x(t)), \quad \text{其中 } g(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} dtdx(t)=5ln23x(t)+g(x(t)),其中 g(x)=ex+exexex

    平衡点满足 d x ( t ) d t = 0 \frac{dx(t)}{dt} = 0 dtdx(t)=0,即:
    − 3 5 ln ⁡ 2 x ( t ) + g ( x ( t ) ) = 0    ⟹    3 5 ln ⁡ 2 x ( t ) = g ( x ( t ) ) -\frac{3}{5 \ln 2} x(t) + g(x(t)) = 0 \implies \frac{3}{5 \ln 2} x(t) = g(x(t)) 5ln23x(t)+g(x(t))=05ln23x(t)=g(x(t))
    由于 g ( x ) = tanh ⁡ ( x ) g(x) = \tanh(x) g(x)=tanh(x),且 tanh ⁡ ( 0 ) = 0 \tanh(0) = 0 tanh(0)=0,因此 x ( t ) = 0 x(t) = 0 x(t)=0 是一个平衡点。由于 tanh ⁡ ( x ) \tanh(x) tanh(x) 的取值范围为 ( − 1 , 1 ) (-1, 1) (1,1),而左侧是线性函数,因此 x ( t ) = 0 x(t) = 0 x(t)=0 是唯一的实数解。

    (2) 构造能量函数判定其平衡点的稳定性。

    构造能量函数 V ( x ) = 1 2 x 2 V(x) = \frac{1}{2} x^2 V(x)=21x2,它是正定的。计算其导数:
    V ˙ ( x ) = x ⋅ x ˙ = x ( − 3 5 ln ⁡ 2 x + tanh ⁡ ( x ) ) \dot{V}(x) = x \cdot \dot{x} = x \left( -\frac{3}{5 \ln 2} x + \tanh(x) \right) V˙(x)=xx˙=x(5ln23x+tanh(x))
    x ≠ 0 x \neq 0 x=0 时, V ˙ ( x ) < 0 \dot{V}(x) < 0 V˙(x)<0,因此 x = 0 x = 0 x=0 是一个稳定的平衡点。

  4. 【本题 20 分】 什么是 CNN?出现 CNN 的必要性是什么?CNN 的典型网络结构和 CNN 的特点是什么?

    • 卷积神经网络(CNN):一种专门用于处理网格结构数据的深度学习模型,广泛应用于图像处理任务。
    • 必要性:传统全连接网络参数过多,难以处理高维图像数据。CNN 通过卷积操作提取局部特征,减少参数数量,同时保持空间信息。
    • 典型网络结构:包括卷积层、激活层(如 ReLU)、池化层(如最大池化)和全连接层。
    • 特点
      • 局部连接:每个神经元只与输入数据的局部区域相连。
      • 权值共享:卷积核的权重在整张图像上共享。
      • 层次化特征提取:浅层提取边缘等低级特征,深层提取复杂的高级特征。
  5. 【本题 20 分】 什么是 GAN?GAN 的基本结构是什么?请列举至少 2 项你知道的 GAN 的改进模型。

    • 生成对抗网络(GAN):由生成器和判别器组成的双网络模型。生成器生成假数据,判别器区分真假数据,两者通过对抗训练提升性能。
    • 基本结构
      • 生成器:从随机噪声生成数据。
      • 判别器:输入真实数据和生成数据,输出概率。
    • 改进模型
      • Wasserstein GAN (WGAN):使用 Wasserstein 距离替代原始 GAN 的 JS 散度,解决训练不稳定问题。
      • Conditional GAN (cGAN):在生成器和判别器中引入条件变量,控制生成数据的属性。
  6. 【本题 20 分】 请解释梯度下降、随机梯度下降、mini-batch 梯度下降算法,并说明其在 PyTorch 框架中的实现。

    • 梯度下降(GD):使用整个训练集计算梯度,更新参数。计算精确但效率低。
    • 随机梯度下降(SGD):每次迭代使用一个样本计算梯度,更新速度快但波动大。
    • Mini-batch 梯度下降:每次迭代使用一小批样本计算梯度,结合了 GD 和 SGD 的优点。

    在 PyTorch 中,可以通过 torch.optim 模块实现:

    import torch
    import torch.nn as nn
    import torch.optim as optim
    
    # 定义模型
    model = nn.Linear(10, 1)
    
    # 定义损失函数和优化器
    criterion = nn.MSELoss()
    optimizer = optim.SGD(model.parameters(), lr=0.01)
    
    # 训练过程
    for epoch in range(100):
        for x_batch, y_batch in dataloader:  # dataloader 提供 mini-batch 数据
            optimizer.zero_grad()  # 清空梯度
            outputs = model(x_batch)  # 前向传播
            loss = criterion(outputs, y_batch)  # 计算损失
            loss.backward()  # 反向传播
            optimizer.step()  # 更新参数
    


1. 深度学习成功的因素及个人思考

深度学习成功的因素

  • 大数据:深度学习模型需要大量数据进行训练,数据量的增加显著提升了模型的性能。
  • 计算能力:GPU和TPU等硬件的发展使得训练大规模神经网络成为可能。
  • 算法改进:如反向传播、激活函数、正则化技术、优化算法等的改进。
  • 开源生态:TensorFlow、PyTorch等开源框架降低了深度学习的门槛。
  • 理论支持:深度学习理论的不断完善,如深度学习的泛化能力、表示学习等。

个人思考

  • 数据隐私:随着数据量的增加,数据隐私和安全问题日益突出,如何在保护隐私的前提下利用数据是一个重要课题。
  • 模型解释性:深度学习模型通常被视为“黑盒”,提高模型的可解释性是未来的一个重要方向。
  • 能源消耗:训练大规模模型需要大量能源,如何提高能源效率是一个挑战。
  • 多模态学习:结合不同类型的数据(如图像、文本、音频)进行多模态学习是未来的一个趋势。

2. 神经网络常用激活函数、正则化手段、初始化方式、常用 loss 函数

常用激活函数

  • ReLU (Rectified Linear Unit) f ( x ) = max ⁡ ( 0 , x ) f(x) = \max(0, x) f(x)=max(0,x)
  • Leaky ReLU f ( x ) = max ⁡ ( 0.01 x , x ) f(x) = \max(0.01x, x) f(x)=max(0.01x,x)
  • Sigmoid f ( x ) = 1 1 + e − x f(x) = \frac{1}{1 + e^{-x}} f(x)=1+ex1
  • Tanh f ( x ) = e x − e − x e x + e − x f(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} f(x)=ex+exexex
  • Softmax f ( x i ) = e x i ∑ j e x j f(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}} f(xi)=jexjexi

常用正则化手段

  • L1/L2 正则化:在损失函数中加入权重参数的L1或L2范数。
  • Dropout:在训练过程中随机丢弃一部分神经元,防止过拟合。
  • Batch Normalization:对每一层的输入进行归一化,加速训练。

常用初始化方式

  • Xavier 初始化:适用于Sigmoid和Tanh激活函数,保持输入和输出的方差一致。
  • He 初始化:适用于ReLU及其变体,保持输入和输出的方差一致。
  • 随机初始化:随机初始化权重参数。

常用 loss 函数

  • 均方误差 (MSE) L = 1 N ∑ i = 1 N ( y i − y ^ i ) 2 L = \frac{1}{N} \sum_{i=1}^N (y_i - \hat{y}_i)^2 L=N1i=1N(yiy^i)2
  • 交叉熵损失 (Cross-Entropy Loss) L = − ∑ i = 1 N y i log ⁡ ( y ^ i ) L = -\sum_{i=1}^N y_i \log(\hat{y}_i) L=i=1Nyilog(y^i)
  • KL 散度 (Kullback-Leibler Divergence) L = ∑ i = 1 N p ( x i ) log ⁡ p ( x i ) q ( x i ) L = \sum_{i=1}^N p(x_i) \log \frac{p(x_i)}{q(x_i)} L=i=1Np(xi)logq(xi)p(xi)

3. PyTorch 梯度自动计算的步骤和示例伪代码

步骤

  1. 定义模型和损失函数。
  2. 前向传播计算输出和损失。
  3. 反向传播计算梯度。
  4. 更新权重参数。

示例伪代码

# 步骤1: 定义张量,并设置 requires_grad=True
x = Tensor(value, requires_grad=True)
w = Tensor(weight, requires_grad=True)
b = Tensor(bias, requires_grad=True)

# 步骤2: 定义模型(例如简单的线性模型)
y = w * x + b   # 前向传播:y = w * x + b

# 步骤3: 定义损失函数
loss = (y - target) ** 2  # 例如均方误差损失

# 步骤4: 计算梯度(反向传播)
loss.backward()  # 计算每个张量的梯度

# 步骤5: 查看计算得到的梯度
print(w.grad)  # 输出 w 的梯度
print(b.grad)  # 输出 b 的梯度

# 步骤6: 使用优化器更新参数
optimizer = SGD([w, b], lr=0.01)
optimizer.step()  # 根据梯度更新参数

4. 梯度下降类算法的公式、思想、优缺点

梯度下降 (GD)

  • 公式 w t + 1 = w t − η ∇ L ( w t ) w_{t+1} = w_t - \eta \nabla L(w_t) wt+1=wtηL(wt)
  • 思想:沿着损失函数的负梯度方向更新参数,逐步逼近最优解。
  • 优点:简单易实现。
  • 缺点:收敛速度慢,容易陷入局部最优。

随机梯度下降 (SGD)

  • 公式 w t + 1 = w t − η ∇ L i ( w t ) w_{t+1} = w_t - \eta \nabla L_i(w_t) wt+1=wtηLi(wt)
  • 思想:每次迭代只使用一个样本的梯度更新参数。
  • 优点:收敛速度快,避免陷入局部最优。
  • 缺点:噪声大,不稳定。

Momentum

  • 公式 v t + 1 = γ v t + η ∇ L ( w t ) v_{t+1} = \gamma v_t + \eta \nabla L(w_t) vt+1=γvt+ηL(wt) w t + 1 = w t − v t + 1 w_{t+1} = w_t - v_{t+1} wt+1=wtvt+1
  • 思想:引入动量项,加速收敛。
  • 优点:加速收敛,减少震荡。
  • 缺点:需要调整动量参数。

AdaGrad

  • 公式 G t = G t − 1 + ( ∇ L ( w t ) ) 2 G_t = G_{t-1} + (\nabla L(w_t))^2 Gt=Gt1+(L(wt))2 w t + 1 = w t − η G t + ϵ ∇ L ( w t ) w_{t+1} = w_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \nabla L(w_t) wt+1=wtGt+ϵ ηL(wt)
  • 思想:自适应调整学习率,对频繁更新的参数降低学习率。
  • 优点:自适应学习率。
  • 缺点:学习率可能过早衰减。

Adam

  • 公式 m t = β 1 m t − 1 + ( 1 − β 1 ) ∇ L ( w t ) m_t = \beta_1 m_{t-1} + (1 - \beta_1) \nabla L(w_t) mt=β1mt1+(1β1)L(wt) v t = β 2 v t − 1 + ( 1 − β 2 ) ( ∇ L ( w t ) ) 2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) (\nabla L(w_t))^2 vt=β2vt1+(1β2)(L(wt))2 w t + 1 = w t − η m t v t + ϵ w_{t+1} = w_t - \eta \frac{m_t}{\sqrt{v_t} + \epsilon} wt+1=wtηvt +ϵmt
  • 思想:结合Momentum和AdaGrad的优点,自适应调整学习率。
  • 优点:收敛速度快,稳定性好。
  • 缺点:需要调整多个超参数。
1. 算法思想

梯度下降(Gradient Descent, GD)是一种用于优化问题的迭代算法。它通过计算损失函数关于模型参数的梯度(即偏导数),然后沿着梯度的反方向更新参数,以逐步逼近最优解。

  • 梯度:指的是损失函数在某一点的导数,表示了损失函数的变化趋势。
  • 更新规则:每次更新参数时,按照梯度的负方向进行调整。这样可以确保损失函数值逐渐减小。
2. 公式

在梯度下降算法中,参数的更新公式为:
θ ( t + 1 ) = θ ( t ) − η ∇ θ J ( θ ) θ ( t + 1 ) = θ ( t ) − η ∇ θ J ( θ ) θ(t+1)=θ(t)−η∇θJ(θ)\theta^{(t+1)} = \theta^{(t)} - \eta \nabla_{\theta} J(\theta) θ(t+1)=θ(t)ηθJ(θ)θ(t+1)=θ(t)ηθJ(θ)
其中:

  • θ ( t ) \theta^{(t)} θ(t) 是第 t t t次迭代的参数。
  • η \eta η 是学习率(learning rate),一个超参数,控制每次更新的步长。
  • ∇ θ J ( θ ) \nabla_{\theta} J(\theta) θJ(θ) 是损失函数 J ( θ ) J(\theta) J(θ) 关于参数 θ \theta θ 的梯度。
3. 梯度下降的类型
  • 批量梯度下降(Batch Gradient Descent, BGD)
    • 每次更新时使用所有的训练数据。
    • 优点:稳定收敛,最终能够找到全局最小值(假设损失函数是凸的)。
    • 缺点:计算量大,尤其是数据集非常大的时候。
  • 随机梯度下降(Stochastic Gradient Descent, SGD)
    • 每次更新时仅使用一个样本的梯度。
    • 优点:计算开销小,能处理大数据集,且每次更新都可以跳出局部最小值。
    • 缺点:收敛速度较慢,且收敛过程可能较为波动。
  • 小批量梯度下降(Mini-Batch Gradient Descent)
    • 每次更新时使用一个小批量的数据。
    • 优点:结合了批量和随机梯度下降的优点,收敛较为平稳,且计算效率较高。
    • 缺点:需要选择适当的批量大小。
4. 优缺点

优点:

  • 计算效率高:尤其是对于大规模数据集,随机梯度下降或小批量梯度下降能有效减少计算成本。
  • 易于实现:梯度下降方法简单直观,可以应用于多种优化问题。
  • 广泛适用:适用于各种机器学习模型,如线性回归、逻辑回归、神经网络等。

缺点:

  • 可能陷入局部最小值:特别是在非凸函数中,梯度下降可能收敛到局部最小值,而非全局最小值。
  • 选择合适的学习率困难:学习率过大可能导致更新过度,学习率过小可能导致收敛过慢。
  • 收敛速度慢:尤其是对于非常复杂的损失函数,可能需要很多迭代才能收敛。
  • 对初始值敏感:不同的初始化可能会影响收敛速度和结果。

总结

梯度下降是一个简单且强大的优化算法,适用于很多机器学习模型。它的核心思想是通过不断调整参数,沿着损失函数的最陡下降方向寻找最优解。虽然它有一些缺点(如可能陷入局部最小值、对学习率敏感等),但通过合理选择变种(如随机梯度下降、小批量梯度下降等)和调参,可以显著提高其性能。

5. Hopfield 神经网络相关的能量函数设计、计算,稳定性、平衡点判断

能量函数设计

  • 公式 E = − 1 2 ∑ i , j w i j s i s j + ∑ i θ i s i E = -\frac{1}{2} \sum_{i,j} w_{ij} s_i s_j + \sum_i \theta_i s_i E=21i,jwijsisj+iθisi
  • 思想:能量函数用于描述网络的状态,能量越低,状态越稳定。

稳定性判断

  • 公式 ∂ E ∂ s i = − ∑ j w i j s j + θ i \frac{\partial E}{\partial s_i} = - \sum_j w_{ij} s_j + \theta_i siE=jwijsj+θi
  • 思想:当能量函数的梯度为零时,网络达到平衡点。

平衡点判断

  • 公式 s i = sgn ( ∑ j w i j s j − θ i ) s_i = \text{sgn}(\sum_j w_{ij} s_j - \theta_i) si=sgn(jwijsjθi)
  • 思想:通过更新规则判断网络是否达到平衡点。

6. RNN/CNN 结构特点,出现的必要性,适合的应用场景

RNN (Recurrent Neural Network)

  • 结构特点:具有循环连接,能够处理序列数据。
  • 出现的必要性:处理时间序列数据,如语音、文本等。
  • 适合的应用场景:语音识别、自然语言处理、时间序列预测。

CNN (Convolutional Neural Network)

  • 结构特点:使用卷积核进行局部特征提取,具有平移不变性。
  • 出现的必要性:处理图像数据,提取空间特征。
  • 适合的应用场景:图像分类、目标检测、图像生成。

7. 典型 CNN 结构特点及 PyTorch 实现伪代码

Class CNN:
    Initialize:
        Conv -> ReLU -> Pooling
        Conv -> ReLU -> Pooling
        Fully Connected -> Dropout -> ReLU
        Output Layer

    Forward Pass:
        For each Conv Layer:
            Convolve -> Activate (ReLU) -> Pool
        Flatten the feature map
        Pass through Fully Connected Layers
        Return Output

LeNet5

  • 结构特点:卷积层、池化层、全连接层。
  • PyTorch 伪代码
import torch.nn as nn

class LeNet5(nn.Module):
    def __init__(self):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
        self.fc1 = nn.Linear(16*4*4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = nn.functional.relu(self.conv1(x))
        x = nn.functional.max_pool2d(x, 2)
        x = nn.functional.relu(self.conv2(x))
        x = nn.functional.max_pool2d(x, 2)
        x = x.view(-1, 16*4*4)
        x = nn.functional.relu(self.fc1(x))
        x = nn.functional.relu(self.fc2(x))
        x = self.fc3(x)
        return x

AlexNet

  • 结构特点:多个卷积层和全连接层,使用ReLU激活函数和Dropout。
  • PyTorch 伪代码
import torch.nn as nn

class AlexNet(nn.Module):
    def __init__(self):
        super(AlexNet, self).__init__()
        self.conv1 = nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2)
        self.conv2 = nn.Conv2d(96, 256, kernel_size=5, padding=2)
        self.conv3 = nn.Conv2d(256, 384, kernel_size=3, padding=1)
        self.conv4 = nn.Conv2d(384, 384, kernel_size=3, padding=1)
        self.conv5 = nn.Conv2d(384, 256, kernel_size=3, padding=1)
        self.fc1 = nn.Linear(256*6*6, 4096)
        self.fc2 = nn.Linear(4096, 4096)
        self.fc3 = nn.Linear(4096, 1000)

    def forward(self, x):
        x = nn.functional.relu(self.conv1(x))
        x = nn.functional.max_pool2d(x, 3, 2)
        x = nn.functional.relu(self.conv2(x))
        x = nn.functional.max_pool2d(x, 3, 2)
        x = nn.functional.relu(self.conv3(x))
        x = nn.functional.relu(self.conv4(x))
        x = nn.functional.relu(self.conv5(x))
        x = nn.functional.max_pool2d(x, 3, 2)
        x = x.view(-1, 256*6*6)
        x = nn.functional.relu(self.fc1(x))
        x = nn.functional.dropout(x, 0.5)
        x = nn.functional.relu(self.fc2(x))
        x = nn.functional.dropout(x, 0.5)
        x = self.fc3(x)
        return x

GoogleNet

  • 结构特点:使用Inception模块,多个并行卷积核。
  • PyTorch 伪代码
import torch.nn as nn

class Inception(nn.Module):
    def __init__(self, in_channels, out_1x1, red_3x3, out_3x3, red_5x5, out_5x5, out_pool):
        super(Inception, self).__init__()
        self.branch1 = nn.Conv2d(in_channels, out_1x1, kernel_size=1)
        self.branch2 = nn.Sequential(
            nn.Conv2d(in_channels, red_3x3, kernel_size=1),
            nn.Conv2d(red_3x3, out_3x3, kernel_size=3, padding=1)
        )
        self.branch3 = nn.Sequential(
            nn.Conv2d(in_channels, red_5x5, kernel_size=1),
            nn.Conv2d(red_5x5, out_5x5, kernel_size=5, padding=2)
        )
        self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            nn.Conv2d(in_channels, out_pool, kernel_size=1)
        )

    def forward(self, x):
        branch1 = self.branch1(x)
        branch2 = self.branch2(x)
        branch3 = self.branch3(x)
        branch4 = self.branch4(x)
        return torch.cat([branch1, branch2, branch3, branch4], 1)

class GoogleNet(nn.Module):
    def __init__(self):
        super(GoogleNet, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
        self.conv2 = nn.Conv2d(64, 192, kernel_size=3, padding=1)
        self.inception3a = Inception(192, 64, 96, 128, 16, 32, 32)
        self.inception3b = Inception(256, 128, 128, 192, 32, 96, 64)
        self.inception4a = Inception(480, 192, 96, 208, 16, 48, 64)
        self.inception4b = Inception(512, 160, 112, 224, 24, 64, 64)
        self.inception4c = Inception(512, 128, 128, 256, 24, 64, 64)
        self.inception4d = Inception(512, 112, 144, 288, 32, 64, 64)
        self.inception4e = Inception(528, 256, 160, 320, 32, 128, 128)
        self.inception5a = Inception(832, 256, 160, 320, 32, 128, 128)
        self.inception5b = Inception(832, 384, 192, 384, 48, 128, 128)
        self.fc = nn.Linear(1024, 1000)

    def forward(self, x):
        x = nn.functional.relu(self.conv1(x))
        x = nn.functional.max_pool2d(x, 3, 2, padding=1)
        x = nn.functional.relu(self.conv2(x))
        x = nn.functional.max_pool2d(x, 3, 2, padding=1)
        x = self.inception3a(x)
        x = self.inception3b(x)
        x = nn.functional.max_pool2d(x, 3, 2, padding=1)
        x = self.inception4a(x)
        x = self.inception4b(x)
        x = self.inception4c(x)
        x = self.inception4d(x)
        x = self.inception4e(x)
        x = nn.functional.max_pool2d(x, 3, 2, padding=1)
        x = self.inception5a(x)
        x = self.inception5b(x)
        x = nn.functional.avg_pool2d(x, 7)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值