FA_CNN卷积神经网络四---线性层及其拉平PyTorch

FA :Formulas and Algorithm, CNN:Convolutional Neural Network

1. 引言

在深度学习的学习过程中,我们经常会遇到一个核心问题:神经网络到底在训练什么? 简单来说,神经网络训练的就是函数系数 KkK_{k}Kk 与偏置项 ddd。通过不断调整这些参数,网络能够学习到输入与输出之间的映射关系。

在图像分类任务中,我们通常需要将多维的图片数据转换为适合全连接层处理的格式。本文将基于 PyTorch 和 CIFAR10 数据集,带你一步步理解**线性拉平(Flatten)和 线性层(Linear Layer)**的核心概念与实战用法。

2. 环境准备

在开始之前,请确保你的环境中已经安装了以下依赖:

python 复制代码
import torch
import torchvision
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

本文使用的数据集为 CIFAR10,它包含 10 个类别的彩色图片,每张图片的尺寸为 3×32×32(通道×高×宽)。

3. 线性拉平(Flatten)

3.1 什么是线性拉平

线性拉平是将多维张量展开为一维向量的操作。在将图片数据输入全连接层之前,我们必须先将多维数据"拉平"。

3.2 方法一:使用 torch.reshape

python 复制代码
import torch
import torchvision
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    output = torch.reshape(imgs, (1, 1, 1, -1))
    print(output.shape)

运行结果:

text 复制代码
torch.Size([64, 3, 32, 32])
torch.Size([1, 1, 1, 196608])

可以看到,原本形状为 [64, 3, 32, 32] 的批量图片数据,经过 torch.reshape 后被拉平为 [1, 1, 1, 196608]。其中 196608 = 64 × 3 × 32 × 32,即所有元素被展开成一维。

3.3 方法二:使用 torch.flatten

除了 torch.reshape,PyTorch 还提供了更直观的 torch.flatten 方法,直接将张量展开为一维:

python 复制代码
output = torch.flatten(imgs)  # 展开为一维
print(output.shape)

运行结果:

text 复制代码
torch.Size([196608])

两种方法都能实现拉平操作,但 torch.flatten 的语义更加清晰,推荐在实际项目中使用。

4. 线性层(Linear Layer)

4.1 什么是线性层

线性层(全连接层)是神经网络中最基础的层之一,它的作用是对输入数据进行线性变换。其数学表达式为:

y=xWT+by = xW^T + by=xWT+b

其中 WWW 是权重矩阵,bbb 是偏置项。

4.2 实战:将拉平后的数据输入线性层

下面我们定义一个简单的神经网络,将拉平后的 CIFAR10 图片数据(196608 维)映射到 10 个类别:

python 复制代码
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.linear1 = Linear(196608, 10)

    def forward(self, input):
        output = self.linear1(input)
        return output

tudui = Tudui()
writer = SummaryWriter("logs")
step = 0

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    writer.add_images("input", imgs, step)
    output = torch.reshape(imgs, (1, 1, 1, -1))  # 方法一:拉平
    print(output.shape)
    output = tudui(output)
    print(output.shape)
    writer.add_images("output", output, step)
    step = step + 1

运行结果:

text 复制代码
torch.Size([64, 3, 32, 32])
torch.Size([1, 1, 1, 196608])
torch.Size([1, 1, 1, 10])

可以看到,数据经过线性层后,从 196608 维被映射到了 10 维,正好对应 CIFAR10 的 10 个类别。

4.3 使用 torch.flatten 的完整示例

python 复制代码
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.linear1 = Linear(196608, 10)

    def forward(self, input):
        output = self.linear1(input)
        return output

tudui = Tudui()
writer = SummaryWriter("logs")
step = 0

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    writer.add_images("input", imgs, step)
    output = torch.flatten(imgs)  # 方法二:拉平,展开为一维
    print(output.shape)
    output = tudui(output)
    print(output.shape)
    step = step + 1

运行结果:

text 复制代码
torch.Size([64, 3, 32, 32])
torch.Size([196608])
torch.Size([10])

5. 使用 TensorBoard 可视化

为了更直观地观察训练过程中的输入与输出,我们可以使用 TensorBoard 进行可视化。

在 Anaconda 终端中,激活你的 Python 环境(例如 py3.6.3),然后输入以下命令:

bash 复制代码
tensorboard --logdir=C:\Users\wangy\Desktop\03CV\logs

将输出的网址复制到浏览器地址栏并回车,即可在 TensorBoard 中查看日志信息。

6. 总结

本文通过实战代码,带你理解了 PyTorch 中两个重要的基础操作:

  • 线性拉平(Flatten) :将多维张量展开为一维向量,是连接卷积层与全连接层的桥梁。常用方法有 torch.reshape 和 torch.flatten。
  • 线性层(Linear Layer):对输入进行线性变换,将高维特征映射到目标维度(如分类任务的类别数)。

理解这两个概念,是深入学习卷积神经网络(CNN)和全连接网络的基础。希望本文能帮助你更好地掌握 PyTorch 的核心操作,为后续的深度学习之旅打下坚实的基础。

相关推荐
字节跳动视频云技术团队22 分钟前
每两家头部手机厂商就有一家选它:火山引擎如何成为 AI 手机助手的“隐形底座”?
人工智能
泯泷43 分钟前
像项目经理一样指挥 AI 团队:管理者模式
人工智能·llm·agent
京东云开发者1 小时前
双11囤Token火了:京东搜索量暴涨7倍,AI生产力成新刚需
人工智能
ahccqw1 小时前
OpenCV 车辆数量统计
人工智能·opencv·计算机视觉
人工智能AI技术1 小时前
LangGraph 本地 build 频频翻车,最终在服务器跑通流式对话
人工智能
Flynn Liang2 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
汤姆宝库2 小时前
构建一个能用的RAG系统:切块、嵌入、混合检索与融合排序
人工智能
Dawson Zhu2 小时前
【LLM推理与Serving⑪】MoE推理与MLA:DeepSeek-V3架构下的显存与通信权衡
人工智能·语言模型·架构·aigc·agi
github_is_geeksKai2 小时前
50 个 AI 与开源工具怎么选:从实际用途到实现边界
人工智能