1. FNN(前馈神经网络)是什么?
1.1 基本概念
FNN(Feedforward Neural Network) ,也叫 全连接神经网络(Fully Connected Neural Network) 或 多层感知机(MLP, Multi-Layer Perceptron),是最基础、最经典的神经网络结构。
1.2 核心特点
"信息单向流动,层层全连接"
输入层 隐藏层1 隐藏层2 输出层
○─────────────○─────────────○─────────────○
○─────────────○─────────────○─────────────○
○─────────────○─────────────○
○─────────────○─────────────○
○ ○
1.3 FNN 的结构
| 组成部分 | 说明 |
|---|---|
| 输入层 | 接收原始特征数据 |
| 隐藏层 | 一层或多层,进行特征变换 |
| 输出层 | 输出最终预测结果 |
| 连接方式 | 相邻层之间全连接(每个神经元与下一层所有神经元相连) |
1.4 数学表达
对于一个隐藏层:
h=σ(W⋅x+b)h = \sigma(W \cdot x + b)h=σ(W⋅x+b)
其中:
- xxx:输入向量
- WWW:权重矩阵
- bbb:偏置向量
- σ\sigmaσ:激活函数(如 ReLU、Sigmoid)
- hhh:隐藏层输出
1.5 FNN 示例代码
python
import torch
import torch.nn as nn
class FNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(FNN, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size) # 全连接层1
self.relu = nn.ReLU() # 激活函数
self.fc2 = nn.Linear(hidden_size, hidden_size) # 全连接层2
self.fc3 = nn.Linear(hidden_size, output_size) # 输出层
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
return x
# 创建模型
model = FNN(input_size=784, hidden_size=256, output_size=10)
2. CNN(卷积神经网络)是什么?
2.1 基本概念
CNN(Convolutional Neural Network) 是专门为处理网格状数据 (如图像)设计的神经网络,通过卷积操作提取局部特征。
2.2 核心特点
"局部连接,权值共享,层次化特征提取"
2.3 CNN 的核心组件
2.3.1 卷积层(Convolutional Layer)
使用卷积核(Filter/Kernel) 在输入上滑动,提取局部特征:
输入图像 (5x5) 卷积核 (3x3) 特征图 (3x3)
┌─┬─┬─┬─┬─┐ ┌─┬─┬─┐ ┌─┬─┬─┐
│1│1│1│0│0│ │1│0│1│ │4│3│4│
├─┼─┼─┼─┼─┤ * ├─┼─┼─┤ = ├─┼─┼─┤
│0│1│1│1│0│ │0│1│0│ │2│4│3│
├─┼─┼─┼─┼─┤ ├─┼─┼─┤ ├─┼─┼─┤
│0│0│1│1│1│ │1│0│1│ │2│3│4│
├─┼─┼─┼─┼─┤ └─┴─┴─┘ └─┴─┴─┘
│0│0│1│1│0│
├─┼─┼─┼─┼─┤
│0│1│1│0│0│
└─┴─┴─┴─┴─┘
2.3.2 池化层(Pooling Layer)
降低特征图的空间尺寸,减少参数:
-
最大池化(Max Pooling):取区域内最大值
-
平均池化(Average Pooling):取区域内平均值
输入 (4x4) 最大池化 (2x2) 输出 (2x2)
┌─┬─┬─┬─┐ ┌───┬───┐ ┌─┬─┐
│1│3│2│4│ │ │ │ │4│6│
├─┼─┼─┼─┤ → ├───┼───┤ = ├─┼─┤
│5│4│1│6│ │ │ │ │8│4│
├─┼─┼─┼─┤ └───┴───┘ └─┴─┘
│7│8│3│2│
├─┼─┼─┼─┤
│1│2│4│3│
└─┴─┴─┴─┘
2.3.3 全连接层(Fully Connected Layer)
在 CNN 的最后,通常会接几层全连接层进行分类或回归。
2.4 CNN 示例代码
python
import torch
import torch.nn as nn
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
# 卷积层
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# 池化层
self.pool = nn.MaxPool2d(2, 2)
# 全连接层
self.fc1 = nn.Linear(64 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
self.relu = nn.ReLU()
def forward(self, x):
# 卷积 + 激活 + 池化
x = self.pool(self.relu(self.conv1(x))) # 28x28 -> 14x14
x = self.pool(self.relu(self.conv2(x))) # 14x14 -> 7x7
# 展平
x = x.view(-1, 64 * 7 * 7)
# 全连接
x = self.relu(self.fc1(x))
x = self.fc2(x)
return x
# 创建模型
model = CNN()
3. FNN vs CNN 核心区别 ⚔️
3.1 对比总览表
| 特性 | FNN(前馈神经网络) | CNN(卷积神经网络) |
|---|---|---|
| 连接方式 | 全连接 | 局部连接 + 全连接 |
| 权值共享 | ❌ 无 | ✅ 有(卷积核共享) |
| 参数数量 | 非常多 | 相对较少 |
| 空间结构 | 不保留 | 保留空间信息 |
| 平移不变性 | ❌ 无 | ✅ 有 |
| 主要应用 | 表格数据、简单任务 | 图像、视频、信号处理 |
| 输入形式 | 一维向量 | 多维张量(如图像) |
3.2 详细对比
🔗 3.2.1 连接方式
FNN - 全连接:
每个神经元与下一层的【所有】神经元相连
输入 (4个) 隐藏层 (3个)
○──────────────○
○──────────────○
○──────────────○
○
连接数 = 4 × 3 = 12
CNN - 局部连接:
每个神经元只与输入的【局部区域】相连
输入 (5个) 隐藏层 (3个)
○───○
○───┼───○
○───┼───┼───○
○───┼───○
○───○
每个输出只连接3个输入(卷积核大小=3)
3.2.2 参数数量对比
假设处理一张 224×224×3 的彩色图像:
FNN:
输入维度 = 224 × 224 × 3 = 150,528
假设第一个隐藏层有 1000 个神经元
参数数量 = 150,528 × 1000 = 150,528,000
CNN:
使用 32 个 3×3 的卷积核
参数数量 = 3 × 3 × 3 × 32 = 864
差距巨大! 这就是为什么 CNN 更适合处理图像!💡
3.2.3 权值共享
FNN:每个连接都有独立的权重
CNN :同一个卷积核在整个输入上滑动,共享权重
CNN 权值共享示意:
同一个卷积核 [w1, w2, w3] 在不同位置使用:
位置1: [x1, x2, x3] × [w1, w2, w3] = y1
位置2: [x2, x3, x4] × [w1, w2, w3] = y2
位置3: [x3, x4, x5] × [w1, w2, w3] = y3
权重 w1, w2, w3 被共享!
3.2.4 空间信息保留
FNN:
-
输入必须展平成一维向量
-
丢失空间结构信息
-
相邻像素的关系被破坏
图像 (3×3): 展平后:
┌─┬─┬─┐
│1│2│3│ → [1,2,3,4,5,6,7,8,9]
├─┼─┼─┤
│4│5│6│ 空间关系丢失!
├─┼─┼─┤
│7│8│9│
└─┴─┴─┘
CNN:
- 保持输入的空间结构
- 保留空间信息
- 能够捕捉局部模式
3.2.5 平移不变性
平移不变性:无论目标出现在图像的哪个位置,都能被识别。
FNN:❌ 没有平移不变性
- 如果训练时猫在左边,测试时猫在右边,可能识别失败
CNN:✅ 具有平移不变性
-
卷积核在整个图像上滑动
-
无论特征在哪里,都能被检测到
CNN 平移不变性示意:
图像1: 猫在左边 图像2: 猫在右边
┌─────────────┐ ┌─────────────┐
│ 🐱 │ │ 🐱 │
│ │ │ │
└─────────────┘ └─────────────┘同一个"猫特征检测器"(卷积核)都能检测到!
4. 形象类比
让我用一个生动的类比来帮助你理解!
4.1 FNN 像"全局扫描仪"
想象你要识别一张图片:
- FNN 会把整张图片一次性看完
- 每个像素都与每个神经元相连
- 就像用一个巨大的眼睛同时看所有细节
- 缺点:参数太多,容易过拟合,不理解局部结构
4.2 CNN 像"放大镜检查员"
-
CNN 用一个小"放大镜"(卷积核)逐步扫描图片
-
先找边缘、纹理等低级特征
-
再组合成眼睛、鼻子等中级特征
-
最后识别出整个物体
-
优点:参数少,能理解局部结构,有层次感
CNN 的层次化特征提取:
第1层: 检测边缘、线条
╱ ╲ │ ─第2层: 检测纹理、角点
┌┐ └┘ ∠第3层: 检测部件
👁️ 👃 👄第4层: 检测整体
😺 🐶 🚗
5. 什么时候用 FNN?什么时候用 CNN?
5.1 使用 FNN 的场景
| 场景 | 示例 |
|---|---|
| 表格数据 | 用户特征、销售数据、金融数据 |
| 低维数据 | 特征数量较少的数据 |
| 无空间结构 | 数据没有空间或时序关系 |
| 简单任务 | 简单的分类或回归 |
| 作为其他网络的一部分 | CNN、RNN 的最后几层 |
5.2 使用 CNN 的场景
| 场景 | 示例 |
|---|---|
| 图像处理 | 图像分类、目标检测、图像分割 |
| 视频分析 | 动作识别、视频分类 |
| 信号处理 | 语音识别、心电图分析 |
| 自然语言处理 | 文本分类(1D CNN) |
| 任何有局部模式的数据 | 基因序列、时间序列 |
6. 总结
6.1 一句话总结
| 网络 | 一句话描述 |
|---|---|
| FNN | 最基础的神经网络,全连接结构,适合处理表格数据 |
| CNN | 专为网格数据设计,通过卷积提取局部特征,适合图像处理 |
6.2 关系图
神经网络家族:
神经网络
│
┌──────────────┼──────────────┐
│ │ │
FNN CNN RNN
(前馈神经网络) (卷积神经网络) (循环神经网络)
│ │ │
表格数据 图像数据 序列数据
6.3 记忆口诀
FNN 全连接,参数多又密,
表格数据它最行,图像处理不给力。
CNN 卷积核,局部连接省参数,
权值共享真厉害,图像识别第一名!