当前位置: 首页 > news >正文

深度学习——常见的神经网络

文章目录

  • 一、FNN
    • 1.1原理
    • 1.2代码
  • 二、CNN
    • 2.1原理
      • Step1:提取图片特征(+padding)
      • Step2:池化
      • Step3:扁平化处理
    • 2.2代码
  • 三、RNN
    • 3.1CNN的问题
    • 3.2原理
    • 3.3代码
  • 四、LSTM
    • 4.1RNN的问题
    • 4.2原理
    • 4.3代码
  • 五、GRU
    • 5.1原理
    • 5.2代码

一、FNN

1.1原理

前馈神经网络(Feedforward Neural Network, FNN) 是最基础、最常见的人工神经网络结构。
其核心思想是:信息从输入层开始,经过若干个隐藏层的非线性变换,最终到达输出层,且信号只沿单向传播,不会形成循环。因此,FNN 又常被称为 多层感知机(MLP, Multi-Layer Perceptron)

  • 输入层(Input Layer):接收原始数据特征,维度 = 输入特征数量。不进行计算,只负责数据传递。
  • 隐藏层(Hidden Layer):一个或多个隐藏层,每层由多个神经元组成。

单层神经元计算:
a=f(z)=f(W⋅x+b)a = f(z)=f( W \cdot x + b)a=f(z)=f(Wx+b)
其中:

  • WWW :权重矩阵;xxx :输入向量;bbb :偏置;
  • fff :激活函数(如 ReLU, Sigmoid, Tanh 等);aaa :神经元输出

多层网络(第 lll 层):
a(l)=f(W(l)⋅a(l−1)+b(l))a^{(l)} = f(W^{(l)} \cdot a^{(l-1)} + b^{(l)})a(l)=f(W(l)a(l1)+b(l))

  • 输出层(Output Layer):将隐藏层结果映射到任务需求的输出维度。
    • 分类:Softmax 输出概率分布
    • 回归:线性输出

FNN 的训练主要依靠 反向传播(Backpropagation, BP) + 梯度下降(Gradient Descent):

  • 前向传播:计算预测输出。
  • 计算损失:衡量预测值与真实值的误差(如 MSE, Cross-Entropy)。
  • 反向传播:通过链式法则计算梯度。
  • 参数更新:使用梯度下降(或优化器,如 Adam、SGD)更新参数。

1.2代码

class FNN(nn.Module):def __init__(self, input_size=10, hidden_size=32, output_size=2):super(FNN, self).__init__()self.fc1 = nn.Linear(input_size, hidden_size)  # 输入层 → 隐藏层self.relu = nn.ReLU()self.fc2 = nn.Linear(hidden_size, output_size)  # 隐藏层 → 输出层def forward(self, x):out = self.fc1(x)out = self.relu(out)out = self.fc2(out)return out
  • input_size:每条输入数据的特征数量,也就是输入向量的长度。
  • hidden_size:隐藏层中神经元的数量。
  • output_size:输出层神经元的数量,决定网络的最终输出维度。
    • 分类任务:输出神经元数量 = 类别数。例如二分类 → output_size = 2,三分类 → output_size = 3。
    • 回归任务:输出神经元数量 = 需要预测的值的数量。

二、CNN

参考视频
https://www.bilibili.com/video/BV1MsrmY4Edi/?spm_id_from=333.337.search-card.all.click&vd_source=67ba3568cbf6ea1d930339cd0f2092ba

在这里插入图片描述

2.1原理

Step1:提取图片特征(+padding)

使用卷积核(特征过滤器)进行特征提取。

  • 卷积核有2个,则会生成2张特征图
  • 卷积核有多少个,就会生成多少张特征图
    在这里插入图片描述

提取特征的计算规则:
在这里插入图片描述

  • 滑动窗口:卷积核在输入图像上按照一定的步长(Stride)滑动,每次滑动都会计算一次卷积操作,得到特征图上的一个值。例如,步长为 1 时,卷积核每次移动一个像素;步长为 2 时,卷积核每次移动两个像素。
  • 局部感知:卷积核的尺寸通常远小于输入图像的尺寸,这意味着它在每次运算时只关注图像的一个局部区域,从而提取局部特征。
  • 权值共享:无论卷积核滑动到图像的哪个位置,其权值都保持不变,整个图像上是共享。这样大大减少了模型的参数数量,降低了计算复杂度,同时也提高了模型的泛化能力。

最终结果如下:原来66的图片被特征提取之后,大小变成了44,并且边缘特征都丢失了。
在这里插入图片描述
Padding:扩充0。使得原来6*6的图片在扩充之后边缘信息能被成功提取。
其主要的作用有:1、保持特征图尺寸2、保护边缘信息。其计算方法不展开叙述。在这里插入图片描述

Step2:池化

池化操作与卷积类似,通过滑动窗口在特征图上移动,对每个窗口内的像素进行聚合计算。常见的有最大池化平均池化
池化的主要作用有1、保留边缘、纹理等显著特征2、将图片的大小变小:8 * 8的图片变成了4 * 4。
在这里插入图片描述

Step3:扁平化处理

将多维的输入数据拉平转换为一维向量 。
在 CNN 中,经过一系列卷积和池化操作后,输出的特征图通常是具有高度、宽度和通道数的三维张量(形状如 [batch_size, height, width, channels] );在 RNN 处理序列数据时,输出也可能是多维张量。而全连接层要求输入是一维向量,扁平化处理就是为了满足全连接层的输入要求。
在这里插入图片描述

2.2代码

class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Sequential( nn.Conv2d(in_channels=1,     out_channels=16,   kernel_size=5,      stride=1,          padding=2,     ),     nn.ReLU(),   nn.MaxPool2d(kernel_size=2),    )self.conv2 = nn.Sequentialnn.Conv2d(16, 32, 5, 1, 2),  nn.ReLU(), nn.MaxPool2d(2),  )self.out = nn.Linear(32 * 7 * 7, 10)  def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = x.view(x.size(0), -1)   output = self.out(x)return output
  • in_channels:输入的通道数(输入图片的“深度”)。
    • 灰度图:1 通道
    • RGB彩色图:3 通道
  • out_channels:卷积核(滤波器)的数量,也就是输出的特征图(feature map)的数量
  • kernel_size:卷积核的大小。
    • 如果写成整数 3,表示是 3x3 的卷积核。
    • 如果写成元组 (3, 5),就是 3x5 的卷积核。
  • stride:卷积的步幅。stride=1 表示卷积核每次滑动 1 个像素。如果 stride=2,就是每次跨 2 个像素,输出的特征图尺寸会缩小一半。
  • padding:在输入的边缘补零(zero padding),用来控制输出大小。
过程图片信息
输入(batch_size, 1, 28, 28)
conv1+ReLu(batch_size, 16, 28, 28)
pool(batch_size, 16, 14, 14)
conv2+ReLu(batch_size, 32, 14, 14)
pool(batch_size, 32, 7, 7)
flatten(batch_size, 10)

三、RNN

3.1CNN的问题

CNN的优点:

  • 局部感受野:捕捉局部模式(如边缘、纹理)
  • 权重共享:减少参数量
  • 空间不变性:平移不影响特征提取

局限:

  • 只能捕捉固定大小局部特征,对长距离依赖不敏感
  • 不适合序列数据(文本、时间序列、语音等),因为 CNN 处理长序列需要非常深的网络才能捕捉远距离依赖。

3.2原理

RNN的核心思想:网络的隐藏状态记录历史信息,每个时间步的输出依赖当前输入和之前的隐藏状态。
在这里插入图片描述

隐藏状态是 RNN 的“记忆”,记录了从序列开头到当前时间步的历史信息。它本身不一定直接就是任务输出。维度通常是 hidden_size

隐藏状态更新: ht=f(Wxhxt+Whhht−1+bh)h_t = f(W_{xh} x_t + W_{hh} h_{t-1} + b_h)ht=f(Wxhxt+Whhht1+bh)

  • WxhxtW_{xh} x_tWxhxt 本质上就是对当前输入 xtx_txt做了全连接
    • xtx_txt:当前输入
    • WxhW_{xh}Wxh:权重矩阵
  • Whhht−1W_{hh} h_{t-1}Whhht1本质上就是对 上一时间步隐藏状态 ht−1h_{t-1}ht1做了全连接
    • ht−1h_{t-1}ht1:上一个时间步的隐藏状态
    • WhhW_{hh}Whh:权重矩阵
  • bhb_hbh:偏置
  • fff:激活函数(如 tanhReLU

将隐藏状态经过 线性映射 + 激活函数 得到最终输出:
yt=g(Whyht+by)y_t = g(W_{hy} h_t + b_y)yt=g(Whyht+by)

3.3代码

class RNNClassifier(nn.Module):def __init__(self, input_size=28, hidden_size=128, num_layers=2, num_classes=10):super(RNNClassifier, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layers# RNN 输入: input_size=28, 输出 hidden_sizeself.rnn = nn.RNN(input_size=input_size, hidden_size=hidden_size,num_layers=num_layers, batch_first=True)# 输出层self.fc = nn.Linear(hidden_size, num_classes)def forward(self, x):# x.shape = (batch, 1, 28, 28)x = x.squeeze(1)  # 去掉通道维度, (batch, 28, 28)# 初始化隐藏状态h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)# RNN 前向传播out, _ = self.rnn(x, h0)  # out: (batch, seq_len=28, hidden_size)out = out[:, -1, :]        # 取最后一个时间步out = self.fc(out)return out
  • 时间步 time step:指序列中每一个单独的输入点。假设一句话是 “HELLO”,则每个字母是一个时间步,共5个时间步。
  • input_size:每个时间步输入的特征维度。每张图 28x28,我们把每一行的28个像素当作一个时间步。
  • 序列长度 seq_len:一共有28个时间步。因此序列长度为28.
  • hidden_size:hidden_size 想象成 RNN 的记忆容量。数值越大,网络容量越强,但参数更多,计算量更大。hth_tht是 hidden_size 维的向量。
  • num_layers:RNN 堆叠的层数
    • num_layers=1 → 单层 RNN
    • num_layers>1 → 多层 RNN,每一层的输出作为下一层的输入
  • batch_first:指定输入和输出张量的维度顺序
    • True → 输入和输出张量形状为 (batch_size, seq_len, input_size)
    • False → 输入和输出张量形状为 (seq_len, batch_size, input_size)

整体 X 是 (batch_size, seq_len, input_size)。RNN 内部会把序列拆开,每个时间步输入:

名称形状说明
单时间步xt单时间步x_t单时间步xt(batch_size, input_size)当前时间步输入向量,送入RNNcell
隐藏状态ht隐藏状态h_t隐藏状态ht(batch_size, hidden_size)当前时间步的隐藏状态
输出yt输出 y_t输出yt(batch_size, output_size)当前时间步输出(分类概率等)

四、LSTM

4.1RNN的问题

RNN 的问题:

  • 梯度消失 / 梯度爆炸:时间步太长时,梯度在反向传播中可能衰减得太快或爆炸。
  • 训练慢:必须按时间步循环计算,难以完全并行。
  • 长序列依赖难:标准 RNN 难以捕捉很长的依赖关系。

参考视频
https://www.bilibili.com/video/av15997678?spm_id_from=333.788.videopod.episodes&aid=15997678&vd_source=67ba3568cbf6ea1d930339cd0f2092ba&p=21
在这里插入图片描述
在这里插入图片描述

4.2原理

为了解决这个问题,LSTM (long-short term memory)引入了一种门控机制来控制信息的“遗忘、记忆和输出”。
在这里插入图片描述

LSTM 在结构上比 RNN 多了一条细胞状态(cell state,记忆线),像是一条传送带,能让信息更容易在序列中流动。 它通过三个门来调控信息流动:

  • 遗忘门(Forget Gate):决定哪些历史信息要丢掉。
    ft=σ(Wf⋅[ht−1,xt]+bf)f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)ft=σ(Wf[ht1,xt]+bf)
    • 输入:上一步隐藏状态 (h_{t-1}) 和当前输入 (x_t)
    • 输出:一个 0~1 之间的向量,接近 0 表示遗忘,接近 1 表示保留
  • 输入门(Input Gate):决定哪些新信息要存入记忆。
    it=σ(Wi⋅[ht−1,xt]+bi)i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)it=σ(Wi[ht1,xt]+bi) C~t=tanh⁡(WC⋅[ht−1,xt]+bC)\tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C)C~t=tanh(WC[ht1,xt]+bC)
    • iti_tit:控制要写入多少新信息
    • C~t\tilde{C}_tC~t:候选的新记忆
  • 更新细胞状态:结合遗忘门和输入门,更新记忆:
    Ct=ft∗Ct−1+it∗C~tC_t = f_t * C_{t-1} + i_t * \tilde{C}_tCt=ftCt1+itC~t
  • 输出门(Output Gate):决定输出多少信息作为隐藏状态 (h_t)。
    ot=σ(Wo⋅[ht−1,xt]+bo)o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)ot=σ(Wo[ht1,xt]+bo) ht=ot∗tanh⁡(Ct)h_t = o_t * \tanh(C_t)ht=ottanh(Ct)

在每个时间步 ttt

  1. 遗忘门决定丢掉多少旧信息;
  2. 输入门决定接收多少新信息;
  3. 更新细胞状态 CtC_tCt,相当于“长期记忆”;
  4. 输出门生成新的隐藏状态 hth_tht,作为“短期记忆”,传给下一步。

LSTM 的优势:

  • 能有效缓解 RNN 的梯度消失问题;
  • 可以记住长期依赖信息(比如一段话开头的信息影响后面很远的词);
  • 在 NLP、语音识别、时间序列预测等任务上表现良好。

4.3代码

其代码和CNN类似:

class LSTMClassifier(nn.Module):def __init__(self, input_size=50, hidden_size=128, num_layers=2, num_classes=2):super(LSTMClassifier, self).__init__()self.lstm = nn.LSTM(input_size=input_size,hidden_size=hidden_size,num_layers=num_layers,batch_first=True)  # 输入格式 (batch, seq_len, input_size)self.fc = nn.Linear(hidden_size, num_classes)def forward(self, x):# h0, c0 默认初始化为 0out, _ = self.lstm(x)       # out: (batch, seq_len, hidden_size)out = out[:, -1, :]         # 取最后一个时间步的隐藏状态out = self.fc(out)          # 全连接层分类return out

五、GRU

5.1原理

普通 RNN 难以捕捉长距离依赖,易出现梯度消失/爆炸。GRU(2014, Cho 等)通过门控机制控制信息流动,像 LSTM 一样缓解长依赖问题,但结构更简洁、参数更少、训练更快。
在这里插入图片描述
GRU 只有一个状态(隐藏状态hth_tht),没有像 LSTM 那样独立的细胞状态 CtC_tCt。它通过两个门来调控:

  • 更新门(Update Gate):决定保留多少旧信息、引入多少新信息。
    zt=σ(Wzxt+Uzht−1+bz)z_t=\sigma(W_z x_t+U_z h_{t-1}+b_z)zt=σ(Wzxt+Uzht1+bz)
    • zt≈0z_t \approx 0zt0:几乎复制 ht−1h_{t-1}ht1,保留长程记忆。
    • zt≈1z_t \approx 1zt1:几乎采用 h~t\tilde{h}_th~t,快速更新为新状态。
  • 重置门(Reset Gate):决定在计算候选状态时,旧信息参与多少。
    rt=σ(Wrxt+Urht−1+br)r_t=\sigma(W_r x_t+U_r h_{t-1}+b_r)rt=σ(Wrxt+Urht1+br)
    • rt≈0r_t \approx 0rt0:近似抛开历史,只看当前输入 xtx_txt
    • rt≈1r_t \approx 1rt1:结合历史与当前信息更新状态。
  • 候选隐藏状态
    h~t=tanh⁡⁣(Whxt+Uh(rt⊙ht−1)+bh)\tilde{h}_t=\tanh\!\big(W_h x_t+U_h\,(r_t\odot h_{t-1})+b_h\big)h~t=tanh(Whxt+Uh(rtht1)+bh)
  • 最终状态更新(线性插值)
    ht=(1−zt)⊙ht−1+zt⊙h~th_t=(1-z_t)\odot h_{t-1}+z_t\odot \tilde{h}_tht=(1zt)ht1+zth~t

与 LSTM 的对比:

方面GRULSTM
状态只有 hth_thtCtC_tCt(细胞)和 hth_tht
门的数量2 个(更新、重置)3 个门 + 候选(遗忘、输入、输出 + 候选)
参数量3×(D·H + H² + H)4×(D·H + H² + H)
速度/内存更快、更省略慢、略占内存
记忆力通常与 LSTM 接近某些长依赖任务可能更稳

5.2代码

class GRUClassifier(nn.Module):def __init__(self, input_size, hidden_size, num_layers, num_classes, bidirectional=False):super().__init__()self.gru = nn.GRU(input_size=input_size,hidden_size=hidden_size,num_layers=num_layers,batch_first=True,bidirectional=bidirectional)factor = 2 if bidirectional else 1self.fc = nn.Linear(hidden_size * factor, num_classes)def forward(self, x):                out, h_n = self.gru(x)         feat = out[:, -1, :]             logits = self.fc(feat)          return logits

上述原理图片来源:
https://github.com/NLP-LOVE/ML-NLP/blob/master/Deep%20Learning/12.2%20LSTM/README.md

http://www.dtcms.com/a/336022.html

相关文章:

  • Tomcat 类加载器原理深度解析
  • PowerPoint和WPS演示让多个对象通过动画同时出现
  • 近期(2021-2025)发行的常用国军标GJB 整理,2021,2022,2023,2024,2025
  • 深入理解QFlags:Qt中的位标志管理工具
  • 本文将详细介绍如何构建一个功能完整的键盘测试工具,包含虚拟键盘、实时统计、打字练习等核心功能,无需任何后端服务或复杂依赖。
  • 无人机视角土地区域类型识别分割数据集labelme格式4904张7类别
  • 使用oradebug收集数据库诊断信息
  • 第3章 Java NIO核心详解
  • AOP配置类自动注入
  • Linux系统分析 CPU 性能问题的工具汇总
  • 【102页PPT】某著名企业智能制造解决方案及智能工厂产品介绍(附下载方式)
  • 19.5 「4步压缩大模型:GPTQ量化实战让OPT-1.3B显存直降75%」
  • 微网智能光储协调控制器方案
  • 【运维进阶】实施任务控制
  • 网络原理与编程实战:从 TCP/IP 到 HTTP/HTTPS
  • 基于Vue的个人博客网站的设计与实现/基于node.js的博客系统的设计与实现#express框架、vscode
  • Rust 入门 生命周期(十八)
  • 力扣3:无重复字符的最长子串
  • Linux软件编程:进程与线程(线程)
  • 最新技术论坛技术动态综述
  • 【论文阅读】美 MBSE 方法发展分析及启示(2024)
  • 多维视角下离子的特性、应用与前沿探索
  • RabbitMQ面试精讲 Day 24:消费者限流与批量处理
  • 从0实现系统设计
  • Python 类元编程(类作为对象)
  • Makefile介绍(Makefile教程)(C/C++编译构建、自动化构建工具)
  • 为什么神经网络在长时间训练过程中会存在稠密特征图退化的问题
  • LangGraph 的官网的一个最简单的聊天机器人
  • 数据与模型融合波士顿房价回归建模预测
  • SQL Server 2019安装教程(超详细图文)