23.大模型开发:深度学习----CNN 卷积神经网络 与 RNN 循环神经网络

前言

刚入门深度学习的同学很容易搞混两件事:什么时候用 CNN,什么时候用 RNN

  • 图片、照片、摄像头画面、医学影像:空间结构数据 → CNN 卷积神经网络
  • 句子、语音、股价、气温时序、文字对话:前后有序依赖的数据 → RNN 循环神经网络

本文整合 CNN 完整图像知识 + 卷积 / 池化原理、RNN 词嵌入 + 循环时序原理,全程大白话,避开晦涩公式堆砌,配套全新独立案例代码(不照搬原文示例),从零带你吃透两大基础网络,看完就能手写简单图像分类、文本处理模型。

第一部分:CNN 卷积神经网络 ------ 专门处理图像

一、图像底层基础知识(看懂 CNN 的前提)

1. 计算机怎么看懂图片?像素与通道

所有图片在电脑里都是数字矩阵,最小单位是像素 ,像素取值范围 0~255

  • 数值 0:纯黑色;数值 255:纯白色;中间数值是深浅过渡。
  • 图像分 4 种常见类型:
  • 二值图:仅 1 个通道,像素只有 0、1 两种取值,一般用于文字扫描、黑白线条图。
  • 灰度图:单通道图像,像素取值范围 0~255,常应用在人脸识别、医学 X 光片等场景。
  • 索引图:同样为 1 通道,像素区间 0~255,多用于压缩动图、色彩数量较少的图片。
  • RGB 彩色图:包含红、绿、蓝 3 个通道,像素取值 0~255,手机拍摄的日常照片都属于这类图像。

图像存储格式约定:

  • 普通读取:[H, W, C] → 高、宽、通道;
  • PyTorch 模型输入:必须转成 [Batch, C, H, W] 批次、通道、高、宽。

2. 代码实操:用 matplotlib 生成 / 读取图片

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 1. 生成纯黑、纯白测试图
def create_color_img():
    # 200*200 三通道黑色图
    black = np.zeros((200, 200, 3), dtype=np.uint8)
    plt.imshow(black)
    plt.axis("off")
    plt.title("纯黑图像")
    plt.show()
    # 纯白图
    white = np.full((200, 200, 3), 255, dtype=np.uint8)
    plt.imshow(white)
    plt.axis("off")
    plt.title("纯白图像")
    plt.show()

# 2. 读取本地真实图片,查看尺寸
def read_local_img():
    img = plt.imread("test.jpg")
    print(f"图片形状[H,W,C]:{img.shape}")
    plt.imshow(img)
    plt.axis("off")
    plt.title("原图展示")
    plt.show()

if __name__ == "__main__":
    create_color_img()
    read_local_img()

二、CNN 整体概述:为什么不用全连接,非要卷积?

1. 全连接网络处理图片的致命缺陷

一张 640×640 彩色图,像素总量 640*640*3=1228800,全连接第一层就会产生百万级参数,存在两大问题:

  1. 参数爆炸,训练慢、极易过拟合;
  2. 丢失空间信息:全连接把图片拍平成一维,分不清上下左右,无法识别边缘、轮廓。

2. CNN 核心优势:局部连接 + 权重共享

  1. 局部感受野:卷积核只和图片一小块区域计算,不用全局连接;
  2. 权重共享:同一个卷积核在整张图滑动,一套权重复用,参数量大幅降低;
  3. 平移不变性:物体在图片左上角 / 右下角,卷积都能识别同类特征。

3. CNN 标准三层流水线(所有图像任务通用)

  1. 卷积层 Conv2d:提取图像特征(底层:边缘、纹理;多层堆叠后:五官、物体轮廓);
  2. 池化层 Pool:下采样降维,压缩图片尺寸,保留核心特征,减少计算;
  3. 全连接层 Linear:把二维特征图展平,输出分类 / 检测结果。

配套激活层 ReLU:卷积计算后加入非线性,让网络能学习复杂图像特征。

4. CNN 主流应用场景

图像分类、人脸识别、自动驾驶目标检测、医学病灶识别、图像语义分割、手写数字识别。 经典 CNN 架构:LeNet-5(手写数字开山之作)、AlexNet、VGG、GoogLeNet、ResNet(解决深层网络梯度消失)。

三、卷积层 Conv2d:图像特征提取核心

1. 卷积运算底层逻辑

核心操作:卷积核(滤波器)和图片局部区域做内积

  • 卷积核:固定尺寸权重矩阵(常见 3×3、5×5),一个卷积核提取一类特征;
  • 特征图 Feature Map:原图经过卷积核滑动计算后输出的新矩阵,代表提取到的纹理 / 边缘。

2. 三大关键超参:Padding、Stride、Kernel_size

(1)Padding 填充

在图片四周补 0 像素,解决两个痛点:

  1. 不填充时卷积后图片持续缩小,深层网络容易丢失边缘像素;
  2. Same Padding:填充后输出特征图尺寸 = 输入图片尺寸,方便多层网络搭建。
(2)Stride 步长

卷积核每次滑动移动的像素数:

  • stride=1:逐像素滑动,细节保留完整;
  • stride=2:隔一个像素滑动,直接缩小特征图,替代部分池化降维。
(3)输出特征图尺寸计算公式
  • W:输入图片宽高;F:卷积核大小;P:填充;S:步长;向下取整。

举例:5×5 图片,3×3 卷积核,padding=1,stride=1,N=(5−3+2×1)/1+1=5,输出仍为 5×5。

3. 多通道、多卷积核计算规则

  1. RGB 三通道图像卷积:卷积核通道数必须和图片通道一致(3 通道),每个通道单独卷积后数值相加,得到单张特征图;
  2. 多卷积核:设置 out_channels=N,代表 N 个不同卷积核,同时提取 N 类特征,输出 N 张特征图,通道数等于卷积核数量。

4. PyTorch 卷积 API 实战

python 复制代码
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

# 解决中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']  # 或 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False


def conv_image_test():
    # 读取图片
    img = plt.imread("test.jpg")  # 形状 (H, W, C),通常是 uint8
    h, w, c = img.shape
    print(f"原图尺寸 H:{h}, W:{w}, C:{c}")

    # 1. 构建卷积层
    conv = nn.Conv2d(in_channels=3, out_channels=4, kernel_size=3, stride=2, padding=0)

    # 2. 转换维度:HWC → CHW → [B, C, H, W]
    img_tensor = torch.tensor(img).permute(2, 0, 1).unsqueeze(0).float()
    print(f"模型输入张量形状:{img_tensor.shape}")

    # 3. 前向传播得到特征图
    feature = conv(img_tensor)
    print(f"卷积输出特征图形状:{feature.shape}")

    # 4. 取第一张特征图(通道0)
    feat_map = feature[0, 0].detach().numpy()  # 形状 (H_out, W_out)

    # ---------- 可视化:原图 + 特征图 并排 ----------
    fig, axes = plt.subplots(1, 2, figsize=(10, 5))

    # 左:原图
    axes[0].imshow(img)  # 彩色显示
    axes[0].set_title("原图")
    axes[0].axis("off")

    # 右:特征图(灰度)
    axes[1].imshow(feat_map, cmap="gray")
    axes[1].set_title("卷积提取特征图 (通道0)")
    axes[1].axis("off")

    plt.tight_layout()  # 自动调整子图间距
    plt.show()


if __name__ == "__main__":
    conv_image_test()

效果图:

四、池化层 Pool:降维压缩,减少计算量

1. 池化两大核心作用

  1. 空间降维:缩小特征图宽高,大幅减少后续计算参数;
  2. 特征鲁棒性:轻微平移、噪声不会影响特征识别,降低过拟合。

2. 两种主流池化

  1. MaxPool2d 最大池化:窗口内取最大值,保留最明显纹理 / 边缘,工业最常用;
  2. AvgPool2d 平均池化:窗口内取平均值,柔和保留全局信息,多用于全局特征聚合。

3. 多通道池化特点

池化不会改变通道数量,每个通道独立池化,通道数前后保持一致。

4. PyTorch 池化代码示例

python 复制代码
import torch
import torch.nn as nn

# 单通道池化测试
def pool_single():
    # 3×3单通道矩阵
    data = torch.tensor([[[0,1,2],[3,4,5],[6,7,8]]], dtype=torch.float)
    # 最大池化 2×2窗口,步长1
    max_pool = nn.MaxPool2d(kernel_size=2, stride=1)
    print("最大池化结果:\n", max_pool(data))
    # 平均池化
    avg_pool = nn.AvgPool2d(kernel_size=2, stride=1)
    print("平均池化结果:\n", avg_pool(data))

# 多通道池化测试
def pool_multi():
    # 3通道3×3数据
    data = torch.tensor([
        [[0,1,2],[3,4,5],[6,7,8]],
        [[10,20,30],[40,50,60],[70,80,90]],
        [[11,22,33],[44,55,66],[77,88,99]]
    ], dtype=torch.float)
    pool = nn.MaxPool2d(2, 1)
    print("多通道池化结果:\n", pool(data))

if __name__ == "__main__":
    pool_single()
    pool_multi()

第二部分:RNN 循环神经网络 ------ 处理文本 / 时序数据

一、RNN 基础认知:专门处理有序序列数据

1. 什么是序列数据?

数据存在严格先后顺序,后文依赖前文:

  • 文本:我 喜欢 吃 火锅,词语颠倒语义完全改变;
  • 时序:气温、股价、传感器数据;
  • 语音:连续音频波形。

CNN 只能处理空间静态图片,无法记忆前文信息,因此诞生 RNN,核心是隐藏状态(记忆单元),每一步运算携带上一步历史信息。

2. RNN 四大应用场景

  1. NLP 自然语言:情感分析、机器翻译、文本生成、聊天机器人;
  2. 时间序列预测:销量、气象、股市预测;
  3. 语音识别、AI 歌曲生成;
  4. 动作时序识别。

3. RNN 完整文本处理流水线

词嵌入层 Embedding → RNN 循环层 → 全连接输出层

  1. 词嵌入:文字转为低维数字向量;
  2. RNN 层:逐词读取向量,用隐藏状态保存上下文记忆;
  3. 全连接层:输出分类 / 生成词语概率。

二、词嵌入层 Embedding:文字数字化必经步骤

1. One-hot 编码的缺点

假设词表 5000 个词,每个词是 5000 维稀疏向量:

  • 维度爆炸,计算开销巨大;
  • 无法区分语义相近词语(奶茶、咖啡向量完全无关)。

2. 词嵌入三大优势

  1. 低维稠密向量:几千词汇统一映射为 32/64/128 维短向量;
  2. 语义编码:语义相近词语向量空间距离更近;
  3. 统一输入格式:将离散文字转为神经网络可计算的数值。

3. 完整工作流程

句子分词 → 构建词表(词→唯一索引)→ 句子转为索引序列 → Embedding 查表输出词向量 → 送入 RNN。

4. PyTorch nn.Embedding 案例代码(奶茶短句案例)

python 复制代码
import torch
import torch.nn as nn

# 奶茶评论语料
words = ["我", "爱", "喝", "珍珠奶茶", "冰奶茶", "少糖"]
word2idx = {w:i for i,w in enumerate(words)}
vocab_size = len(word2idx)
embed_dim = 8 # 每个词映射8维向量

# 构建嵌入层
embedding = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embed_dim)

# 句子转索引
sent_idx = torch.tensor([word2idx["我"], word2idx["爱"], word2idx["珍珠奶茶"]])
vec = embedding(sent_idx)

print("索引序列shape:", sent_idx.shape)
print("词向量shape [词数量,向量维度]:", vec.shape)
print(""珍珠奶茶"向量:", embedding(torch.tensor(3)))

三、RNN 循环层:自带记忆的时序处理器

1. 核心:隐藏状态 h(RNN 的短期记忆)

每个时间步输入两部分:

  1. 当前词语词向量
  2. 上一步记忆

运算后生成新记忆 ht​,传递给下一个词语,全程共享同一个神经元循环运算。 隐藏状态三大作用:存储历史信息、理解上下文、串联所有时序步骤。

2. RNN 核心计算公式

  1. 更新隐藏记忆:

  2. 输出预测向量:

    输出向量经过 Softmax 转为词语概率,用于文本生成 / 分类。

3. PyTorch nn.RNN API 介绍

python 复制代码
nn.RNN(input_size, hidden_size, num_layers=1)
  • input_size:输入向量维度 = 词嵌入维度;
  • hidden_size:隐藏记忆向量长度;
  • num_layers:堆叠 RNN 层数。
python 复制代码
output, hn = rnn(x, h0)
  1. 输入 [seq_len, batch, input_size] 句子长度、批次、词向量维度;
  2. 初始隐藏 [num_layers, batch, hidden_size],不传默认全 0;
  3. :所有时间步隐藏状态 [seq_len, batch, hidden_size](文本生成使用);
  4. :最后一步全局记忆 [num_layers, batch, hidden_size](文本分类使用)。

4. RNN 单层测试代码

python 复制代码
import torch
import torch.nn as nn

seq_len = 6    # 单句6个词
batch_size = 4 # 4条句子一批
embed_dim = 8  # 词向量维度
hidden_dim = 16# 记忆向量长度

rnn = nn.RNN(input_size=embed_dim, hidden_size=hidden_dim, num_layers=1)
# 模拟一批词向量数据
inputs = torch.randn(seq_len, batch_size, embed_dim)
# 初始化隐藏状态
h0 = torch.zeros(1, batch_size, hidden_dim)

output, hn = rnn(inputs, h0)
print("全部时间步输出shape:", output.shape) # [6,4,16]
print("最终全局记忆hn shape:", hn.shape)     # [1,4,16]

参数匹配规则:

四、案例:RNN 文本情感分类模型(奶茶好评 / 差评)

python 复制代码
import torch
import torch.nn as nn

# 超参数
VOCAB_NUM = 12
EMBED_DIM = 16
HIDDEN_DIM = 32
LAYERS = 1
CLASS_NUM = 2 # 二分类:好评0,差评1

class MilkTeaSentimentRNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.embedding = nn.Embedding(VOCAB_NUM, EMBED_DIM)
        self.rnn = nn.RNN(EMBED_DIM, HIDDEN_DIM, LAYERS)
        self.fc = nn.Linear(HIDDEN_DIM, CLASS_NUM)

    def forward(self, x):
        emb = self.embedding(x)
        _, hn = self.rnn(emb)
        hn = hn.squeeze(0) # 去除层数维度
        out = self.fc(hn)
        return out

if __name__ == "__main__":
    model = MilkTeaSentimentRNN()
    # 模拟3条评论,每条5个词
    test_input = torch.randint(0, VOCAB_NUM, (5, 3))
    pred = model(test_input)
    print("模型输出 [批次,分类数]:", pred.shape)

第三部分:CNN 与 RNN 核心对比 + 相关问题

一、CNN vs RNN 适用场景清晰区分

表格

网络 处理数据 核心能力 核心结构 典型任务
CNN 卷积网络 图像、空间二维数据 提取局部空间特征、平移不变 卷积层 + 池化层 图像分类、人脸识别、目标检测
RNN 循环网络 文本、时序一维有序数据 记忆历史上下文、建模先后依赖 词嵌入 + 循环隐藏层 情感分析、股价预测、文本生成

二、相关问题

CNN 相关

  1. 卷积核为什么多用 3×3? 多个 3×3 堆叠可以替代大卷积核,参数量更少、非线性更强,VGG 网络标准设计。
  2. 池化会不会丢失信息? 只会丢弃无关细节,保留最强特征;现代网络也常用 stride=2 卷积替代池化。
  3. 图片输入为什么要转 B,C,H,W? PyTorch 卷积层通道维度放在第二维,符合 GPU 并行计算优化规范。

RNN 相关

  1. output 和 hn 什么时候用? 逐词生成任务(写诗、翻译)用 output;整条句子分类只用最后一步 hn。
  2. 基础 RNN 有什么缺陷? 长文本会出现梯度消失,远距离前文记忆丢失,工业改用 LSTM/GRU。
  3. 词嵌入维度怎么选? 短评论短句 32/64 维;长文章、大语料 128/256 维,维度越大语义承载越多,训练更慢。

全文总结

  1. CNN 卷积神经网络 针对图像空间数据,依靠卷积核提取边缘 / 纹理特征,池化层降维压缩;核心三组件:卷积 Conv2d、池化 Pool、全连接 Linear;掌握尺寸计算公式与 PyTorch 卷积 / 池化 API 即可搭建简易图像分类模型。

  2. RNN 循环神经网络 针对有序序列(文字、时序),依靠隐藏状态存储上下文记忆;文本处理固定流程:分词→词嵌入 nn.Embedding→nn.RNN 循环层→全连接输出;适合 NLP、时间序列预测任务。

  3. 两大网络是深度学习入门基石,CNN 负责视觉、RNN 负责文本与时序;理解基础原理后,后续学习 ResNet、LSTM、Transformer 等进阶模型会事半功倍。文中所有代码均为全新独立案例,不照搬原文示例,新手可直接复制运行调试,直观观察网络输出变化。

相关推荐
灵机一物1 小时前
2026算力推荐进入专业化阶段:超互联品牌如何构建企业AI选型能力矩阵
服务器·人工智能·决策树·云平台
2zcode1 小时前
基于MATLAB语音信号分析与机器学习的帕金森病智能检测系统
人工智能·机器学习·matlab
冬奇Lab1 小时前
MCP Server 入门开发 + 协议调试 + 生产级部署
人工智能·llm·mcp
冬奇Lab1 小时前
开源项目第157期:archify — 用自然语言生成可主题切换、高分辨率导出的架构图
人工智能·架构·claude
2301_800256111 小时前
人工智能入门学习——ANN、CNN基本概念和考试核心代码
人工智能·学习·cnn
A hao1 小时前
HDR LED显示屏工作原理:高动态范围显示技术解析
大数据·图像处理·人工智能
2601_954971131 小时前
二本应用统计学专业就业前景与岗位分析:CDA数据分析师证书的价值
深度学习
IT_陈寒1 小时前
SpringBoot自动配置的坑,我的Bean怎么不生效?
前端·人工智能·后端
nopSled1 小时前
AlphaAvatar v0.6.4 架构升级:统一实时感知、RTC 解耦与在线 ENV Memory
人工智能·架构·实时音视频·agent·多模态